kubeclient 4.2.2 → 4.7.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: 9e11771dcb8f222f6c3a3bb4fb1c8b3db8cc745a9d2dbe8b2ff3edfe02382f3d
4
- data.tar.gz: a5edd9efc28428fd2e5d232a1bdce0a1f5d0bd56fad06cff4d10e82e03bdc3f6
3
+ metadata.gz: 886ba443bde8e7b8a2403dc5cc300fa53f8ffdad30782f2c7c58911049d7d322
4
+ data.tar.gz: 340073ed06a0252095adb47a73ea972332e2615afdefe9fab5f357db61ceb2f4
5
5
  SHA512:
6
- metadata.gz: 17cdfd31bf3df9292a2edf052071e99b30e62ee6ebfd05bce7b710623cc7c0ae57acb1c469787cee49bd472dc1661d687908acbb364cc8d36723f7ee4b07d273
7
- data.tar.gz: f739a8fc768a688853e2f6e55232087bdfbdc31b26a86ca6ffe6ecc87996b72906a2d60d674c5aae3d5023d578b5cc9d20611a349f1cfc0d2ee1d2511e4f4c7c
6
+ metadata.gz: 129ca12cda43fdb8e7c2b7400f31b6086cbd06ba4c7874a4c88d07fdcfeb165b88acb620a9673a1a3a7d60f12571cef48e4167f1dd65c8c68d35022db2264320
7
+ data.tar.gz: 6184774412f3d0fa0d5a16e43520530cf279a8f8d23129f50d9973a91f58cb8bf1db4c55ddccecb710ab7577ab1737a3eba569096b8b257935ee9463e23c34c6
@@ -14,12 +14,16 @@ Metrics/ParameterLists:
14
14
  CountKeywordArgs: false
15
15
  Metrics/CyclomaticComplexity:
16
16
  Max: 8
17
+ Metrics/PerceivedComplexity:
18
+ Max: 8
17
19
  Metrics/ModuleLength:
18
20
  Enabled: false
19
21
  Style/MethodCallWithArgsParentheses:
20
22
  Enabled: true
21
23
  IgnoredMethods: [require, raise, include, attr_reader, refute, assert]
22
24
  Exclude: [Gemfile, Rakefile, kubeclient.gemspec, Gemfile.dev.rb]
25
+ Metrics/BlockLength:
26
+ Exclude: [kubeclient.gemspec]
23
27
  Security/MarshalLoad:
24
28
  Exclude: [test/**/*]
25
29
  Style/FileName:
@@ -1,13 +1,29 @@
1
1
  language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ script: bundle exec rake $TASK
5
+
6
+ os:
7
+ - linux
8
+ - osx
2
9
  rvm:
3
- - "2.2"
10
+ - "2.2.0"
4
11
  - "2.3.0"
5
12
  - "2.4.0"
6
13
  - "2.5.0"
7
- - "2.6.0-preview1"
8
- sudo: false
9
- cache: bundler
10
- script: bundle exec rake $TASK
14
+ - "2.6.0"
15
+ - "2.7.0"
11
16
  env:
12
17
  - TASK=test
13
- - TASK=rubocop
18
+ matrix:
19
+ exclude:
20
+ - os: osx
21
+ rvm: "2.2.0"
22
+ - os: osx
23
+ rvm: "2.3.0"
24
+ # No point running Rubocop on different rubies, results will be same.
25
+ # The rubies it expects the code to target are controlled in .rubocop.yml.
26
+ include:
27
+ - os: linux
28
+ rvm: "2.5.0"
29
+ env: TASK=rubocop
@@ -4,6 +4,52 @@ 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.7.0 — 2020-06-14
8
+
9
+ ### Fixed
10
+ - Ruby 2.7 compatibility: bumped minimum recursive-open-struct to one that works on 2.7 (#439).
11
+ - Ruby 2.7 warnings (#433, #438).
12
+ - Improved watch documentation, including behavior planned to change in 5.0.0 (#436).
13
+
14
+ ### Added
15
+ - Google Application Default Credentials: Added `userinfo.email` to requested scopes, which is necessary for RBAC policies (#441).
16
+
17
+ ## 4.6.0 — 2019-12-30
18
+
19
+ ### Fixed
20
+ - AmazonEksCredentials was sometimes leaving base64 padding that IAM auth of the EKS cluster rejects. Now padding is always stripped. (#424, #423)
21
+
22
+ ### Added
23
+ - Allow calling `watch_foos` methods with a block, simpler to use and guarantees closing the connection. (#425)
24
+
25
+ - Support `limitBytes` query parameter for `get_pod_log`. (#426)
26
+
27
+ ## 4.5.0 — 2019-09-27
28
+
29
+ ### Added
30
+ - Support `:resourceVersion` parameter in `get_foos` methods (similar to existing support in `watch_foos` methods). (#420)
31
+
32
+ - Relax dependency on `http` gem to allow both 3.x and 4.x. (#413)
33
+
34
+ ## 4.4.0 — 2019-05-03
35
+
36
+ ### Added
37
+ - GCP configs with `user[auth-provider][name] == 'gcp'` will execute credential plugin (normally the `gcloud config config-helper` subcommand) when the config specifies it in `cmd-path`, `cmd-args` fields (similar to `exec` support). This code path works without `googleauth` gem. Otherwise, `GoogleApplicationDefaultCredentials` path will be tried as before. (#410)
38
+ - `AmazonEksCredentials` helper for obtaining a token to authenticate against Amazon EKS. This is not currently integrated in `Config`, you will need to invoke it yourself. You'll need some aws gems that Kubeclient _does not_ include. (#404, #406)
39
+
40
+ ### Changed
41
+ - OpenID Connect tokens which cannot be validaded because we cannot identify the key they were signed with will be considered expired and refreshed as usual. (#407)
42
+
43
+ ## 4.3.0 — 2019-03-03
44
+
45
+ ### Changed
46
+ - `GoogleApplicationDefaultCredentials` will now automatically be used by `Config` if the `user[auth-provider][name] == 'gcp'` in the provided context. Note that `user[exec]` is checked first in anticipation of this functionality being added to GCP sometime in the future. Kubeclient _does not_ include the required `googleauth` gem, so you will need to include it in your calling application. (#394)
47
+
48
+ ### Added
49
+ - OpenID Connect credentials will automatically be used if the `user[auth-provider][name] == 'oidc'` in the provided context. Note that `user[exec]` is checked first. Kubeclient _does not_ include the required `openid_connect` gem, so you will need to include it in your calling application. (#396)
50
+
51
+ - Support for `json_patch_#{entity}` and `merge_patch_#{entity}`. `patch_#{entity}` will continue to use strategic merge patch. (#390)
52
+
7
53
  ## 4.2.2 — 2019-01-09
8
54
 
9
55
  ### Added
data/README.md CHANGED
@@ -166,29 +166,6 @@ namespace = File.read('/var/run/secrets/kubernetes.io/serviceaccount/namespace')
166
166
  ```
167
167
  You can find information about tokens in [this guide](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod) and in [this reference](http://kubernetes.io/docs/admin/authentication/).
168
168
 
169
- #### Google's Application Default Credentials
170
-
171
- On Google Compute Engine, Google App Engine, or Google Cloud Functions, as well as `gcloud`-configured systems
172
- with [application default credentials](https://developers.google.com/identity/protocols/application-default-credentials),
173
- you can use the token provider to authorize `kubeclient`.
174
-
175
- This requires the [`googleauth` gem](https://github.com/google/google-auth-library-ruby) that is _not_ included in
176
- `kubeclient` dependencies so you should add it to your bundle.
177
-
178
- ```ruby
179
- require 'googleauth'
180
-
181
- auth_options = {
182
- bearer_token: Kubeclient::GoogleApplicationDefaultCredentials.token
183
- }
184
- client = Kubeclient::Client.new(
185
- 'https://localhost:8443/api/', 'v1', auth_options: auth_options
186
- )
187
- ```
188
-
189
- Note that this token is good for one hour. If your code runs for longer than that, you should plan to
190
- acquire a new one.
191
-
192
169
  ### Non-blocking IO
193
170
 
194
171
  You can also use kubeclient with non-blocking sockets such as Celluloid::IO, see [here](https://github.com/httprb/http/wiki/Parallel-requests-with-Celluloid%3A%3AIO)
@@ -230,7 +207,7 @@ client = Kubeclient::Client.new(
230
207
 
231
208
  ### Timeouts
232
209
 
233
- Watching never times out.
210
+ Watching configures the socket to never time out (however, sooner or later all watches terminate).
234
211
 
235
212
  One-off actions like `.get_*`, `.delete_*` have a configurable timeout:
236
213
  ```ruby
@@ -303,12 +280,121 @@ context = config.context('default/192-168-99-100:8443/system:admin')
303
280
 
304
281
  Kubeclient::Client.new(
305
282
  context.api_endpoint,
306
- context.api_version,
283
+ 'v1',
307
284
  ssl_options: context.ssl_options,
308
285
  auth_options: context.auth_options
309
286
  )
310
287
  ```
311
288
 
289
+
290
+ #### Amazon EKS Credentials
291
+
292
+ On Amazon EKS by default the authentication method is IAM. When running kubectl a temporary token is generated by shelling out to
293
+ the aws-iam-authenticator binary which is sent to authenticate the user.
294
+ See [aws-iam-authenticator](https://github.com/kubernetes-sigs/aws-iam-authenticator).
295
+ To replicate that functionality, the `Kubeclient::AmazonEksCredentials` class can accept a set of IAM credentials and
296
+ contains a helper method to generate the authentication token for you.
297
+
298
+ This requires a set of gems which are _not_ included in
299
+ `kubeclient` dependencies (`aws-sigv4`) so you should add them to your bundle.
300
+ You will also require either the `aws-sdk` v2 or `aws-sdk-core` v3 gems to generate the required `Aws:Credentials` object to pass to this method.
301
+
302
+ To obtain a token:
303
+
304
+ ```ruby
305
+ require 'aws-sdk-core'
306
+ # Use keys
307
+ credentials = Aws::Credentials.new(access_key, secret_key)
308
+ # Or a profile
309
+ credentials = Aws::SharedCredentials.new(profile_name: 'default').credentials
310
+
311
+ auth_options = {
312
+ bearer_token: Kubeclient::AmazonEksCredentials.token(credentials, eks_cluster_name)
313
+ }
314
+ client = Kubeclient::Client.new(
315
+ eks_cluster_https_endpoint, 'v1', auth_options: auth_options
316
+ )
317
+ ```
318
+
319
+ Note that this returns a token good for one minute. If your code requires authorization for longer than that, you should plan to
320
+ acquire a new one, see [How to manually renew](#how-to-manually-renew-expired-credentials) section.
321
+
322
+ #### Google GCP credential plugin
323
+
324
+ If kubeconfig file has `user: {auth-provider: {name: gcp, cmd-path: ..., cmd-args: ..., token-key: ...}}`, the command will be executed to obtain a token.
325
+ (Normally this would be a `gcloud config config-helper` command.)
326
+
327
+ Note that this returns an expiring token. If your code requires authorization for a long time, you should plan to acquire a new one, see [How to manually renew](#how-to-manually-renew-expired-credentials) section.
328
+
329
+ #### Google's Application Default Credentials
330
+
331
+ On Google Compute Engine, Google App Engine, or Google Cloud Functions, as well as `gcloud`-configured systems
332
+ with [application default credentials](https://developers.google.com/identity/protocols/application-default-credentials),
333
+ kubeclient can use `googleauth` gem to authorize.
334
+
335
+ This requires the [`googleauth` gem](https://github.com/google/google-auth-library-ruby) that is _not_ included in
336
+ `kubeclient` dependencies so you should add it to your bundle.
337
+
338
+ If you use `Config.context(...).auth_options` and the kubeconfig file has `user: {auth-provider: {name: gcp}}`, but does not contain `cmd-path` key, kubeclient will automatically try this (raising LoadError if you don't have `googleauth` in your bundle).
339
+
340
+ Or you can obtain a token manually:
341
+
342
+ ```ruby
343
+ require 'googleauth'
344
+
345
+ auth_options = {
346
+ bearer_token: Kubeclient::GoogleApplicationDefaultCredentials.token
347
+ }
348
+ client = Kubeclient::Client.new(
349
+ 'https://localhost:8443/api/', 'v1', auth_options: auth_options
350
+ )
351
+ ```
352
+
353
+ Note that this returns a token good for one hour. If your code requires authorization for longer than that, you should plan to
354
+ acquire a new one, see [How to manually renew](#how-to-manually-renew-expired-credentials) section.
355
+
356
+ #### OIDC Auth Provider
357
+
358
+ If the cluster you are using has OIDC authentication enabled you can use the `openid_connect` gem to obtain
359
+ id-tokens if the one in your kubeconfig has expired.
360
+
361
+ This requires the [`openid_connect` gem](https://github.com/nov/openid_connect) which is not included in
362
+ the `kubeclient` dependencies so should be added to your own applications bundle.
363
+
364
+ The OIDC Auth Provider will not perform the initial setup of your `$KUBECONFIG` file. You will need to use something
365
+ like [`dexter`](https://github.com/gini/dexter) in order to configure the auth-provider in your `$KUBECONFIG` file.
366
+
367
+ If you use `Config.context(...).auth_options` and the `$KUBECONFIG` file has user: `{auth-provider: {name: oidc}}`,
368
+ kubeclient will automatically obtain a token (or use `id-token` if still valid)
369
+
370
+ Tokens are typically short-lived (e.g. 1 hour) and the expiration time is determined by the OIDC Provider (e.g. Google).
371
+ If your code requires authentication for longer than that you should obtain a new token periodically, see [How to manually renew](#how-to-manually-renew-expired-credentials) section.
372
+
373
+ Note: id-tokens retrieved via this provider are not written back to the `$KUBECONFIG` file as they would be when
374
+ using `kubectl`.
375
+
376
+ #### How to manually renew expired credentials
377
+
378
+ Kubeclient [does not yet](https://github.com/abonas/kubeclient/issues/393) help with this.
379
+
380
+ The division of labor between `Config` and `Context` objects may change, for now please make no assumptions at which stage `exec:` and `auth-provider:` are handled and whether they're cached.
381
+ The currently guaranteed way to renew is create a new `Config` object.
382
+
383
+ The more painful part is that you'll then need to create new `Client` object(s) with the credentials from new config.
384
+ So repeat all of this:
385
+ ```ruby
386
+ config = Kubeclient::Config.read(ENV['KUBECONFIG'] || '/path/to/.kube/config')
387
+ context = config.context
388
+ ssl_options = context.ssl_options
389
+ auth_options = context.auth_options
390
+
391
+ client = Kubeclient::Client.new(
392
+ context.api_endpoint, 'v1',
393
+ ssl_options: ssl_options, auth_options: auth_options
394
+ )
395
+ # and additional Clients if needed...
396
+ ```
397
+
312
398
  #### Security: Don't use config from untrusted sources
313
399
 
314
400
  `Config.read` is catastrophically unsafe — it will execute arbitrary command lines specified by the config!
@@ -334,16 +420,45 @@ We try to support the last 3 minor versions, matching the [official support poli
334
420
  Kubernetes 1.2 and below have known issues and are unsupported.
335
421
  Kubernetes 1.3 presumed to still work although nobody is really testing on such old versions...
336
422
 
337
- ## Examples:
423
+ ## Supported actions & examples:
424
+
425
+ Summary of main CRUD actions:
426
+
427
+ ```
428
+ get_foos(namespace: 'namespace', **opts) # namespaced collection
429
+ get_foos(**opts) # all namespaces or global collection
430
+
431
+ get_foo('name', 'namespace', opts) # namespaced
432
+ get_foo('name', nil, opts) # global
433
+
434
+ watch_foos(namespace: ns, **opts) # namespaced collection
435
+ watch_foos(**opts) # all namespaces or global collection
436
+ watch_foos(namespace: ns, name: 'name', **opts) # namespaced single object
437
+ watch_foos(name: 'name', **opts) # global single object
438
+
439
+ delete_foo('name', 'namespace', opts) # namespaced
440
+ delete_foo('name', nil, opts) # global
441
+
442
+ create_foo(Kubeclient::Resource.new({metadata: {name: 'name', namespace: 'namespace', ...}, ...}))
443
+ create_foo(Kubeclient::Resource.new({metadata: {name: 'name', ...}, ...})) # global
444
+
445
+ update_foo(Kubeclient::Resource.new({metadata: {name: 'name', namespace: 'namespace', ...}, ...}))
446
+ update_foo(Kubeclient::Resource.new({metadata: {name: 'name', ...}, ...})) # global
338
447
 
339
- #### Get all instances of a specific entity type
448
+ patch_foo('name', patch, 'namespace') # namespaced
449
+ patch_foo('name', patch) # global
450
+ ```
451
+
452
+ These grew to be quite inconsistent :confounded:, see https://github.com/abonas/kubeclient/issues/312 and https://github.com/abonas/kubeclient/issues/332 for improvement plans.
453
+
454
+ ### Get all instances of a specific entity type
340
455
  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`
341
456
 
342
457
  ```ruby
343
458
  pods = client.get_pods
344
459
  ```
345
460
 
346
- Get all entities of a specific type in a namespace:<br>
461
+ Get all entities of a specific type in a namespace:
347
462
 
348
463
  ```ruby
349
464
  services = client.get_services(namespace: 'development')
@@ -361,7 +476,22 @@ You can specify multiple labels (that option will return entities which have bot
361
476
  pods = client.get_pods(label_selector: 'name=redis-master,app=redis')
362
477
  ```
363
478
 
364
- Get all entities of a specific type in chunks:
479
+ There is also [a limited ability to filter by *some* fields](https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/). Which fields are supported is not documented, you can try and see if you get an error...
480
+ ```ruby
481
+ client.get_pods(field_selector: 'spec.nodeName=master-0')
482
+ ```
483
+
484
+ You can ask for entities at a specific version by specifying a parameter named `resource_version`:
485
+ ```ruby
486
+ pods = client.get_pods(resource_version: '0')
487
+ ```
488
+ but it's not guaranteed you'll get it. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions to understand the semantics.
489
+
490
+ With default (`as: :ros`) return format, the returned object acts like an array of the individual pods, but also supports a `.resourceVersion` method.
491
+
492
+ With `:parsed` and `:parsed_symbolized` formats, the returned data structure matches kubernetes list structure: it's a hash containing `metadata` and `items` keys, the latter containing the individual pods.
493
+
494
+ #### Get all entities of a specific type in chunks
365
495
 
366
496
  ```ruby
367
497
  continue = nil
@@ -416,7 +546,87 @@ Other formats are:
416
546
  - `:parsed` for `JSON.parse`
417
547
  - `:parsed_symbolized` for `JSON.parse(..., symbolize_names: true)`
418
548
 
419
- #### Delete an entity (by name)
549
+ ### Watch Receive entities updates
550
+
551
+ See https://kubernetes.io/docs/reference/using-api/api-concepts/#efficient-detection-of-changes for an overview.
552
+
553
+ It is possible to receive live update notices watching the relevant entities:
554
+
555
+ ```ruby
556
+ client.watch_pods do |notice|
557
+ # process notice data
558
+ end
559
+ ```
560
+
561
+ The notices have `.type` field which may be `'ADDED'`, `'MODIFIED'`, `'DELETED'`, or currently `'ERROR'`, and an `.object` field containing the object. **UPCOMING CHANGE**: In next major version, we plan to raise exceptions instead of passing on ERROR into the block.
562
+
563
+ For namespaced entities, the default watches across all namespaces, and you can specify `client.watch_secrets(namespace: 'foo')` to only watch in a single namespace.
564
+
565
+ You can narrow down using `label_selector:` and `field_selector:` params, like with `get_pods` methods.
566
+
567
+ You can also watch a single object by specifying `name:` e.g. `client.watch_nodes(name: 'gandalf')` (not namespaced so a name is enough) or `client.watch_pods(namespace: 'foo', name: 'bar')` (namespaced, need both params).
568
+ Note the method name is still plural! There is no `watch_pod`, only `watch_pods`. The yielded "type" remains the same — watch notices, it's just they'll always refer to the same object.
569
+
570
+ You can use `as:` param to control the format of the yielded notices.
571
+
572
+ #### All watches come to an end!
573
+
574
+ While nominally the watch block *looks* like an infinite loop, that's unrealistic. Network connections eventually get severed, and kubernetes apiserver is known to terminate watches.
575
+
576
+ Unfortunately, this sometimes raises an exception and sometimes the loop just exits. **UPCOMING CHANGE**: In next major version, non-deliberate termination will always raise an exception; the block will only exit silenty if stopped deliberately.
577
+
578
+ #### Deliberately stopping a watch
579
+
580
+ You can use `break` or `return` inside the watch block.
581
+
582
+ It is possible to interrupt the watcher from another thread with:
583
+
584
+ ```ruby
585
+ watcher = client.watch_pods
586
+
587
+ watcher.each do |notice|
588
+ # process notice data
589
+ end
590
+ # <- control will pass here after .finish is called
591
+
592
+ ### In another thread ###
593
+ watcher.finish
594
+ ```
595
+
596
+ #### Starting watch version
597
+
598
+ You can specify version to start from, commonly used in "List+Watch" pattern:
599
+ ```
600
+ list = client.get_pods
601
+ collection_version = list.resourceVersion
602
+ # or with other return formats:
603
+ list = client.get_pods(as: :parsed)
604
+ collection_version = list['metadata']['resourceVersion']
605
+
606
+ # note spelling resource_version vs resourceVersion.
607
+ client.watch_pods(resource_version: collection_version) do |notice|
608
+ # process notice data
609
+ end
610
+ ```
611
+ It's important to understand [the effects of unset/0/specific resource_version](https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions) as it modifies the behavior of the watch — in some modes you'll first see a burst of synthetic 'ADDED' notices for all existing objects.
612
+
613
+ If you re-try a terminated watch again without specific resourceVersion, you might see previously seen notices again, and might miss some events.
614
+
615
+ To attempt resuming a watch from same point, you can try using last resourceVersion observed during the watch. Or do list+watch again.
616
+
617
+ Whenever you ask for a specific version, you must be prepared for an 410 "Gone" error if the server no longer recognizes it.
618
+
619
+ #### Watch events about a particular object
620
+ Events are [entities in their own right](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#event-v1-core).
621
+ You can use the `field_selector` option as part of the watch methods.
622
+
623
+ ```ruby
624
+ client.watch_events(namespace: 'development', field_selector: 'involvedObject.name=redis-master') do |notice|
625
+ # process notice date
626
+ end
627
+ ```
628
+
629
+ ### Delete an entity (by name)
420
630
 
421
631
  For example: `delete_pod "pod name"` , `delete_replication_controller "rc name"`, `delete_node "node name"`, `delete_secret "secret name"`
422
632
 
@@ -440,7 +650,7 @@ delete_options = Kubeclient::Resource.new(
440
650
  client.delete_deployment(deployment_name, namespace, delete_options: delete_options)
441
651
  ```
442
652
 
443
- #### Create an entity
653
+ ### Create an entity
444
654
  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`
445
655
 
446
656
  Input parameter - object of type `Service`, `Pod`, `ReplicationController`.
@@ -466,7 +676,7 @@ service.metadata.labels.role = 'slave'
466
676
  client.create_service(service)
467
677
  ```
468
678
 
469
- #### Update an entity
679
+ ### Update an entity
470
680
  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`
471
681
 
472
682
  Input parameter - object of type `Pod`, `Service`, `ReplicationController` etc.
@@ -477,7 +687,7 @@ The below example is for v1
477
687
  updated = client.update_service(service1)
478
688
  ```
479
689
 
480
- #### Patch an entity (by name)
690
+ ### Patch an entity (by name)
481
691
  For example: `patch_pod`, `patch_service`, `patch_secret`, `patch_resource_quota`, `patch_persistent_volume`
482
692
 
483
693
  Input parameters - name (string) specifying the entity name, patch (hash) to be applied to the resource, optional: namespace name (string)
@@ -490,41 +700,19 @@ The below example is for v1
490
700
  patched = client.patch_pod("docker-registry", {metadata: {annotations: {key: 'value'}}}, "default")
491
701
  ```
492
702
 
493
- #### Get all entities of all types : all_entities
494
- Returns a hash with the following 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.
495
- This method is a convenience method instead of calling each entity's get method separately.
496
-
497
- ```ruby
498
- client.all_entities
499
- ```
500
-
501
- #### Receive entity updates
502
- It is possible to receive live update notices watching the relevant entities:
703
+ `patch_#{entity}` is called using a [strategic merge patch](https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#notes-on-the-strategic-merge-patch). `json_patch_#{entity}` and `merge_patch_#{entity}` are also available that use JSON patch and JSON merge patch, respectively. These strategies are useful for resources that do not support strategic merge patch, such as Custom Resources. Consult the [Kubernetes docs](https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment) for more information about the different patch strategies.
503
704
 
504
- ```ruby
505
- watcher = client.watch_pods
506
- watcher.each do |notice|
507
- # process notice data
508
- end
509
- ```
705
+ ### Get all entities of all types : all_entities
510
706
 
511
- It is possible to interrupt the watcher from another thread with:
707
+ Makes requests for all entities of each discovered kind (in this client's API group). This method is a convenience method instead of calling each entity's get method separately.
512
708
 
513
- ```ruby
514
- watcher.finish
515
- ```
516
-
517
- #### Watch events for a particular object
518
- You can use the `field_selector` option as part of the watch methods.
709
+ Returns a hash with keys being the *singular* entity kind, in lowercase underscore style. For example for core API group may return keys `"node'`, `"secret"`, `"service"`, `"pod"`, `"replication_controller"`, `"namespace"`, `"resource_quota"`, `"limit_range"`, `"endpoint"`, `"event"`, `"persistent_volume"`, `"persistent_volume_claim"`, `"component_status"`, `"service_account"`. Each key points to an EntityList of same type.
519
710
 
520
711
  ```ruby
521
- watcher = client.watch_events(namespace: 'development', field_selector: 'involvedObject.name=redis-master')
522
- watcher.each do |notice|
523
- # process notice date
524
- end
712
+ client.all_entities
525
713
  ```
526
714
 
527
- #### Get a proxy URL
715
+ ### Get a proxy URL
528
716
  You can get a complete URL for connecting a kubernetes entity via the proxy.
529
717
 
530
718
  ```ruby
@@ -539,7 +727,7 @@ client.proxy_url('pod', 'podname', 5001, 'ns')
539
727
  # => "https://localhost.localdomain:8443/api/v1/namespaces/ns/pods/podname:5001/proxy"
540
728
  ```
541
729
 
542
- #### Get the logs of a pod
730
+ ### Get the logs of a pod
543
731
  You can get the logs of a running pod, specifying the name of the pod and the
544
732
  namespace where the pod is running:
545
733
 
@@ -576,16 +764,21 @@ client.get_pod_log('pod-name', 'default', tail_lines: 10)
576
764
  # => "..."
577
765
  ```
578
766
 
767
+ Kubernetes can fetch a specific number of bytes from the log, but the exact size is not guaranteed and last line may not be terminated:
768
+ ```ruby
769
+ client.get_pod_log('pod-name', 'default', limit_bytes: 10)
770
+ # => "..."
771
+ ```
772
+
579
773
  You can also watch the logs of a pod to get a stream of data:
580
774
 
581
775
  ```ruby
582
- watcher = client.watch_pod_log('pod-name', 'default', container: 'ruby')
583
- watcher.each do |line|
776
+ client.watch_pod_log('pod-name', 'default', container: 'ruby') do |line|
584
777
  puts line
585
778
  end
586
779
  ```
587
780
 
588
- #### Process a template
781
+ ### OpenShift: Process a template
589
782
  Returns a processed template containing a list of objects to create.
590
783
  Input parameter - template (hash)
591
784
  Besides its metadata, the template should include a list of objects to be processed and a list of parameters