openshift-client 2.0.4__tar.gz → 2.0.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {openshift-client-2.0.4 → openshift_client-2.0.5}/PKG-INFO +142 -106
  2. {openshift-client-2.0.4 → openshift_client-2.0.5}/README.md +138 -101
  3. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/__init__.py +1 -1
  4. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/apiobject.py +10 -8
  5. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client.egg-info/PKG-INFO +142 -106
  6. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client.egg-info/requires.txt +2 -1
  7. {openshift-client-2.0.4 → openshift_client-2.0.5}/pyproject.toml +3 -4
  8. {openshift-client-2.0.4 → openshift_client-2.0.5}/LICENSE +0 -0
  9. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/action.py +0 -0
  10. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/ansible.py +0 -0
  11. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/base_verbs.py +0 -0
  12. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/config.py +0 -0
  13. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/context.py +0 -0
  14. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/decorators.py +0 -0
  15. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/model.py +0 -0
  16. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/naming.py +0 -0
  17. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/result.py +0 -0
  18. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/selector.py +0 -0
  19. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/status.py +0 -0
  20. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/test_apiobject.py +0 -0
  21. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/test_model.py +0 -0
  22. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/test_selector.py +0 -0
  23. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/test_util.py +0 -0
  24. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client/util.py +0 -0
  25. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client.egg-info/SOURCES.txt +0 -0
  26. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client.egg-info/dependency_links.txt +0 -0
  27. {openshift-client-2.0.4 → openshift_client-2.0.5}/packages/openshift_client.egg-info/top_level.txt +0 -0
  28. {openshift-client-2.0.4 → openshift_client-2.0.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openshift-client
3
- Version: 2.0.4
3
+ Version: 2.0.5
4
4
  Summary: OpenShift python client
5
5
  Author-email: Justin Pierce <jupierce@redhat.com>
6
6
  Maintainer-email: Brad Williams <brawilli@redhat.com>
@@ -205,20 +205,20 @@ Classifier: Intended Audience :: Information Technology
205
205
  Classifier: License :: OSI Approved :: Apache Software License
206
206
  Classifier: Operating System :: OS Independent
207
207
  Classifier: Programming Language :: Python
208
- Classifier: Programming Language :: Python :: 2
209
- Classifier: Programming Language :: Python :: 2.7
210
208
  Classifier: Programming Language :: Python :: 3
211
209
  Classifier: Programming Language :: Python :: 3.12
212
210
  Classifier: Topic :: Utilities
213
- Requires-Python: >=2.7
211
+ Requires-Python: >=3.0
214
212
  Description-Content-Type: text/markdown
215
213
  License-File: LICENSE
216
- Requires-Dist: pyyaml
214
+ Requires-Dist: build
217
215
  Requires-Dist: six
216
+ Requires-Dist: pyyaml
218
217
  Provides-Extra: ssh
219
218
  Requires-Dist: paramiko; extra == "ssh"
220
219
 
221
220
  # Openshift Python Client
221
+
222
222
  <!-- Install doctoc with `npm install -g doctoc` then `doctoc README.md --github` -->
223
223
 
224
224
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
@@ -228,73 +228,82 @@ Requires-Dist: paramiko; extra == "ssh"
228
228
  - [Overview](#overview)
229
229
  - [Reader Prerequisites](#reader-prerequisites)
230
230
  - [Setup](#setup)
231
- - [Prerequisites](#prerequisites)
232
- - [Installation Instructions](#installation-instructions)
233
- - [Using PIP](#using-pip)
234
- - [For development](#for-development)
231
+ - [Prerequisites](#prerequisites)
232
+ - [Installation Instructions](#installation-instructions)
233
+ - [Using PIP](#using-pip)
234
+ - [For development](#for-development)
235
235
  - [Usage](#usage)
236
- - [Quickstart](#quickstart)
237
- - [Selectors](#selectors)
238
- - [APIObjects](#apiobjects)
239
- - [Making changes to APIObjects](#making-changes-to-apiobjects)
240
- - [Running within a Pod](#running-within-a-pod)
241
- - [Tracking oc invocations](#tracking-oc-invocations)
242
- - [Time limits](#time-limits)
243
- - [Advanced contexts](#advanced-contexts)
244
- - [Something missing?](#something-missing)
245
- - [Running oc on a bastion host](#running-oc-on-a-bastion-host)
246
- - [Gathering reports and logs with selectors](#gathering-reports-and-logs-with-selectors)
247
- - [Advanced verbs:](#advanced-verbs)
236
+ - [Quickstart](#quickstart)
237
+ - [Selectors](#selectors)
238
+ - [APIObjects](#apiobjects)
239
+ - [Making changes to APIObjects](#making-changes-to-apiobjects)
240
+ - [Running within a Pod](#running-within-a-pod)
241
+ - [Tracking oc invocations](#tracking-oc-invocations)
242
+ - [Time limits](#time-limits)
243
+ - [Advanced contexts](#advanced-contexts)
244
+ - [Something missing?](#something-missing)
245
+ - [Running oc on a bastion host](#running-oc-on-a-bastion-host)
246
+ - [Gathering reports and logs with selectors](#gathering-reports-and-logs-with-selectors)
247
+ - [Advanced verbs:](#advanced-verbs)
248
248
  - [Examples](#examples)
249
249
  - [Environment Variables](#environment-variables)
250
- - [Defaults when invoking `oc`](#defaults-when-invoking-oc)
251
- - [Master timeout](#master-timeout)
252
- - [SSH Client Host](#ssh-client-host)
250
+ - [Defaults when invoking `oc`](#defaults-when-invoking-oc)
251
+ - [Master timeout](#master-timeout)
252
+ - [SSH Client Host](#ssh-client-host)
253
253
 
254
254
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
255
255
 
256
256
  ## Overview
257
+
257
258
  The [openshift-client-python](https://www.github.com/openshift/openshift-client-python) library aims to provide a readable, concise, comprehensive, and fluent
258
259
  API for rich interactions with an [OpenShift](https://www.openshift.com) cluster. Unlike other clients, this library exclusively uses the command
259
260
  line tool (oc) to achieve the interactions. This approach comes with important benefits and disadvantages when compared
260
261
  to other client libraries.
261
262
 
262
263
  Pros:
264
+
263
265
  - No additional software needs to be installed on the cluster. If a system with python support can (1) invoke `oc`
264
- locally OR (2) ssh to a host and invoke `oc`, you can use the library.
266
+ locally OR (2) ssh to a host and invoke `oc`, you can use the library.
265
267
  - Portable. If you have python and `oc` working, you don't need to worry about OpenShift versions or machine architectures.
266
268
  - Custom resources are supported and treated just like any other resource. There is no need to generate code to support them.
267
269
  - Quick to learn. If you understand the `oc` command line interface, you can use this library.
268
270
 
269
271
  Cons:
272
+
270
273
  - This API is not intended to implement something as complex as a controller. For example, it does not implement
271
- watch functionality. If you can't imagine accomplishing your use case through CLI interactions, this API is probably
272
- not the right starting point for it.
274
+ watch functionality. If you can't imagine accomplishing your use case through CLI interactions, this API is probably
275
+ not the right starting point for it.
273
276
  - If you care about whether a REST API returns a particular error code, this API is probably not for you. Since it
274
- is based on the CLI, high level return codes are used to determine success or failure.
277
+ is based on the CLI, high level return codes are used to determine success or failure.
275
278
 
276
279
  ## Reader Prerequisites
277
- * Familiarity with OpenShift [command line interface](https://docs.openshift.org/latest/cli_reference/basic_cli_operations.html)
278
- is highly encouraged before exploring the API's features. The API leverages the [oc](https://docs.openshift.org/latest/cli_reference/index.html)
279
- binary and, in many cases, passes method arguments directly on to the command line. This document cannot, therefore,
280
- provide a complete description of all possible OpenShift interactions -- the user may need to reference
281
- the CLI documentation to find the pass-through arguments a given interaction requires.
280
+
281
+ * Familiarity with OpenShift [command line interface](https://docs.okd.io/latest/cli_reference/index.html)
282
+ is highly encouraged before exploring the API's features. The API leverages
283
+ the [oc](https://docs.okd.io/latest/cli_reference/openshift_cli/getting-started-cli.html#cli-getting-started)
284
+ binary and, in many cases, passes method arguments directly on to the command line. This document cannot, therefore,
285
+ provide a complete description of all possible OpenShift interactions -- the user may need to reference
286
+ the CLI documentation to find the pass-through arguments a given interaction requires.
282
287
 
283
288
  * A familiarity with Python is assumed.
284
289
 
285
290
  ## Setup
291
+
286
292
  ### Prerequisites
293
+
287
294
  1. Download and install the OpenShift [command-line Tools](https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest/) needed to access your OpenShift cluster.
288
295
 
289
296
  ### Installation Instructions
290
297
 
291
298
  #### Using PIP
299
+
292
300
  1. Install the `openshift-client` module from PyPI.
293
301
  ```bash
294
302
  sudo pip install openshift-client
295
303
  ```
296
304
 
297
305
  #### For development
306
+
298
307
  1. Git clone https://github.com/openshift/openshift-client-python.git (or your fork).
299
308
  2. Add required libraries
300
309
  ```bash
@@ -306,6 +315,7 @@ the CLI documentation to find the pass-through arguments a given interaction req
306
315
  ## Usage
307
316
 
308
317
  ### Quickstart
318
+
309
319
  Any standard Python application should be able to use the API if it imports the openshift package. The simplest
310
320
  possible way to begin using the API is login to your target cluster before running your first application.
311
321
 
@@ -319,20 +329,20 @@ print('OpenShift client version: {}'.format(oc.get_client_version()))
319
329
  print('OpenShift server version: {}'.format(oc.get_server_version()))
320
330
 
321
331
  # Set a project context for all inner `oc` invocations and limit execution to 10 minutes
322
- with oc.project('openshift-infra'), oc.timeout(10*60):
332
+ with oc.project('openshift-infra'), oc.timeout(10 * 60):
323
333
  # Print the list of qualified pod names (e.g. ['pod/xyz', 'pod/abc', ...] in the current project
324
334
  print('Found the following pods in {}: {}'.format(oc.get_project_name(), oc.selector('pods').qnames()))
325
-
335
+
326
336
  # Read in the current state of the pod resources and represent them as python objects
327
337
  for pod_obj in oc.selector('pods').objects():
328
-
338
+
329
339
  # The APIObject class exposes several convenience methods for interacting with objects
330
340
  print('Analyzing pod: {}'.format(pod_obj.name()))
331
341
  pod_obj.print_logs(timestamps=True, tail=15)
332
-
342
+
333
343
  # If you need access to the underlying resource definition, get a Model instance for the resource
334
344
  pod_model = pod_obj.model
335
-
345
+
336
346
  # Model objects enable dot notation and allow you to navigate through resources
337
347
  # to an arbitrary depth without checking if any ancestor elements exist.
338
348
  # In the following example, there is no need for boilerplate like:
@@ -347,6 +357,7 @@ with oc.project('openshift-infra'), oc.timeout(10*60):
347
357
  ```
348
358
 
349
359
  ### Selectors
360
+
350
361
  Selectors are a central concept used by the API to interact with collections
351
362
  of OpenShift resources. As the name implies, a "selector" selects zero or
352
363
  more resources on a server which satisfy user specified criteria. An apt
@@ -368,10 +379,10 @@ sa_selector = oc.selector(["serviceaccount/deployer", "serviceaccount/builder"])
368
379
 
369
380
  # Performing an operation will act on all selected resources. In this case,
370
381
  # both serviceaccounts are labeled.
371
- sa_selector.label({"mylabel" : "myvalue"})
382
+ sa_selector.label({"mylabel": "myvalue"})
372
383
 
373
384
  # Selectors can also select based on kind and labels.
374
- sa_label_selector = oc.selector("sa", labels={"mylabel":"myvalue"})
385
+ sa_label_selector = oc.selector("sa", labels={"mylabel": "myvalue"})
375
386
 
376
387
  # We should find the service accounts we just labeled.
377
388
  print("Found labeled serviceaccounts: " + sa_label_selector.names())
@@ -407,7 +418,7 @@ project = projects[0]
407
418
 
408
419
  # The APIObject exposes methods providing simple access to metadata and common operations.
409
420
  print('The project is: {}/{}'.format(project.kind(), project.name()))
410
- project.label({ 'mylabel': 'myvalue' })
421
+ project.label({'mylabel': 'myvalue'})
411
422
 
412
423
  # And the APIObject allow you to interact with an object's data via the 'model' attribute.
413
424
  # The Model is similar to a standard dict, but also allows dot notation to access elements
@@ -444,6 +455,7 @@ oc.selector('node/alpha').object().model.status.conditions.can_match(
444
455
  }
445
456
  )
446
457
 
458
+
447
459
  # can_match can also ensure nest objects and list are present within a resource. Several
448
460
  # of these types of checks are already implemented in the openshift.status module.
449
461
  def is_route_admitted(apiobj):
@@ -461,8 +473,8 @@ def is_route_admitted(apiobj):
461
473
  })
462
474
  ```
463
475
 
464
-
465
476
  ### Making changes to APIObjects
477
+
466
478
  ```python
467
479
  # APIObject exposes simple interfaces to delete and patch the resource it represents.
468
480
  # But, more interestingly, you can make detailed changes to the model and apply those
@@ -471,6 +483,7 @@ def is_route_admitted(apiobj):
471
483
  project.model.metadata.labels['my_label'] = 'myvalue'
472
484
  project.apply()
473
485
 
486
+
474
487
  # If modifying the underlying API resources could be contentious, use the more robust
475
488
  # modify_and_apply method which can retry the operation multiple times -- refreshing
476
489
  # with the current object state between failures.
@@ -480,6 +493,7 @@ def make_model_change(apiobj):
480
493
  apiobj.model.data['somefile.yaml'] = 'wyxz'
481
494
  return True
482
495
 
496
+
483
497
  # modify_and_apply will call the function and attempt to apply its changes to the model
484
498
  # if it returns True. If the apply is rejected by the API, the function will pull
485
499
  # the latest object content, call make_model_change again, and try the apply again
@@ -508,18 +522,20 @@ def set_unmanaged_in_cvo(apiobj):
508
522
  apiobj.model.spec.overrides.append(desired_entry)
509
523
  return True
510
524
 
525
+
511
526
  result, changed = oc.selector('clusterversion.config.openshift.io/version').object().modify_and_apply(set_unmanaged_in_cvo)
512
527
  if changed:
513
528
  context.report_change('Instructed CVO to ignore openshift-samples operator')
514
529
 
515
530
  ```
516
531
 
517
-
518
532
  ### Running within a Pod
533
+
519
534
  It is simple to use the API within a Pod. The `oc` binary automatically
520
535
  detects it is running within a container and automatically uses the Pod's serviceaccount token/cacert.
521
536
 
522
537
  ### Tracking oc invocations
538
+
523
539
  It is good practice to setup at least one tracking context within your application so that
524
540
  you will be able to easily analyze what `oc` invocations were made on your behalf and the result
525
541
  of those operations. *Note that details about all `oc` invocations performed within the context will
@@ -535,61 +551,63 @@ with oc.tracking() as tracker:
535
551
  print('Current user: {}'.format(oc.whoami()))
536
552
  except:
537
553
  print('Error acquiring current username')
538
-
554
+
539
555
  # Print out details about the invocations made within this context.
540
556
  print(tracker.get_result())
541
557
  ```
542
558
 
543
559
  In this case, the tracking output would look something like:
560
+
544
561
  ```json
545
562
  {
546
- "status": 0,
547
- "operation": "tracking",
548
- "actions": [
549
- {
550
- "status": 0,
551
- "verb": "project",
552
- "references": {},
553
- "in": null,
554
- "out": "aos-cd\n",
555
- "err": "",
556
- "cmd": [
557
- "oc",
558
- "project",
559
- "-q"
560
- ],
561
- "elapsed_time": 0.15344810485839844,
562
- "internal": false,
563
- "timeout": false,
564
- "last_attempt": true
565
- },
566
- {
567
- "status": 0,
568
- "verb": "whoami",
569
- "references": {},
570
- "in": null,
571
- "out": "aos-ci-jenkins\n",
572
- "err": "",
573
- "cmd": [
574
- "oc",
575
- "whoami"
576
- ],
577
- "elapsed_time": 0.6328380107879639,
578
- "internal": false,
579
- "timeout": false,
580
- "last_attempt": true
581
- }
582
- ]
563
+ "status": 0,
564
+ "operation": "tracking",
565
+ "actions": [
566
+ {
567
+ "status": 0,
568
+ "verb": "project",
569
+ "references": {},
570
+ "in": null,
571
+ "out": "aos-cd\n",
572
+ "err": "",
573
+ "cmd": [
574
+ "oc",
575
+ "project",
576
+ "-q"
577
+ ],
578
+ "elapsed_time": 0.15344810485839844,
579
+ "internal": false,
580
+ "timeout": false,
581
+ "last_attempt": true
582
+ },
583
+ {
584
+ "status": 0,
585
+ "verb": "whoami",
586
+ "references": {},
587
+ "in": null,
588
+ "out": "aos-ci-jenkins\n",
589
+ "err": "",
590
+ "cmd": [
591
+ "oc",
592
+ "whoami"
593
+ ],
594
+ "elapsed_time": 0.6328380107879639,
595
+ "internal": false,
596
+ "timeout": false,
597
+ "last_attempt": true
598
+ }
599
+ ]
583
600
  }
584
601
  ```
585
602
 
586
- Alternatively, you can record actions yourself by passing an action_handler to the tracking
603
+ Alternatively, you can record actions yourself by passing an action_handler to the tracking
587
604
  contextmanager. Your action handler will be invoked each time an `oc` invocation completes.
588
605
 
589
606
  ```python
590
607
  def print_action(action):
591
608
  print('Performed: {} - status={}'.format(action.cmd, action.status))
592
609
 
610
+
593
611
  with oc.tracking(action_handler=print_action):
594
612
  try:
595
613
  print('Current project: {}'.format(oc.get_project_name()))
@@ -600,14 +618,16 @@ with oc.tracking(action_handler=print_action):
600
618
  ```
601
619
 
602
620
  ### Time limits
621
+
603
622
  Have a script you want to ensure succeeds or fails within a specific period of time? Use
604
- a `timeout` context. Timeout contexts can be nested - if any timeout context expires,
605
- the current oc invocation will be killed.
623
+ a `timeout` context. Timeout contexts can be nested - if any timeout context expires,
624
+ the current oc invocation will be killed.
606
625
 
607
626
  ```python
608
627
  #!/usr/bin/python
609
628
  import openshift_client as oc
610
629
 
630
+
611
631
  def node_is_ready(node):
612
632
  ready = node.model.status.conditions.can_match({
613
633
  'type': 'Ready',
@@ -626,38 +646,42 @@ You will be able to see in `tracking` context results that a timeout occurred fo
626
646
  invocation. The `timeout` field will be set to `True`.
627
647
 
628
648
  ### Advanced contexts
629
- If you are unable to use a KUBECONFIG environment variable or need fine grained control over the
630
- server/credentials you communicate with for each invocation, use openshift-client-python contexts.
631
- Contexts can be nested and cause oc invocations within them to use the most recently established
649
+
650
+ If you are unable to use a KUBECONFIG environment variable or need fine grained control over the
651
+ server/credentials you communicate with for each invocation, use openshift-client-python contexts.
652
+ Contexts can be nested and cause oc invocations within them to use the most recently established
632
653
  context information.
633
654
 
634
655
  ```python
635
656
  with oc.api_server('https:///....'): # use the specified api server for nested oc invocations.
636
-
657
+
637
658
  with oc.token('abc..'): # --server=... --token=abc... will be included in inner oc invocations.
638
659
  print("Current project: " + oc.get_project_name())
639
-
660
+
640
661
  with oc.token('def..'): # --server=... --token=def... will be included in inner oc invocations.
641
662
  print("Current project: " + oc.get_project_name())
642
663
  ```
643
664
 
644
- You can control the loglevel specified for `oc` invocations.
665
+ You can control the loglevel specified for `oc` invocations.
666
+
645
667
  ```python
646
668
  with oc.loglevel(6):
647
- # all oc invocations within this context will be invoked with --loglevel=6
669
+ # all oc invocations within this context will be invoked with --loglevel=6
648
670
  oc...
649
671
  ```
650
672
 
651
673
  You ask `oc` to skip TLS verification if necessary.
674
+
652
675
  ```python
653
676
  with oc.tls_verify(enable=False):
654
- # all oc invocations within this context will be invoked with --insecure-skip-tls-verify
677
+ # all oc invocations within this context will be invoked with --insecure-skip-tls-verify
655
678
  oc...
656
679
  ```
657
680
 
658
681
  ### Something missing?
659
- Most common API iterations have abstractions, but if there is no openshift-client-python API
660
- exposing the `oc` function you want to run, you can always use `oc.invoke` to directly pass arguments to
682
+
683
+ Most common API iterations have abstractions, but if there is no openshift-client-python API
684
+ exposing the `oc` function you want to run, you can always use `oc.invoke` to directly pass arguments to
661
685
  an `oc` invocation on your host.
662
686
 
663
687
  ```python
@@ -683,6 +707,7 @@ occur on the remote host.
683
707
  ### Gathering reports and logs with selectors
684
708
 
685
709
  Various objects within OpenShift have logs associated with them:
710
+
686
711
  - pods
687
712
  - deployments
688
713
  - daemonsets
@@ -701,6 +726,7 @@ with oc.project('openshift-monitoring'):
701
726
  ```
702
727
 
703
728
  The above example would output something like:
729
+
704
730
  ```
705
731
  Container: openshift-monitoring:pod/node-exporter-hw5r5(node-exporter)
706
732
  time="2018-10-22T21:07:36Z" level=info msg="Starting node_exporter (version=0.16.0, branch=, revision=)" source="node_exporter.go:82"
@@ -709,19 +735,21 @@ time="2018-10-22T21:07:36Z" level=info msg=" - arp" source="node_exporter.go:97"
709
735
  ...
710
736
  ```
711
737
 
712
- Note that these logs are held in memory. Use tail or other available method parameters to ensure
738
+ Note that these logs are held in memory. Use tail or other available method parameters to ensure
713
739
  predictable and efficient results.
714
740
 
715
741
  To simplify even further, you can ask the library to pretty-print the logs for you:
742
+
716
743
  ```python
717
744
  oc.selector(['daemonset', 'deployment']).print_logs()
718
745
  ```
719
746
 
720
- And to quickly pull together significant diagnostic data on selected objects, use `report()` or `print_report()`.
747
+ And to quickly pull together significant diagnostic data on selected objects, use `report()` or `print_report()`.
721
748
  A report includes the following information for each selected object, if available:
749
+
722
750
  - `object` - The current state of the object.
723
751
  - `describe` - The output of describe on the object.
724
- - `logs` - If applicable, a map of logs -- one of each container associated with the object.
752
+ - `logs` - If applicable, a map of logs -- one of each container associated with the object.
725
753
 
726
754
  ```python
727
755
  # Pretty-print a detail set of data about all deploymentconfigs, builds, and configmaps in the
@@ -732,23 +760,26 @@ oc.selector(['dc', 'build', 'configmap']).print_report()
732
760
  ### Advanced verbs:
733
761
 
734
762
  Running oc exec on a pod.
763
+
735
764
  ```python
736
765
  result = oc.selector('pod/alertmanager-main-0').object().execute(['cat'],
737
766
  container_name='alertmanager',
738
767
  stdin='stdin for cat')
739
- print(result.out())
768
+ print(result.out())
740
769
  ```
741
770
 
742
771
  Finding all pods running on a node:
772
+
743
773
  ```python
744
774
  with oc.client_host():
745
775
  for node_name in oc.selector('nodes').qnames():
746
776
  print('Pods running on node: {}'.format(node_name))
747
- for pod_obj in oc.get_pods_by_node(node_name):
748
- print(' {}'.format(pod_obj.fqname()))
777
+ for pod_obj in oc.get_pods_by_node(node_name):
778
+ print(' {}'.format(pod_obj.fqname()))
749
779
  ```
750
780
 
751
781
  Example output:
782
+
752
783
  ```
753
784
  ...
754
785
  Pods running on node: node/ip-172-31-18-183.ca-central-1.compute.internal
@@ -764,11 +795,14 @@ Pods running on node: node/ip-172-31-18-183.ca-central-1.compute.internal
764
795
  - [Some unit tests](examples/cluster_tests.py)
765
796
 
766
797
  ## Environment Variables
767
- To allow openshift-client-python applications to be portable between environments without needing to be modified,
768
- you can specify many default contexts in the environment.
798
+
799
+ To allow openshift-client-python applications to be portable between environments without needing to be modified,
800
+ you can specify many default contexts in the environment.
769
801
 
770
802
  ### Defaults when invoking `oc`
803
+
771
804
  Establishing explicit contexts within an application will override these environment defaults.
805
+
772
806
  - `OPENSHIFT_CLIENT_PYTHON_DEFAULT_OC_PATH` - default path to use when invoking `oc`
773
807
  - `OPENSHIFT_CLIENT_PYTHON_DEFAULT_CONFIG_PATH` - default `--kubeconfig` argument
774
808
  - `OPENSHIFT_CLIENT_PYTHON_DEFAULT_API_SERVER` - default `--server` argument
@@ -778,20 +812,22 @@ Establishing explicit contexts within an application will override these environ
778
812
  - `OPENSHIFT_CLIENT_PYTHON_DEFAULT_SKIP_TLS_VERIFY` - default `--insecure-skip-tls-verify`
779
813
 
780
814
  ### Master timeout
815
+
781
816
  Defines an implicit outer timeout(..) context for the entire application. This allows you to ensure
782
817
  that an application terminates within a reasonable time, even if the author of the application has
783
818
  not included explicit timeout contexts. Like any `timeout` context, this value is not overridden
784
819
  by subsequent `timeout` contexts within the application. It provides an upper bound for the entire
785
820
  application's oc interactions.
786
821
 
787
- - `OPENSHIFT_CLIENT_PYTHON_MASTER_TIMEOUT`
822
+ - `OPENSHIFT_CLIENT_PYTHON_MASTER_TIMEOUT`
788
823
 
789
824
  ### SSH Client Host
790
- In some cases, it is desirable to run an openshift-client-python application using a local `oc` binary and
825
+
826
+ In some cases, it is desirable to run an openshift-client-python application using a local `oc` binary and
791
827
  in other cases, the `oc` binary resides on a remote client. Encoding this decision in the application
792
828
  itself is unnecessary.
793
829
 
794
- Simply wrap you application in a `client_host` context without arguments. This will try to pull
830
+ Simply wrap you application in a `client_host` context without arguments. This will try to pull
795
831
  client host information from environment variables if they are present. If they are not present,
796
832
  the application will execute on the local host.
797
833
 
@@ -800,7 +836,7 @@ in the environment. Otherwise, `oc` interactions will be executed on the host ru
800
836
 
801
837
  ```python
802
838
  with oc.client_host(): # if OPENSHIFT_CLIENT_PYTHON_DEFAULT_SSH_HOSTNAME if not defined in the environment, this is a no-op
803
- print( 'Found nodes: {}'.format(oc.selector('nodes').qnames()) )
839
+ print('Found nodes: {}'.format(oc.selector('nodes').qnames()))
804
840
  ```
805
841
 
806
842
  - `OPENSHIFT_CLIENT_PYTHON_DEFAULT_SSH_HOSTNAME` - The hostname on which the `oc` binary resides