diff --git a/documentation/content/en/book/04-using-functions/_index.md b/documentation/content/en/book/04-using-functions/_index.md index 75ca80115f..e82b032129 100644 --- a/documentation/content/en/book/04-using-functions/_index.md +++ b/documentation/content/en/book/04-using-functions/_index.md @@ -2,9 +2,9 @@ title: "Chapter 4: Using functions" linkTitle: "Chapter 4: Using functions" description: | - [Chapter 2](../02-concepts/#functions) provided a high-level conceptual explanation of functions. We also saw examples of how to use - `fn eval` and `fn render` to execute functions. In this chapter, we will take a closer look at how to execute - functions using these two approaches. + [Chapter 2](../02-concepts/#functions) provided a high-level conceptual explanation of the functions. We also saw examples of how to use `fn eval` and `fn render` to + execute the functions. In this chapter, we will take a closer look at how to execute the functions using these two + two approaches. toc: true menu: @@ -15,23 +15,16 @@ menu: ## Declarative function execution -In many real-world scenarios, it's not sufficient to only have packages of -static, fully-rendered resource configuration. You want the package to declare -both static data as well as operations that should be performed on current -resources and any resource that may be added in the future as you edit the -package. Example use cases: +In many real-world scenarios, it is not enough only to have packages of static, fully-rendered resource configurations. You need the package to declare static data, as well as operations that should be performed on the current resources and any resource that may be added in the future, as you edit the package. Example use cases are as follows: -- Set the namespace on all namespace-scoped resources -- Always perform schema validation on resources in the package -- Always enforce a constraint policy on resources in the package -- Generate resources using a human-authored custom resource +- Set the namespace on all the namespace-scoped resources. +- Always perform schema validation on the resources in the package. +- Always enforce a constraint policy on the resources in the package. +- Generate the resources using a human-authored custom resource. -In kpt, this is achieved by declaring a pipeline of functions in the `Kptfile` -and executing all the pipelines in the package hierarchy in a depth-first order -using the `fn render` command. +In kpt, this is achieved by declaring a pipeline of functions in the `Kptfile` and executing all the pipelines in the package hierarchy in a depth-first order, using the `fn render` command. -In our wordpress example, the top-level `wordpress` package declares this -pipeline: +In our wordpress example, the top-level `wordpress` package declares the following pipeline: ```yaml # wordpress/Kptfile (Excerpt) @@ -48,21 +41,19 @@ pipeline: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ``` -This declares two functions: +This pipeline declares the following two functions: -- `set-label` is a mutator function which adds a set of labels to resources. -- `kubeconform` is a validator function which validates the resources against their - OpenAPI schema. +- `set-label`: this is a mutator function which adds a set of labels to the resources. +- `kubeconform`: this is a validator function which validates the resources against their OpenAPI schemas. -Refer to the [Functions Catalog](https://catalog.kpt.dev/function-catalog) -for details on how to use a particular function. +See the [Functions Catalog](https://catalog.kpt.dev/function-catalog) for details about how to use a particular function. -There are two differences between mutators and validators: +There are two differences between the mutator functions and the validator functions: -1. Validators are not allowed to modify resources. -2. Validators are always executed after mutators. +1. The validators are not allowed to modify the resources. +2. The validators are always executed after the mutators. -The `mysql` subpackage declares only a mutator function: +The `mysql` subpackage declares a mutator function only, as follows: ```yaml # wordpress/mysql/Kptfile @@ -77,7 +68,7 @@ pipeline: tier: mysql ``` -Now, let's render the package hierarchy: +Let us now render the package hierarchy: ```shell kpt fn render wordpress @@ -93,43 +84,31 @@ Package "wordpress": Successfully executed 3 function(s) in 2 package(s). ``` -Refer to the [render command reference](../../reference/cli/fn/render/) for usage. +See the [render command reference](../../reference/cli/fn/render/) for usage. When you invoke the `render` command, kpt performs the following steps: -1. Sequentially executes the list of mutators declared in the `mysql` package. - The input to the first function is the set of resources read from the - configuration files in the `mysql` package. The output of the first function - is the input of the second function and so on. -2. Similarly, executes all the validators declared in the `mysql` package. The - input to the first validator is the output of the last mutator. The output of - the last validator is the output of the pipeline in the `mysql` package. -3. Sequentially executes the list of mutators declared in the `wordpress` - package. The input to the first function is the union of: +1. It executes sequentially the list of mutators declared in the `mysql` package. The input to the first function is the set of resources read from the configuration files in the `mysql` package. The output of the first function is the input of the second function, and so on. +2. Similarly, it executes all the validators declared in the `mysql` package. The input to the first validator is the output of the last mutator. The output of the last validator is the output of the pipeline in the `mysql` package. +3. It executes sequentially the list of mutators declared in the `wordpress` package. The input to the first function is the union of the following: - - Resources read from configuration files in the `wordpress` package AND - - Output of the pipeline from the `mysql` package (Step 2). + - The resources read from the configuration files in the `wordpress` package. + - The output of the pipeline from the `mysql` package (see step 2). -4. Similarly, execute all the validators declared in the `wordpress` package. - The output of the last validator is the output of the pipeline in the - `wordpress` package. -5. Write the output of step 4 by modifying the local filesystem in-place. This - can change both `wordpress` and `mysql` packages. +4. Similarly, it executes all the validators declared in the `wordpress` package. The output of the last validator is the output of the pipeline in the `wordpress` package. +5. It writes the output of step 4 by modifying the local filesystem in-place. This can change both the `wordpress` and the `mysql` packages. -The end result is that: +The result is the following: -1. Resources in the `mysql` package are labelled with `tier: mysql`. -2. Resources in `mysql` and `wordpress` packages are labelled with - `app: wordpress`. -3. Resources in `mysql` and `wordpress` packages are validated against their - OpenAPI spec. +1. The resources in the `mysql` package are labeled with `tier: mysql`. +2. The resources in the `mysql` and `wordpress` packages are labeled with `app: wordpress`. +3. The resources in the `mysql` and `wordpress` packages are validated against their Open API specifications. ### Render status tracking -After each `kpt fn render` execution, kpt records the render status in the root package's `Kptfile`. This provides -visibility into whether the most recent render succeeded or failed, which is helpful for debugging and -tracking the state of your package. +After each `kpt fn render` execution, kpt records the render status in the root package's `Kptfile`. This provides visibility +into whether the most recent render succeeded or failed. This is helpful for debugging and tracking the state of the package. The render status is recorded as a `Rendered` condition in the `status.conditions` section of the root `Kptfile`: @@ -167,19 +146,15 @@ status: pipeline.run: must run with `--allow-exec` option to allow running function binaries ``` -The render status is recorded only when performing in-place rendering (the default mode). It is not recorded when using -out-of-place modes such as `--output stdout`, `--output unwrap`, or `--output `. +The render status is only recorded when performing in-place rendering (this is the default mode). It is not recorded when using out-of-place modes, such as `--output stdout`, `--output unwrap`, or `--output `. -You can inspect the render status by examining the root `Kptfile` to understand the result of the most recent render operation. +You can inspect the render status by examining the root `Kptfile`, in order to understand the result of the most recent render operation. ### Debugging render failures -When a render pipeline fails, you can configure the package to save partially rendered resources to disk. -This is particularly useful for debugging function pipeline issues by inspecting what changes were made before -the failure occurred. +When a render pipeline fails, you can configure the package to save partially rendered resources to the disk. This is particularly useful for debugging function pipeline issues by inspecting the changes that were made before the failure occurred. -By default, partially rendered resources are not saved when render fails. To enable this behaviour, -add the `kpt.dev/save-on-render-failure` annotation to the Kptfile's metadata section: +By default, partially rendered resources are not saved when a render fails. To enable this behavior, add the `kpt.dev/save-on-render-failure` annotation to the Kptfile's metadata section, as follows: ```yaml apiVersion: kpt.dev/v1 @@ -197,30 +172,30 @@ pipeline: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ``` -With this annotation set to `"true"`, if a function in the pipeline fails, kpt will save all resources that were -successfully processed up to the point of failure. This allows you to examine the intermediate state and understand -what transformations were applied before the error. - -This annotation follows the same pattern as `kpt.dev/bfs-rendering` and must be declared in the root package's Kptfile -before running `kpt fn render`. +With the `kpt.dev/save-on-render-failure` annotation set to _true_, if a function in the pipeline fails, kpt saves all the resources that had been successfully processed up to the point of failure. This allows you to examine the intermediate state and understand what transformations had been applied before the error occurred. +This annotation follows the same pattern as that of the `kpt.dev/bfs-rendering` annotation. It must be declared in the root package's Kptfile before running `kpt fn render`. ### Specifying `function` +For specifying the `function` field, the following fields are required: + +- `image` +- `tag` +- `exec` + +Details of these fields are set out below. + #### `image` -The `image` field specifies the container image for the function. You can specify -an image from any container registry. If the registry is omitted, the default -container registry for functions catalog (`ghcr.io/kptdev/krm-functions-catalog`) is prepended automatically. -For example, `set-labels:latest` is automatically expanded to `ghcr.io/kptdev/krm-functions-catalog/set-labels:latest`. +The `image` field specifies the container image for the function. You can specify an image from any container registry. If the registry is omitted, the default container registry for the functions catalog (`ghcr.io/kptdev/krm-functions-catalog`) is prepended automatically. For example, `set-labels:latest` is automatically expanded to `ghcr.io/kptdev/krm-functions-catalog/set-labels:latest`. #### `tag` -The `tag` field specifies the exact tag of the function container image *or* a semantic version constraint for the -desired tag. The version constraints are validated by `github.com/Masterminds/semver/v3`, so they must fulfil that spec. +The `tag` field specifies the exact tag of the function container image or a semantic version constraint for the +desired tag. The version constraints are validated by `github.com/Masterminds/semver/v3`. Therefore, they must fulfill that specification. -If a `tag` is provided, it will override whatever tag is already specified within the `image` field, -*even if `tag` is not a valid semantic version or constraint*. +If a `tag` field is provided, it overrides whichever tag is already specified within the `image` field, even if the `tag` field is not a valid semantic version or constraint. Examples: ```yaml @@ -256,11 +231,9 @@ result: ghcr.io/kptdev/krm-functions-catalog/set-labels:de3c135 #### `exec` -The `exec` field specifies the executable command for the function. You can specify -an executable with arguments. +The `exec` field specifies the executable command for the function. You can specify an executable with arguments. -Example below uses `sed` executable to replace all occurrences of `foo` with `bar` -in the package resources. +The following example uses the `sed` executable to replace all the occurrences of `foo` with `bar` in the package resources. ```yaml # PKG_DIR/Kptfile (Excerpt) @@ -273,35 +246,33 @@ pipeline: - exec: "sed -e 's/foo/bar/'" ``` -Note that you must render the package by allowing executables by specifying `--allow-exec` -command line flag as shown below. +Note: +You must render the package by allowing the executables. To do this, specify the `--allow-exec` command line flag, as shown below: ```shell kpt fn render [PKG_DIR] --allow-exec ``` -Using `exec` is not recommended for two reasons: +Using the `exec` field is not recommended, for the following two reasons: -- It makes the package non-portable since rendering the package requires the - executables to be present on the system. -- Executing binaries is not very secure since they can perform privileged operations - on the system. +- It makes the package non-portable, since rendering the package requires the executables to be present in the system. +- Executing binaries is not secure, since they can perform privileged operations in the system. ### Specifying `functionConfig` -In [Chapter 2](../02-concepts/#functions), we saw this conceptual representation of a function invocation: +In [Chapter 2](../02-concepts/#functions), we saw the following conceptual representation of a function invocation: ![img](/images/func.svg) -`functionConfig` is an optional meta resource containing the arguments to a -particular invocation of the function. There are two different ways to declare -the `functionConfig`. +The `functionConfig` field is an optional meta resource containing the arguments to a particular invocation of the function. There are two different ways to declare the +`functionConfig`: + +- `configPath` +- `configMap` #### `configPath` -The general way to provide a `functionConfig` of arbitrary kind (core or custom -resources), is to declare the resource in a separate file in the same directory -as the `Kptfile` and refer to it using the `configPath` field. +The general way to provide a `functionConfig` of the arbitrary kind (core or custom resources) is to declare the resource in a separate file, in the same directory as the `Kptfile`, and refer to it using the `configPath` field. For example: @@ -329,11 +300,9 @@ data: #### `configMap` -Many functions take a `functionConfig` of kind `ConfigMap` since they only need -simple key/value pairs as argument. For convenience, there is a way to inline -the key/value pairs in the `Kptfile`. +Many functions take a `functionConfig` of kind `ConfigMap`, since they only need simple key/value pairs as an argument. For convenience, there is a way to inline the key/value pairs in the `Kptfile`. -The following is equivalent to what we showed before: +The following is equivalent to that which we showed in the previous example: ```yaml # wordpress/mysql/Kptfile @@ -350,8 +319,7 @@ pipeline: ### Specifying function `name` -Functions can optionally be named using the `pipeline.mutators.name` -or `pipeline.validators.name` field to identify a function. +The functions can optionally be named using the `pipeline.mutators.name` field or the `pipeline.validators.name` field to identify a function. For example: @@ -369,25 +337,17 @@ pipeline: tier: mysql ``` -Unique function names for all functions in the Kptfile function -pipeline is recommended. If `name` is specified, `kpt pkg update` -will merge each function pipeline list as an associative list, using -`name` as the merge key. An unspecified `name` or duplicated names may -result in unexpected merges. +It is recommended to use unique function names for all the functions in the Kptfile function pipeline. If the `name` is specified, then the `kpt pkg update` will merge each function pipeline list as an associative list, using `name` as the merge key. An unspecified `name`, or duplicated names, may result in unexpected merges. ### Specifying `selectors` -In some cases, you want to invoke the function only on a subset of resources based on a -selection criteria. This can be accomplished using selectors. At a high level, selectors -work as follows: +In some cases, it is necessary to invoke the function only on a subset of resources based on certain selection criteria. This can be accomplished using selectors. At a high level, the selectors work as follows: ![img](/images/func-target.svg) -Resources that are selected are passed as input to the function. -Resources that are not selected are passed through unchanged. +The resources that are selected are passed as input to the function. The resources that are not selected are passed through unchanged. -For example, let's add a function to the pipeline that adds an annotation to -resources with name `wordpress-mysql` only: +As an example, let us add a function to the pipeline that adds an annotation to the resources with the name `wordpress-mysql` only, as follows: ```yaml # wordpress/Kptfile (Excerpt) @@ -409,9 +369,7 @@ pipeline: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ``` -When you invoke the render command, the `mysql` package is rendered first, and `set-annotations` -function is invoked only on the resources with name `wordpress-mysql`. Then, `set-label` -function is invoked on all the resources in the package hierarchy of `wordpress` package. +When you invoke the render command, the `mysql` package is rendered first, and the `set-annotations` function is invoked only on the resources with the name `wordpress-mysql`. The `set-label` function is then invoked on all the resources in the package hierarchy of the `wordpress` package. ```shell $ kpt fn render wordpress @@ -430,10 +388,10 @@ Package "wordpress": Successfully executed 4 function(s) in 2 package(s). ``` -As another example, let's add another function to the pipeline that adds a prefix to the name of a resource if: -- it has kind `Deployment` AND name `wordpress` - **OR** -- it has kind `Service` AND name `wordpress` +As another example, let us add another function to the pipeline that adds a prefix to the name of a resource if either of the following is true: + +- It has the kind `Deployment` and the name `wordpress`. +- It has the kind `Service` and the name `wordpress`. ```yaml # wordpress/Kptfile (Excerpt) @@ -463,7 +421,7 @@ pipeline: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ``` -Now, let's render the package: +Render the package as follows: ```shell kpt fn render wordpress @@ -484,12 +442,11 @@ Package "wordpress": Successfully executed 5 function(s) in 2 package(s). ``` -Note that the `ensure-name-substring` function is applied only to the +Note: +The `ensure-name-substring` function is applied only to the resources matching the selection criteria. -If you have resources with particular labels or annotations that you want to use to -select your resources, you can do so. For example, here is a function that will only -be applied to resources matching the label `foo: bar`: +If you have resources with particular labels or annotations that you want to use to select your resources, then you can use them. Here, for example, is a function that is only applied to the resources matching the label `foo: bar`: ```yaml apiVersion: kpt.dev/v1 @@ -508,20 +465,20 @@ pipeline: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ``` -The following are the matchers you can specify in a selector: +The following are the matchers that you can specify in a selector: -1. `apiVersion`: `apiVersion` field value of resources to be selected. -2. `kind`: `kind` field value of resources to be selected. -3. `name`: `metadata.name` field value of resources to be selected. -4. `namespace`: `metadata.namespace` field of resources to be selected. -5. `annotations`: resources with matching annotations will be selected. -6. `labels`: resources with matching labels will be selected. +1. `apiVersion`: this is the `apiVersion` field value of the resources to be selected. +2. `kind`: this is the `kind` field value of the resources to be selected. +3. `name`: this is the `metadata.name` field value of the resources to be selected. +4. `namespace`: this is the `metadata.namespace` field of the resources to be selected. +5. `annotations`: the resources with matching annotations will be selected. +6. `labels`: the resources with matching labels will be selected. #### Specifying `exclude` -Similar to `selectors`, you can also specify resources that should be excluded from functions. +Similarly to the `selectors`, you can also specify the resources that should be excluded from the functions. -For example, you can exclude a resource if it has both kind "Deployment" and name "nginx": +For example, you can exclude a resource if it has both the kind `Deployment` and the name `nginx`, as follows: ```yaml apiVersion: kpt.dev/v1 @@ -540,7 +497,7 @@ pipeline: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ``` -This is distinct from the following, which excludes a resource if it has either kind "Deployment" or name "nginx": +This is distinct from the following example, which excludes a resource if it has either the kind `Deployment` or the name `nginx`, as follows: ```yaml apiVersion: kpt.dev/v1 @@ -561,20 +518,18 @@ pipeline: The following are the matchers you can specify in an exclusion: -1. `apiVersion`: `apiVersion` field value of resources to be excluded. -2. `kind`: `kind` field value of resources to be excluded. -3. `name`: `metadata.name` field value of resources to be excluded. -4. `namespace`: `metadata.namespace` field of resources to be excluded. -5. `annotations`: resources with matching annotations will be excluded. -6. `labels`: resources with matching labels will be excluded. +1. `apiVersion`: this is the `apiVersion` field value of the resources to be excluded. +2. `kind`: this is the `kind` field value of the resources to be excluded. +3. `name`: this is the `metadata.name` field value of the resources to be excluded. +4. `namespace`: this is the `metadata.namespace` field of the resources to be excluded. +5. `annotations`: the resources with matching annotations will be excluded. +6. `labels`: the resources with matching labels will be excluded. ## Imperative function execution -The `fn eval` command enables you to execute a single function without declaring -it in the package. This is referred to as imperative function execution. +The `fn eval` command enables you to execute a single function without declaring it in the package. This is referred to as an imperative function execution. -For example, to set the namespace of all resources in the wordpress package -hierarchy: +For example, to set the namespace of all resources in the `wordpress` package hierarchy, use the following command: ```shell kpt fn eval wordpress --image ghcr.io/kptdev/krm-functions-catalog/set-namespace:latest -- namespace=mywordpress @@ -586,10 +541,9 @@ Alternatively, for convenience, you can use the short-hand form of the above com kpt fn eval wordpress -i set-namespace:latest -- namespace=mywordpress ``` -Refer to the [eval command reference](../../reference/cli/fn/eval/) for usage. +See the [eval command reference](../../reference/cli/fn/eval/) for usage. -This changes the resources in the `wordpress` package and the `mysql` -subpackage. +This changes the resources in the `wordpress` package and the `mysql` subpackage. For comparison, this has the same effect as the following declaration: @@ -606,26 +560,27 @@ pipeline: namespace: mywordpress ``` -So when should you execute a function using `eval` instead of `render`? +When should you execute a function using `eval`, instead of `render`? -When you have one of these use cases: +When you have one of the following use cases: -- Perform a one-time operation -- Execute a function from a CI/CD system on packages authored by other teams -- Develop shell scripts and chain functions with the Unix pipe (`|`) -- Execute the function with privilege (Not allowed by `render`) +- Performing a one-time operation. +- Executing a function from a CI/CD system on packages authored by other teams. +- Developing shell scripts and chain functions with the Unix pipe (`|`). +- Executing the function with privileges (not allowed by the `render` command). -We will cover these topics in detail. +These topics will be covered in detail later on. ### Specifying `functionConfig` -There are two ways to specify the `functionConfig`. +There are two ways to specify the `functionConfig`: + +- `fn-config` flag +- CLI arguments #### `fn-config` flag -The general way to provide a `functionConfig` of arbitrary kind (core or custom -resources), is to declare the resource in a separate file and use the -`fn-config` flag. +The general way to provide a `functionConfig` of the arbitrary kind (core or custom resources) is to declare the resource in a separate file and use the `fn-config` flag. ```shell cat << EOF > /tmp/fn-config.yaml @@ -644,29 +599,26 @@ kpt fn eval wordpress -i set-namespace:latest --fn-config /tmp/fn-config.yaml #### CLI arguments -Many functions take a `functionConfig` of kind `ConfigMap` since they only need -simple key/value pairs as argument. For convenience, there is a way to provide -the key/value pairs as command line arguments. The following is equivalent to -what we showed previously: +Many functions take a `functionConfig` of the kind `ConfigMap`, since they only need simple key/value pairs as an argument. For convenience, there is a way to provide the key/value pairs as command line arguments. The following is equivalent to that which we showed in the previous example: ```shell kpt fn eval wordpress -i set-namespace:latest -- namespace=mywordpress ``` -Note that the arguments must come after the separator `--`. +Note: +The arguments must come after the separator `--`. ### Specifying `selectors` Selectors can be used to target specific resources for a function execution. -For example, you can selectively add an annotation to the resources if it has kind -`Deployment` AND name `wordpress`: +For example, you can selectively add an annotation to the resources if it has the kind `Deployment` and the name `wordpress`: ```shell kpt fn eval wordpress -i set-annotations:latest --match-kind Deployment --match-name wordpress -- foo=bar ``` -Here is the list of available selector matcher flags: +The available selector matcher flags are as follows: 1. `match-api-version` 2. `match-kind` @@ -679,22 +631,19 @@ Here is the list of available selector matcher flags: Exclusions can be used to exclude specific resources for a function execution. -For example, you can set the namespace of all resources in the wordpress package, -except for the ones with the label `foo: bar`: +For example, you can set the namespaces of all the resources in the `wordpress` package, except for the ones that have the label `foo: bar`: ```shell kpt fn eval wordpress -i set-namespace:latest --exclude-labels foo=bar -- namespace=my-namespace ``` -If you use multiple exclusions, it will exclude resources that match all provided exclusions. For -example, you can set the namespace of all resources, except for those that have both kind "Deployment" -and name "nginx": +If you use multiple exclusions, it will exclude the resources that match all the provided exclusions. For example, you can set the namespaces of all the resources, except for those that have both the kind `Deployment` and the name `nginx`, as follows: ```shell kpt fn eval wordpress -i set-namespace:latest --exclude-kind Deployment --exclude-name nginx -- namespace=my-namespace ``` -Here is the list of available exclusion flags: +The list of available exclusion flags is as follows: 1. `exclude-api-version` 2. `exclude-kind` @@ -705,47 +654,36 @@ Here is the list of available exclusion flags: ### Privileged Execution -Since the function is provided explicitly by the user, `eval` can be more -privileged and low-level than a declarative invocation using `render`. For -example, it can have access to the host system. +Since the function is provided explicitly by the user, the `eval` command can be more privileged and low-level than a declarative invocation using the `render` command. For example, +it can have access to the host system. -In general, we recommend against having functions that require privileged access -to the host since they can only be executed imperatively and pose a challenge in -terms of security, correctness, portability and speed. If at all possible, -functions should be executed hermetically with all required dependencies either -passed in as KRM resources (input items or functionConfig) or included in the -container image. However, there are some legitimate use cases where the only -available option requires either network access or mounting a volume from the -host. In those situations, you can use `eval` as described below. +In general, we recommend against having functions that require privileged access to the host. Such functions can only be executed imperatively and may pose a challenge in terms of security, correctness, portability, and speed. If possible, the functions should be executed hermetically with all the required dependencies, either passed in as KRM resources (input items or `functionConfig`), or included in the container image. However, there are some legitimate use cases in which the only available +option requires either network access or mounting a volume from the host. In such situations, you can use the `eval` command, as described below. -#### Network Access +#### Network access -By default, functions cannot access the network. You can enable network access -using the `--network` flag. +By default, the functions cannot access the network. You can enable network access by using the `--network` flag. -For example, `kubeconform` function can download a JSON schema file: +The `kubeconform` function can, for example, download a JSON schema file, as follows: ```shell kpt fn eval wordpress -i kubeconform:latest --network -- schema_location="https://kubernetesjsonschema.dev" ``` -#### Mounting Directories +#### Mounting directories -By default, functions cannot access the host file system. You can use the -`--mount` flag to mount host volumes. kpt accepts the same options to `--mount` -specified on the [Docker Volumes](https://docs.docker.com/storage/volumes/) page. +By default, the functions cannot access the host file system. You can use the `--mount` flag to mount the host volumes. kpt accepts the same options to `--mount`, as specified on the [Docker Volumes](https://docs.docker.com/storage/volumes/) page. -For example, `kubeconform` function can consume a JSON schema file: +The `kubeconform` function can, for example, consume a JSON schema file, as follows: ```shell kpt fn eval -i kubeconform:latest --mount type=bind,src="/path/to/schema-dir",dst=/schema-dir --as-current-user wordpress -- schema_location=file:///schema-dir ``` -Note that the `--as-current-user` flag may be required to run the function as -your uid instead of the default `nobody` to access the host filesystem. +Note: +The `--as-current-user` flag may be required to run the function as your uid, instead of the default `nobody`, to access the host filesystem. -All volumes are mounted readonly by default. Specify `rw=true` to mount volumes -in read-write mode. +All the volumes are mounted as _readonly_ by default. To mount volumes in _read-write_ mode, specify `rw=true`, as follows: ```shell --mount type=bind,src="/path/to/schema-dir",dst=/schema-dir,rw=true @@ -753,8 +691,7 @@ in read-write mode. ### Chaining functions using the Unix pipe -As an alternative to declaring a pipeline in the `Kptfile`, you can chain -functions using the Unix pipe. +As an alternative to declaring a pipeline in the `Kptfile`, you can chain functions using the Unix pipe. Here is an example: @@ -765,43 +702,27 @@ kpt fn source wordpress \ | kpt fn sink my-wordpress ``` -Refer to the command reference for usage of [source](../..//reference/cli/fn/source/) and -[sink](../../reference/cli/fn/sink/) commands. +See the command reference for usage of the [source](../..//reference/cli/fn/source/) command and the +[sink](../../reference/cli/fn/sink/) command. -The following describes the above pipeline: +The above pipeline can be described as follows: -1. The `source` command is used to read the resources in the package hierarchy - (`wordpress` and `mysql` packages). The output of the `source` command - follows the KRM Function Specification standard, which we are going to look - at in chapter 5. -2. The output of the `source` function is piped into the `set-namespace` - function. `eval` function is instructed to read inputs items from the `stdin` - using `-`. This is the convention used in all commands in kpt that can read - from `stdin`. The `set-namespace` function mutates the input items and emits - the output items. -3. The output of the `set-namespace` function is piped into `set-labels` - function which adds the given labels to all resources. -4. The `sink` command writes the output of `set-labels` to the filesystem. +1. The `source` command is used to read the resources in the package hierarchy (the `wordpress` and `mysql` packages). The output of the `source` command follows the KRM Function Specification standard, which we will look at in chapter 5. +2. The output of the `source` function is piped into the `set-namespace` function. The `eval` command is instructed to read the inputs items from the `stdin`, using `-`. This is the convention used in all commands in kpt that can read from `stdin`. The `set-namespace` function mutates the input items and emits the output items. +3. The output of the `set-namespace` function is piped into `set-labels` function. This adds the given labels to all the resources. +4. The `sink` command writes the output of the `set-labels` to the filesystem. -This is a low-level and less abstracted approach to executing functions. You can -instead write the output of the pipeline to a different directory instead of -mutating the directory in-place. You can also pipe to other programs (e.g. -`sed`, `yq`) that are not functions. Be mindful that the cost of this low-level -flexibility is not having benefits provided by functions: scalability, -reusability, and encapsulation. +This is a low-level and less abstracted approach to executing functions. You can instead write the output of the pipeline to a different directory, instead of mutating the directory in-place. You can also pipe to other programs (such as `sed` and `yq`) that are not functions. Be mindful that the cost of this low-level flexibility is not having the benefits provided by the functions: scalability, reusability, and encapsulation. ## Function results -In kpt, the counterpart to Unix philsophophy of "everything is a file" is "everything is a -Kubernetes resource". This also extends to the results of executing functions using `eval` or -`render`. In addition to providing a human-readable terminal output, these commands provide -structured results which can be consumed by other tools. This enables you to build robust UI layers -on top of kpt. For example: +In kpt, the counterpart to the Unix philsophophy of "everything is a file" is "everything is a Kubernetes resource". This also extends to the results of executing the functions using the `eval` or `render` command. In addition to providing a human-readable terminal output, these commands provide +structured results which can be consumed by other tools. This enables you to build robust UI layers on top of kpt. You can, for example, do the following: -- Create a custom dashboard that shows the results returned by functions -- Annotate a GitHub Pull Request with results returned by a validator function at the granularity of individuals fields +- Create a custom dashboard that shows the results returned by the functions. +- Annotate a GitHub pull request with the results returned by a validator function at the granularity of the individuals fields. -In both `render` and `eval`, structured results can be enabled using the `--results-dir` flag. +In both the `render` and the `eval` commands, structured results can be enabled using the `--results-dir` flag. For example: @@ -820,7 +741,7 @@ Successfully executed 3 function(s) in 2 package(s). For complete results, see /tmp/results.yaml ``` -The results are provided as resource of kind `FunctionResultList`: +The results are provided as a resource of kind `FunctionResultList`: ```yaml # /tmp/results.yaml @@ -838,9 +759,8 @@ items: exitCode: 0 ``` -Let's see a more interesting result where the `kubeconform` function catches a validation issue. -For example, change the value of `port` field in `service.yaml` from `80` to `"80"` and -rerun: +We can see a more interesting result, in which the `kubeconform` function catches a validation issue. +For example, change the value of the `port` field in the `service.yaml` from `80` to `"80"` and rerun the command: ```shell kpt fn render wordpress --results-dir /tmp @@ -859,7 +779,7 @@ Package "wordpress": For complete results, see /tmp/results.yaml ``` -The results resource will now contain failure details: +The results resource will now contain the failure details: ```yaml # /tmp/results.yaml