kubeclient 0.8.1 → 0.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
  SHA1:
3
- metadata.gz: 89981c7be5cb927a6c04b5c8c40304476a21f56f
4
- data.tar.gz: b81b39d1e30735371b0e2d74109541a38a7cacf0
3
+ metadata.gz: 3acf742f15a2ac53054784e80bd9e7d2e281a2ee
4
+ data.tar.gz: c793a0e544599ae7bd734bd2036e4af55d9496e8
5
5
  SHA512:
6
- metadata.gz: 2bbd52b20567a3c70eeb0a784a0e608e6adcbf451b0ba61b10565aaafd831f972f717902d62b3daeeef5ed2bc3297083e471a8f430c7142af2cf6e1581ab12b8
7
- data.tar.gz: 2b549a7cbde4f56ec88c0a7ef5fd802718d40536549507d912e682026cebde0cc7a999e66f764cd0095a568e604a54304d87de7674dbb6b3eba3edd772a188f6
6
+ metadata.gz: 5fa15ac1a973910a1ba705d38ef703db022ad99fc37a1a50ab9236c49a22c0505c3eec635b02df6d602c7504dcac7cc3f9ed81cec332827442055bf1808de242
7
+ data.tar.gz: 3c972f1c2a61d7ae39b1d4afde76bc86e72b884fab763d94339d3ea6a343a6f1ffebd7418c8abed432b3f0e539a68d2381e53a54fad8737a9ab828270ed7f861
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![Dependency Status](https://gemnasium.com/abonas/kubeclient.svg)](https://gemnasium.com/abonas/kubeclient)
7
7
 
8
8
  A Ruby client for Kubernetes REST api.
9
- The client supports GET, POST, PUT, DELETE on nodes, pods, secrets, services, replication controllers, namespaces, resource quotas, limit ranges, endpoints, persistent volumes, persistent volume claims and component statuses.
9
+ The client supports GET, POST, PUT, DELETE on nodes, pods, secrets, services, replication controllers, namespaces, resource quotas, limit ranges, endpoints, persistent volumes, persistent volume claims, component statuses and service accounts.
10
10
  The client currently supports Kubernetes REST api version v1.
11
11
 
12
12
  ## Installation
@@ -58,6 +58,19 @@ client = Kubeclient::Client.new 'https://localhost:8443/api/' , "v1",
58
58
  ssl_options: ssl_options
59
59
  ```
60
60
 
61
+ As an alternative to the `ca_file` it's possible to use the `cert_store`:
62
+
63
+ ```ruby
64
+ cert_store = OpenSSL::X509::Store.new
65
+ cert_store.add_cert(OpenSSL::X509::Certificate.new(ca_cert_data))
66
+ ssl_options = {
67
+ cert_store: cert_store
68
+ verify_ssl: OpenSSL::SSL::VERIFY_PEER
69
+ }
70
+ client = Kubeclient::Client.new 'https://localhost:8443/api/' , "v1",
71
+ ssl_options: ssl_options
72
+ ```
73
+
61
74
  For testing and development purpose you can disable the ssl check with:
62
75
 
63
76
  ```ruby
@@ -118,7 +131,7 @@ client = Kubeclient::Client.new 'https://localhost:8443/api/' , 'v1',
118
131
  ## Examples:
119
132
 
120
133
  #### Get all instances of a specific entity type
121
- Such as: `get_pods`, `get_secrets`, `get_services`, `get_nodes`, `get_replication_controllers`, `get_resource_quotas`, `get_limit_ranges`, `get_persistent_volumes`, `get_persistent_volume_claims`, `get_component_statuses`
134
+ Such as: `get_pods`, `get_secrets`, `get_services`, `get_nodes`, `get_replication_controllers`, `get_resource_quotas`, `get_limit_ranges`, `get_persistent_volumes`, `get_persistent_volume_claims`, `get_component_statuses`, `get_service_accounts`
122
135
 
123
136
  ```ruby
124
137
  pods = client.get_pods
@@ -142,7 +155,7 @@ pods = client.get_pods(label_selector: 'name=redis-master,app=redis')
142
155
  ```
143
156
 
144
157
  #### Get a specific instance of an entity (by name)
145
- Such as: `get_service "service name"` , `get_pod "pod name"` , `get_replication_controller "rc name"`, `get_secret "secret name"`, `get_resource_quota "resource quota name"`, `get_limit_range "limit range name"` , `get_persistent_volume "persistent volume name"` , `get_persistent_volume_claim "persistent volume claim name"`, `get_component_status "component name"`
158
+ Such as: `get_service "service name"` , `get_pod "pod name"` , `get_replication_controller "rc name"`, `get_secret "secret name"`, `get_resource_quota "resource quota name"`, `get_limit_range "limit range name"` , `get_persistent_volume "persistent volume name"` , `get_persistent_volume_claim "persistent volume claim name"`, `get_component_status "component name"`, `get_service_account "service account name"`
146
159
 
147
160
  The GET request should include the namespace name, except for nodes and namespaces entities.
148
161
 
@@ -167,7 +180,7 @@ client.delete_service "redis-service"
167
180
  ```
168
181
 
169
182
  #### Create an entity
170
- For example: `create_pod pod_object`, `create_replication_controller rc_obj`, `create_secret secret_object`, `create_resource_quota resource_quota_object`, `create_limit_range limit_range_object`, `create_persistent_volume persistent_volume_object`, `create_persistent_volume_claim persistent_volume_claim_object`
183
+ For example: `create_pod pod_object`, `create_replication_controller rc_obj`, `create_secret secret_object`, `create_resource_quota resource_quota_object`, `create_limit_range limit_range_object`, `create_persistent_volume persistent_volume_object`, `create_persistent_volume_claim persistent_volume_claim_object`, `create_service_account service_account_object`
171
184
 
172
185
  Input parameter - object of type `Service`, `Pod`, `ReplicationController`.
173
186
 
@@ -192,7 +205,7 @@ client.create_service service`
192
205
  ```
193
206
 
194
207
  #### Update an entity
195
- For example: `update_pod`, `update_service`, `update_replication_controller`, `update_secret`, `update_resource_quota`, `update_limit_range`, `update_persistent_volume`, `update_persistent_volume_claim`
208
+ For example: `update_pod`, `update_service`, `update_replication_controller`, `update_secret`, `update_resource_quota`, `update_limit_range`, `update_persistent_volume`, `update_persistent_volume_claim`, `update_service_account`
196
209
 
197
210
  Input parameter - object of type `Pod`, `Service`, `ReplicationController` etc.
198
211
 
@@ -203,7 +216,7 @@ client.update_service service1
203
216
  ```
204
217
 
205
218
  #### Get all entities of all types : all_entities
206
- Returns a hash with 13 keys (node, secret, service, pod, replication_controller, namespace, resource_quota, limit_range, endpoint, event, persistent_volume, persistent_volume_claim and component_status). Each key points to an EntityList of same type.
219
+ Returns a hash with 14 keys (node, secret, service, pod, replication_controller, namespace, resource_quota, limit_range, endpoint, event, persistent_volume, persistent_volume_claim, component_status and service_account). Each key points to an EntityList of same type.
207
220
  This method is a convenience method instead of calling each entity's get method separately.
208
221
 
209
222
  ```ruby
@@ -226,6 +239,16 @@ It is possible to interrupt the watcher from another thread with:
226
239
  watcher.finish
227
240
  ```
228
241
 
242
+ #### Watch events for a particular object
243
+ You can use the `field_selector` option as part of the watch methods.
244
+
245
+ ```ruby
246
+ watcher = client.watch_events(namespace: 'development', field_selector: 'involvedObject.name=redis-master')
247
+ watcher.each do |notice|
248
+ # process notice date
249
+ end
250
+ ```
251
+
229
252
  #### Get a proxy URL
230
253
  You can get a complete URL for connecting a kubernetes entity via the proxy.
231
254
 
@@ -241,6 +264,38 @@ client.proxy_url('pod', 'podname', 5001, 'ns')
241
264
  => "https://localhost.localdomain:8443/api/v1/namespaces/ns/pods/podname:5001/proxy"
242
265
  ```
243
266
 
267
+ #### Get the logs of a pod
268
+ You can get the logs of a running pod, specifying the name of the pod and the
269
+ namespace where the pod is running:
270
+
271
+ ```ruby
272
+ client.get_pod_log('pod-name', 'default')
273
+ => "Running...\nRunning...\nRunning...\n"
274
+ ```
275
+
276
+ If that pod has more than one container, you must specify the container:
277
+
278
+ ```ruby
279
+ client.get_pod_log('pod-name', 'default', container: 'ruby')
280
+ => "..."
281
+ ```
282
+
283
+ If a container in a pod terminates, a new container is started, and you want to
284
+ retrieve the logs of the dead container, you can pass in the `:previous` option:
285
+
286
+ ```ruby
287
+ client.get_pod_log('pod-name', 'default', previous: true)
288
+ => "..."
289
+ ```
290
+
291
+ You can also watch the logs of a pod to get a stream of data:
292
+
293
+ ```ruby
294
+ watcher = client.watch_pod_log('pod-name', 'default', container: 'ruby')
295
+ watcher.each do |line|
296
+ puts line
297
+ end
298
+ ```
244
299
 
245
300
 
246
301
  ## Contributing
@@ -19,7 +19,7 @@ module Kubeclient
19
19
  # and especially since currently the class body is empty
20
20
  ENTITY_TYPES = %w(Pod Service ReplicationController Node Event Endpoint
21
21
  Namespace Secret ResourceQuota LimitRange PersistentVolume
22
- PersistentVolumeClaim ComponentStatus).map do |et|
22
+ PersistentVolumeClaim ComponentStatus ServiceAccount).map do |et|
23
23
  clazz = Class.new(RecursiveOpenStruct) do
24
24
  def initialize(hash = nil, args = {})
25
25
  args.merge!(recurse_over_arrays: true)
@@ -35,9 +35,10 @@ module Kubeclient
35
35
  version = 'v1',
36
36
  ssl_options: {
37
37
  client_cert: nil,
38
- client_key: nil,
39
- ca_file: nil,
40
- verify_ssl: OpenSSL::SSL::VERIFY_PEER
38
+ client_key: nil,
39
+ ca_file: nil,
40
+ cert_store: nil,
41
+ verify_ssl: OpenSSL::SSL::VERIFY_PEER
41
42
  },
42
43
  auth_options: {
43
44
  username: nil,
@@ -16,6 +16,7 @@ module Kubeclient
16
16
  client_cert: nil,
17
17
  client_key: nil,
18
18
  ca_file: nil,
19
+ cert_store: nil,
19
20
  verify_ssl: OpenSSL::SSL::VERIFY_PEER
20
21
  },
21
22
  auth_options: {
@@ -79,8 +80,12 @@ module Kubeclient
79
80
 
80
81
  # watch all entities of a type e.g. watch_nodes, watch_pods, etc.
81
82
  define_method("watch_#{entity_name_plural}") \
82
- do |resource_version = nil|
83
- watch_entities(entity_type, resource_version)
83
+ do |options = {}|
84
+ # This method used to take resource_version as a param, so
85
+ # this conversion is to keep backwards compatibility
86
+ options = { resource_version: options } unless options.is_a?(Hash)
87
+
88
+ watch_entities(entity_type, options)
84
89
  end
85
90
 
86
91
  # get a single entity of a specific type by name
@@ -111,6 +116,7 @@ module Kubeclient
111
116
  path ||= @api_endpoint.path
112
117
  options = {
113
118
  ssl_ca_file: @ssl_options[:ca_file],
119
+ ssl_cert_store: @ssl_options[:cert_store],
114
120
  verify_ssl: @ssl_options[:verify_ssl],
115
121
  ssl_client_cert: @ssl_options[:client_cert],
116
122
  ssl_client_key: @ssl_options[:client_key],
@@ -126,28 +132,41 @@ module Kubeclient
126
132
  end
127
133
  end
128
134
 
129
- def watch_entities(entity_type, resource_version = nil)
130
- resource = resource_name(entity_type.to_s)
131
- uri = @api_endpoint
132
- .merge("#{@api_endpoint.path}/#{@api_version}/watch/#{resource}")
133
-
134
- unless resource_version.nil?
135
- uri.query = URI.encode_www_form('resourceVersion' => resource_version)
135
+ # Accepts the following string options:
136
+ # :namespace - the namespace of the entity.
137
+ # :name - the name of the entity to watch.
138
+ # :label_selector - a selector to restrict the list of returned objects by their labels.
139
+ # :field_selector - a selector to restrict the list of returned objects by their fields.
140
+ # :resource_version - shows changes that occur after that particular version of a resource.
141
+ def watch_entities(entity_type, options = {})
142
+ ns = build_namespace_prefix(options[:namespace])
143
+
144
+ path = "watch/#{ns}#{resource_name(entity_type.to_s)}"
145
+ path += "/#{options[:name]}" if options[:name]
146
+ uri = @api_endpoint.merge("#{@api_endpoint.path}/#{@api_version}/#{path}")
147
+
148
+ params = options.slice(:label_selector, :field_selector, :resource_version)
149
+ if params.any?
150
+ uri.query = URI.encode_www_form(params.map { |k, v| [k.to_s.camelize(:lower), v] })
136
151
  end
137
152
 
138
153
  Kubeclient::Common::WatchStream.new(uri, net_http_options(uri))
139
154
  end
140
155
 
156
+ # Accepts the following string options:
157
+ # :namespace - the namespace of the entity.
158
+ # :label_selector - a selector to restrict the list of returned objects by their labels.
159
+ # :field_selector - a selector to restrict the list of returned objects by their fields.
141
160
  def get_entities(entity_type, klass, options = {})
142
161
  params = {}
143
- if options[:label_selector]
144
- params['params'] = { labelSelector: options[:label_selector] }
162
+ [:label_selector, :field_selector].each do |p|
163
+ params[p.to_s.camelize(:lower)] = options[p] if options[p]
145
164
  end
146
165
 
147
166
  ns_prefix = build_namespace_prefix(options[:namespace])
148
167
  response = handle_exception do
149
168
  rest_client[ns_prefix + resource_name(entity_type)]
150
- .get(params.merge(@headers))
169
+ .get({ 'params' => params }.merge(@headers))
151
170
  end
152
171
 
153
172
  result = JSON.parse(response)
@@ -194,7 +213,6 @@ module Kubeclient
194
213
  # https://github.com/GoogleCloudPlatform/kubernetes/issues/6439
195
214
  hash['kind'] = entity_type
196
215
  hash['apiVersion'] = @api_version
197
- @headers['Content-Type'] = 'application/json'
198
216
  response = handle_exception do
199
217
  rest_client[ns_prefix + resource_name(entity_type)]
200
218
  .post(hash.to_json, @headers)
@@ -209,7 +227,6 @@ module Kubeclient
209
227
  # struct
210
228
  hash = entity_config.to_hash
211
229
  ns_prefix = build_namespace_prefix(entity_config.metadata['table'][:namespace])
212
- @headers['Content-Type'] = 'application/json'
213
230
  handle_exception do
214
231
  rest_client[ns_prefix + resource_name(entity_type) + "/#{name}"]
215
232
  .put(hash.to_json, @headers)
@@ -231,6 +248,33 @@ module Kubeclient
231
248
  end
232
249
  end
233
250
 
251
+ def get_pod_log(pod_name, namespace, container: nil, previous: false)
252
+ params = {}
253
+ params[:previous] = true if previous
254
+ params[:container] = container if container
255
+
256
+ ns = build_namespace_prefix(namespace)
257
+ handle_exception do
258
+ rest_client[ns + "pods/#{pod_name}/log"]
259
+ .get({ 'params' => params }.merge(@headers))
260
+ end
261
+ end
262
+
263
+ def watch_pod_log(pod_name, namespace, container: nil)
264
+ # Adding the "follow=true" query param tells the Kubernetes API to keep
265
+ # the connection open and stream updates to the log.
266
+ params = { follow: true }
267
+ params[:container] = container if container
268
+
269
+ ns = build_namespace_prefix(namespace)
270
+
271
+ uri = @api_endpoint.dup
272
+ uri.path += "/#{@api_version}/#{ns}pods/#{pod_name}/log"
273
+ uri.query = URI.encode_www_form(params)
274
+
275
+ Kubeclient::Common::WatchStream.new(uri, net_http_options(uri), format: :text)
276
+ end
277
+
234
278
  def proxy_url(kind, name, port, namespace = '')
235
279
  entity_name_plural = ClientMixin.pluralize_entity(kind.to_s)
236
280
  ns_prefix = build_namespace_prefix(namespace)
@@ -297,6 +341,7 @@ module Kubeclient
297
341
  use_ssl: true,
298
342
  ca_file: @ssl_options[:ca_file],
299
343
  cert: @ssl_options[:client_cert],
344
+ cert_store: @ssl_options[:cert_store],
300
345
  key: @ssl_options[:client_key],
301
346
  # ruby Net::HTTP uses verify_mode instead of verify_ssl
302
347
  # http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html
@@ -1,4 +1,4 @@
1
1
  # Kubernetes REST-API Client
2
2
  module Kubeclient
3
- VERSION = '0.8.1'
3
+ VERSION = '0.9.0'
4
4
  end
@@ -0,0 +1,25 @@
1
+ {
2
+ "kind": "ServiceAccount",
3
+ "apiVersion": "v1",
4
+ "metadata": {
5
+ "name": "default",
6
+ "namespace": "default",
7
+ "selfLink": "/api/v1/namespaces/default/serviceaccounts/default",
8
+ "uid": "d3d773f4-6bf0-11e5-843a-525400f8b93e",
9
+ "resourceVersion": "94",
10
+ "creationTimestamp": "2015-10-06T06:09:39Z"
11
+ },
12
+ "secrets": [
13
+ {
14
+ "name": "default-token-6s23q"
15
+ },
16
+ {
17
+ "name": "default-dockercfg-62tf3"
18
+ }
19
+ ],
20
+ "imagePullSecrets": [
21
+ {
22
+ "name": "default-dockercfg-62tf3"
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,82 @@
1
+ {
2
+ "kind": "List",
3
+ "apiVersion": "v1",
4
+ "metadata": {},
5
+ "items": [
6
+ {
7
+ "kind": "ServiceAccount",
8
+ "apiVersion": "v1",
9
+ "metadata": {
10
+ "name": "builder",
11
+ "namespace": "default",
12
+ "selfLink": "/api/v1/namespaces/default/serviceaccounts/builder",
13
+ "uid": "d40655f6-6bf0-11e5-843a-525400f8b93e",
14
+ "resourceVersion": "133",
15
+ "creationTimestamp": "2015-10-06T06:09:39Z"
16
+ },
17
+ "secrets": [
18
+ {
19
+ "name": "builder-token-5v6z2"
20
+ },
21
+ {
22
+ "name": "builder-dockercfg-qe2re"
23
+ }
24
+ ],
25
+ "imagePullSecrets": [
26
+ {
27
+ "name": "builder-dockercfg-qe2re"
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ "kind": "ServiceAccount",
33
+ "apiVersion": "v1",
34
+ "metadata": {
35
+ "name": "default",
36
+ "namespace": "default",
37
+ "selfLink": "/api/v1/namespaces/default/serviceaccounts/default",
38
+ "uid": "d3d773f4-6bf0-11e5-843a-525400f8b93e",
39
+ "resourceVersion": "94",
40
+ "creationTimestamp": "2015-10-06T06:09:39Z"
41
+ },
42
+ "secrets": [
43
+ {
44
+ "name": "default-token-6s23q"
45
+ },
46
+ {
47
+ "name": "default-dockercfg-62tf3"
48
+ }
49
+ ],
50
+ "imagePullSecrets": [
51
+ {
52
+ "name": "default-dockercfg-62tf3"
53
+ }
54
+ ]
55
+ },
56
+ {
57
+ "kind": "ServiceAccount",
58
+ "apiVersion": "v1",
59
+ "metadata": {
60
+ "name": "deployer",
61
+ "namespace": "default",
62
+ "selfLink": "/api/v1/namespaces/default/serviceaccounts/deployer",
63
+ "uid": "d41d385e-6bf0-11e5-843a-525400f8b93e",
64
+ "resourceVersion": "137",
65
+ "creationTimestamp": "2015-10-06T06:09:39Z"
66
+ },
67
+ "secrets": [
68
+ {
69
+ "name": "deployer-token-h3i57"
70
+ },
71
+ {
72
+ "name": "deployer-dockercfg-qgjjj"
73
+ }
74
+ ],
75
+ "imagePullSecrets": [
76
+ {
77
+ "name": "deployer-dockercfg-qgjjj"
78
+ }
79
+ ]
80
+ }
81
+ ]
82
+ }
@@ -172,6 +172,38 @@ class KubeClientTest < MiniTest::Test
172
172
  times: 1)
173
173
  end
174
174
 
175
+ def test_entities_with_label_selector
176
+ selector = 'component=apiserver'
177
+
178
+ stub_request(:get, %r{/services})
179
+ .to_return(body: open_test_file('entity_list.json'),
180
+ status: 200)
181
+
182
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
183
+ services = client.get_services(label_selector: selector)
184
+
185
+ assert_instance_of(Kubeclient::Common::EntityList, services)
186
+ assert_requested(:get,
187
+ "http://localhost:8080/api/v1/services?labelSelector=#{selector}",
188
+ times: 1)
189
+ end
190
+
191
+ def test_entities_with_field_selector
192
+ selector = 'involvedObject.name=redis-master'
193
+
194
+ stub_request(:get, %r{/services})
195
+ .to_return(body: open_test_file('entity_list.json'),
196
+ status: 200)
197
+
198
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
199
+ services = client.get_services(field_selector: selector)
200
+
201
+ assert_instance_of(Kubeclient::Common::EntityList, services)
202
+ assert_requested(:get,
203
+ "http://localhost:8080/api/v1/services?fieldSelector=#{selector}",
204
+ times: 1)
205
+ end
206
+
175
207
  def test_empty_list
176
208
  stub_request(:get, %r{/pods})
177
209
  .to_return(body: open_test_file('empty_pod_list.json'),
@@ -234,9 +266,13 @@ class KubeClientTest < MiniTest::Test
234
266
  .to_return(body: open_test_file('component_status_list.json'),
235
267
  status: 200)
236
268
 
269
+ stub_request(:get, %r{/serviceaccounts})
270
+ .to_return(body: open_test_file('service_account_list.json'),
271
+ status: 200)
272
+
237
273
  client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
238
274
  result = client.all_entities
239
- assert_equal(13, result.keys.size)
275
+ assert_equal(14, result.keys.size)
240
276
  assert_instance_of(Kubeclient::Common::EntityList, result['node'])
241
277
  assert_instance_of(Kubeclient::Common::EntityList, result['service'])
242
278
  assert_instance_of(Kubeclient::Common::EntityList,
@@ -256,6 +292,7 @@ class KubeClientTest < MiniTest::Test
256
292
  assert_instance_of(Kubeclient::PersistentVolume, result['persistent_volume'][0])
257
293
  assert_instance_of(Kubeclient::PersistentVolumeClaim, result['persistent_volume_claim'][0])
258
294
  assert_instance_of(Kubeclient::ComponentStatus, result['component_status'][0])
295
+ assert_instance_of(Kubeclient::ServiceAccount, result['service_account'][0])
259
296
  end
260
297
 
261
298
  def test_api_bearer_token_with_params_success
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ # Pod log tests
4
+ class TestPodLog < MiniTest::Test
5
+ def test_get_pod_log
6
+ stub_request(:get, %r{/namespaces/default/pods/[a-z0-9-]+/log})
7
+ .to_return(body: open_test_file('pod_log.txt'),
8
+ status: 200)
9
+
10
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
11
+ retrieved_log = client.get_pod_log('redis-master-pod', 'default')
12
+
13
+ assert_equal(open_test_file('pod_log.txt').read, retrieved_log)
14
+
15
+ assert_requested(:get,
16
+ 'http://localhost:8080/api/v1/namespaces/default/pods/redis-master-pod/log',
17
+ times: 1)
18
+ end
19
+
20
+ def test_get_pod_log_container
21
+ stub_request(:get, %r{/namespaces/default/pods/[a-z0-9-]+/log})
22
+ .to_return(body: open_test_file('pod_log.txt'),
23
+ status: 200)
24
+
25
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
26
+ retrieved_log = client.get_pod_log('redis-master-pod', 'default', container: 'ruby')
27
+
28
+ assert_equal(open_test_file('pod_log.txt').read, retrieved_log)
29
+
30
+ assert_requested(:get,
31
+ 'http://localhost:8080/api/v1/namespaces/default/pods/redis-master-pod/log?container=ruby',
32
+ times: 1)
33
+ end
34
+
35
+ def test_watch_pod_log
36
+ expected_lines = open_test_file('pod_log.txt').read.split("\n")
37
+
38
+ stub_request(:get, %r{/namespaces/default/pods/[a-z0-9-]+/log\?.*follow})
39
+ .to_return(body: open_test_file('pod_log.txt'),
40
+ status: 200)
41
+
42
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
43
+
44
+ stream = client.watch_pod_log('redis-master-pod', 'default')
45
+ stream.to_enum.with_index do |notice, index|
46
+ assert_instance_of(String, notice)
47
+ assert_equal(expected_lines[index], notice)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ # ServiceAccount tests
4
+ class TestServiceAccount < MiniTest::Test
5
+ def test_get_from_json_v1
6
+ stub_request(:get, %r{/serviceaccounts})
7
+ .to_return(body: open_test_file('service_account.json'),
8
+ status: 200)
9
+
10
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
11
+ account = client.get_service_account 'default'
12
+
13
+ assert_instance_of(Kubeclient::ServiceAccount, account)
14
+ assert_equal('default', account.metadata.name)
15
+ assert_equal('default-token-6s23q', account.secrets[0].name)
16
+ assert_equal('default-dockercfg-62tf3', account.secrets[1].name)
17
+
18
+ assert_requested(:get,
19
+ 'http://localhost:8080/api/v1/serviceaccounts/default',
20
+ times: 1)
21
+ end
22
+ end
@@ -50,4 +50,55 @@ class TestWatch < MiniTest::Test
50
50
  assert_equal(expected_lines[index], line)
51
51
  end
52
52
  end
53
+
54
+ def test_watch_with_resource_version
55
+ api_host = 'http://localhost:8080/api'
56
+ version = '1995'
57
+
58
+ stub_request(:get, %r{.*\/watch/events})
59
+ .to_return(body: open_test_file('watch_stream.json'),
60
+ status: 200)
61
+
62
+ client = Kubeclient::Client.new api_host, 'v1'
63
+ results = client.watch_events(version).to_enum
64
+
65
+ assert_equal(3, results.count)
66
+ assert_requested(:get,
67
+ "#{api_host}/v1/watch/events?resourceVersion=#{version}",
68
+ times: 1)
69
+ end
70
+
71
+ def test_watch_with_label_selector
72
+ api_host = 'http://localhost:8080/api'
73
+ selector = 'name=redis-master'
74
+
75
+ stub_request(:get, %r{.*\/watch/events})
76
+ .to_return(body: open_test_file('watch_stream.json'),
77
+ status: 200)
78
+
79
+ client = Kubeclient::Client.new api_host, 'v1'
80
+ results = client.watch_events(label_selector: selector).to_enum
81
+
82
+ assert_equal(3, results.count)
83
+ assert_requested(:get,
84
+ "#{api_host}/v1/watch/events?labelSelector=#{selector}",
85
+ times: 1)
86
+ end
87
+
88
+ def test_watch_with_field_selector
89
+ api_host = 'http://localhost:8080/api'
90
+ selector = 'involvedObject.kind=Pod'
91
+
92
+ stub_request(:get, %r{.*\/watch/events})
93
+ .to_return(body: open_test_file('watch_stream.json'),
94
+ status: 200)
95
+
96
+ client = Kubeclient::Client.new api_host, 'v1'
97
+ results = client.watch_events(field_selector: selector).to_enum
98
+
99
+ assert_equal(3, results.count)
100
+ assert_requested(:get,
101
+ "#{api_host}/v1/watch/events?fieldSelector=#{selector}",
102
+ times: 1)
103
+ end
53
104
  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: 0.8.1
4
+ version: 0.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: 2016-03-08 00:00:00.000000000 Z
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -202,6 +202,8 @@ files:
202
202
  - test/json/resource_quota_list.json
203
203
  - test/json/secret_list.json
204
204
  - test/json/service.json
205
+ - test/json/service_account.json
206
+ - test/json/service_account_list.json
205
207
  - test/json/service_illegal_json_404.json
206
208
  - test/json/service_list.json
207
209
  - test/json/service_update.json
@@ -217,10 +219,12 @@ files:
217
219
  - test/test_persistent_volume.rb
218
220
  - test/test_persistent_volume_claim.rb
219
221
  - test/test_pod.rb
222
+ - test/test_pod_log.rb
220
223
  - test/test_replication_controller.rb
221
224
  - test/test_resource_quota.rb
222
225
  - test/test_secret.rb
223
226
  - test/test_service.rb
227
+ - test/test_service_account.rb
224
228
  - test/test_watch.rb
225
229
  - test/txt/pod_log.txt
226
230
  - test/valid_token_file
@@ -279,6 +283,8 @@ test_files:
279
283
  - test/json/resource_quota_list.json
280
284
  - test/json/secret_list.json
281
285
  - test/json/service.json
286
+ - test/json/service_account.json
287
+ - test/json/service_account_list.json
282
288
  - test/json/service_illegal_json_404.json
283
289
  - test/json/service_list.json
284
290
  - test/json/service_update.json
@@ -294,10 +300,12 @@ test_files:
294
300
  - test/test_persistent_volume.rb
295
301
  - test/test_persistent_volume_claim.rb
296
302
  - test/test_pod.rb
303
+ - test/test_pod_log.rb
297
304
  - test/test_replication_controller.rb
298
305
  - test/test_resource_quota.rb
299
306
  - test/test_secret.rb
300
307
  - test/test_service.rb
308
+ - test/test_service_account.rb
301
309
  - test/test_watch.rb
302
310
  - test/txt/pod_log.txt
303
311
  - test/valid_token_file