...

Text file src/sigs.k8s.io/cli-utils/README.md

Documentation: sigs.k8s.io/cli-utils

     1# cli-utils
     2
     3`cli-utils` is a collection of Go libraries designed to facilitate bulk
     4actuation of Kubernetes resource objects by wraping and enahancing
     5`kubectl apply` with a more user friendly abstraction.
     6
     7While the name indicates a focus on CLI utilities, the project has evolved to
     8encompass a broader scope, including CLI use and server-side use in GitOps
     9controllers.
    10
    11## Features
    12
    131. **Pruning**
    141. **Status Interpretation**
    151. **Status Lookup**
    161. **Diff & Preview**
    171. **Waiting for Reconciliation**
    181. **Resource Ordering**
    191. **Explicit Dependency Ordering**
    201. **Implicit Dependency Ordering**
    211. **Apply Time Mutation**
    221. **CLI Printers**
    23
    24### Pruning
    25
    26The Applier automatically deletes objects that were previously applied and then
    27removed from the input set on a subsequent apply.
    28
    29The current implementation of `kubectl apply --prune` uses labels to identify the
    30set of previously applied objects in the prune set calculation. But the use of labels
    31has significant downsides. The current `kubectl apply --prune` implementation is alpha,
    32and it is improbable that it will graduate to beta. `cli-utils` attempts to address
    33the current `kubectl apply --prune` deficiencies by storing the set of previously
    34applied objects in an **inventory** object which is applied to the cluster. The
    35reference implementation uses a `ConfigMap` as an **inventory** object, and references
    36to the applied objects are stored in the `data` section of the `ConfigMap`.
    37
    38The following example illustrates a `ConfigMap` resource used as an inventory object:
    39
    40```yaml
    41apiVersion: v1
    42kind: ConfigMap
    43metadata:
    44  # DANGER: Do not change the inventory object namespace.
    45  # Changing the namespace will cause a loss of continuity
    46  # with previously applied grouped objects. Set deletion
    47  # and pruning functionality will be impaired.
    48  namespace: test-namespace
    49  # NOTE: The name of the inventory object does NOT have
    50  # any impact on group-related functionality such as
    51  # deletion or pruning.
    52  name: inventory-26306433
    53  labels:
    54    # DANGER: Do not change the value of this label.
    55    # Changing this value will cause a loss of continuity
    56    # with previously applied grouped objects. Set deletion
    57    # and pruning functionality will be impaired.
    58    cli-utils.sigs.k8s.io/inventory-id: 46d8946c-c1fa-4e1d-9357-b37fb9bae25f
    59```
    60
    61### Status Interpretation
    62
    63The `kstatus` library can be used to read an object's current status and interpret
    64whether that object has be reconciled (aka Current) or not, including whether it
    65is expected to never reconcile (aka Failed).
    66
    67### Status Lookup
    68
    69In addition to performing interpretation of status from an object in-memory,
    70`cli-utils` can also be used to query status from the server, allowing you to
    71retrieve the status of previously or concurrently applied objects.
    72
    73### Diff & Preview
    74
    75`cli-utils` can be used to compare local object manifests with remote objects
    76from the server. These can be compared locally with diff or remotely with
    77preview (aka dry-run). This can be useful for discovering drift or previewing
    78which changes would be made, if the local manifests were applied.
    79
    80### Waiting for Reconciliation
    81
    82The Applier automatically watches applied and deleted objects and tracks their
    83status, blocking until the objects have reconciled, failed, or been fully
    84deleted.
    85
    86This functionality is similar to `kubectl delete <resource> <name> --wait`, in
    87that it waits for all finalizers to complete, except it also works for creates
    88and updates.
    89
    90While there is a `kubectl apply <resource> <name> --wait`, it only waits for
    91deletes when combined with `--prune`. `cli-utils` provides an alternative that
    92works for all spec changes, waiting for reconciliation, the convergence of
    93status to the desired specification. After reconciliation, it is expected that
    94the object has reached a steady state until the specification is changed again.
    95
    96### Resource Ordering
    97
    98The Applier and Destroyer use resource type to determine which order to apply
    99and delete objects.
   100
   101In contrast, when using `kubectl apply`, the objects are applied in alphanumeric
   102order of their file names, and top to bottom in each file. With `cli-utils`,
   103this manual sorting is unnecessary for many common use cases.
   104
   105### Explicit Dependency Ordering
   106
   107While resource ordering provides a smart default user experience, sometimes
   108resource type alone is not enough to determine desired ordering. In these cases,
   109the user can use explicit dependency ordering by adding a
   110`config.kubernetes.io/depends-on: <OBJECT_REFERENCE>` annotation to an object.
   111
   112The Applier and Destroyer use these explicit dependency directives to build a
   113dependency tree and flatten it for determining apply ordering. When deleting,
   114the order is reversed, ensuring that dependencies are not deleted before the
   115objects that depend on them (aka dependents).
   116
   117In addition to ordering the applies and deletes, dependency ordering also waits
   118for dependency reconciliation when applying and deletion finalization when
   119deleting. This ensures that dependencies are not just applied first, but have
   120reconciled before their dependents are applied. Likewise, dependents are not
   121just deleted first, but have completed finalization before their dependencies
   122are deleted.
   123
   124Also, because dependency ordering is enforced during actuation, a dependency
   125cannot be pruned by the Applier unless all its dependents are also deleted. This
   126prevents accidental premature deletion of objects that are still in active use.
   127
   128In the following example, the `config.kubernetes.io/depends-on` annotation
   129identifies that `pod-c` must be successfully applied prior to `pod-a`
   130actuation:
   131
   132```yaml
   133apiVersion: v1
   134kind: Pod
   135metadata:
   136  name: pod-a
   137  annotations:
   138    config.kubernetes.io/depends-on: /namespaces/default/Pod/pod-c
   139spec:
   140  containers:
   141    - name: kubernetes-pause
   142      image: k8s.gcr.io/pause:2.0
   143```
   144
   145### Implicit Dependency Ordering
   146
   147In addition to being able to specify explicit dependencies, `cli-utils`
   148automatically detects some implicit dependencies.
   149
   150Implicit dependencies include:
   151
   1521. Namespace-scoped resource objects depend on their Namespace.
   1532. Custom resource objects depend on their Custom Resource Definition
   154
   155Like resource ordering, implicit dependency ordering improves the apply and
   156delete experience to reduce the need to manually specify ordering for many
   157common use cases. This allows more objects to be applied together all at once,
   158with less manual orchestration.
   159
   160### Apply-Time Mutation
   161
   162The Applier can dynamically modify objects before applying them, performing
   163field value substitution using input(s) from dependency fields.
   164
   165This allows for applying objects together in a set that you would otherwise need
   166to seperate into multiple sets, with manual modifications between applies.
   167
   168Apply-Time Mutation is configured using the
   169`config.kubernetes.io/apply-time-mutation` annotation on the target object to be
   170modified. The annotation may specify one or more substitutions. Each
   171substitution includes a source object, and source field path, and a target
   172field path, with an optional token. 
   173
   174If the token is specified, the token is
   175replaced in the target field value string with the source field value. If the
   176token is not specified, the whole target field value is replaced with the
   177source field value. This alternatively allows either templated interpretation or
   178type preservation.
   179
   180The source and target field paths are specified using JSONPath, allowing for
   181robust navigation of complex resource field hierarchies using a familiar syntax.
   182
   183In the following example, `pod-a` will substitute the IP address and port from
   184the spec and status of the source `pod-b` into the spec of the target `pod-a`:
   185
   186```yaml
   187kind: Pod
   188apiVersion: v1
   189metadata:
   190  name: pod-a
   191  annotations:
   192    config.kubernetes.io/apply-time-mutation: |
   193      - sourceRef:
   194          kind: Pod
   195          name: pod-b
   196        sourcePath: $.status.podIP
   197        targetPath: $.spec.containers[?(@.name=="nginx")].env[?(@.name=="SERVICE_HOST")].value
   198        token: ${pob-b-ip}
   199      - sourceRef:
   200          kind: Pod
   201          name: pod-b
   202        sourcePath: $.spec.containers[?(@.name=="nginx")].ports[?(@.name=="tcp")].containerPort
   203        targetPath: $.spec.containers[?(@.name=="nginx")].env[?(@.name=="SERVICE_HOST")].value
   204        token: ${pob-b-port}
   205spec:
   206  containers:
   207  - name: nginx
   208    image: nginx:1.21
   209    ports:
   210    - name: tcp
   211      containerPort: 80
   212    env:
   213    - name: SERVICE_HOST
   214      value: "${pob-b-ip}:${pob-b-port}"
   215```
   216
   217The primary reason to do this with Apply-Time Mutation, instead of client-side
   218manifest templating is that the pod IP is populated by a controller at runtime
   219during reconciliation, and is not known before applying. 
   220
   221That said, this is a toy example using built-in types. For pods, you probably
   222actually want to use DNS for service discovery instead. 
   223
   224Most use cases for Apply-Time Mutation are actually using custom resources, as a
   225temporary alternative to building higher level abstractions, modifying
   226interfaces, or creating dependencies between otherwise independent interfaces.
   227
   228### CLI Printers
   229
   230Since the original intent of `cli-utils` was to contain common code for CLIs,
   231and end-to-end testing requires a reference implementation, a few printers are
   232included to translate from the primary event stream into STDOUT text:
   233
   2341. **Event Printer**: The event printer just prints text to STDOT whenever an
   235    event is recieved.
   2361. **JSON Printer**: The JSON printer converts events into a JSON string per
   237    line, intended for automated interpretation by machine.
   2381. **Table Printer**: The table  printer writes and updates in-place a table
   239    with one object per line, intended for human consumption.
   240
   241## Packages
   242
   243├── **cmd**: the kapply CLI command
   244├── **examples**: examples that serve as additional end-to-end tests using mdrip
   245├── **hack**: hacky scripts used by make
   246├── **pkg**
   247│   ├── **apis**: API resources that satisfy the kubernetes Object interface
   248│   ├── **apply**: bulk applier and destroyer
   249│   ├── **common**: placeholder for common tools that should probably have their own package
   250│   ├── **config**: inventory config bootstrapping
   251│   ├── **errors**: error printing
   252│   ├── **flowcontrol**: flow control enablement discovery
   253│   ├── **inventory**: inventory resource reference implementation
   254│   ├── **jsonpath**: utility for using jsonpath to read & write Unstructured object fields
   255│   ├── **kstatus**: object status event watcher with ability to reduce status to a single enum
   256│   ├── **manifestreader**: bolk resource object manifest reading and parsing
   257│   ├── **multierror**: error composition
   258│   ├── **object**: library for dealing with Unstructured objects
   259│   ├── **ordering**: sort functionality for objects
   260│   ├── **print**: CLI output
   261│   ├── **printers**: CLI output
   262│   └── **testutil**: utility for facilitating testing
   263├── **release**: goreleaser config
   264├── **scripts**: scripts used by make
   265└── **test**: end-to-end and stress tests
   266
   267## kapply
   268
   269To facilitate testing, this repository includes a reference CLI called `kapply`.
   270The `kapply` tool is not intended for direct consumer use, but may be useful
   271when trying to determine how to best utilize the `cli-utils` library packages.
   272
   273## Community, discussion, contribution, and support
   274
   275Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/).
   276
   277You can reach the maintainers of this project at:
   278
   279- [Slack channel](https://kubernetes.slack.com/messages/sig-cli)
   280- [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-cli)
   281
   282### Code of conduct
   283
   284Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).

View as plain text