github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/site/book/04-using-functions/02-imperative-function-execution.md (about) 1 The `fn eval` command enables you to execute a single function without declaring 2 it in the package. This is referred to as imperative function execution. 3 4 For example, to set the namespace of all resources in the wordpress package 5 hierarchy: 6 7 ```shell 8 $ kpt fn eval wordpress --image gcr.io/kpt-fn/set-namespace:v0.1 -- namespace=mywordpress 9 ``` 10 11 Alternatively, for convenience, you can use the short-hand form of the above command: 12 13 ```shell 14 $ kpt fn eval wordpress -i set-namespace:v0.1 -- namespace=mywordpress 15 ``` 16 17 ?> Refer to the [eval command reference][eval-doc] for usage. 18 19 This changes the resources in the `wordpress` package and the `mysql` 20 subpackage. 21 22 For comparison, this has the same effect as the following declaration: 23 24 ```yaml 25 # wordpress/Kptfile (Excerpt) 26 apiVersion: kpt.dev/v1 27 kind: Kptfile 28 metadata: 29 name: wordpress 30 pipeline: 31 mutators: 32 - image: gcr.io/kpt-fn/set-namespace:v0.1 33 configMap: 34 namespace: mywordpress 35 ``` 36 37 So when should you execute a function using `eval` instead of `render`? 38 39 When you have one of these use cases: 40 41 - Perform a one-time operation 42 - Execute a function from a CI/CD system on packages authored by other teams 43 - Develop shell scripts and chain functions with the Unix pipe (`|`) 44 - Execute the function with privilege (Not allowed by `render`) 45 46 We will cover these topics in detail. 47 48 ## Specifying `functionConfig` 49 50 There are two ways to specify the `functionConfig`. 51 52 ### `fn-config` flag 53 54 The general way to provide a `functionConfig` of arbitrary kind (core or custom 55 resources), is to declare the resource in a separate file and use the 56 `fn-config` flag. 57 58 ```shell 59 $ cat << EOF > /tmp/fn-config.yaml 60 apiVersion: v1 61 kind: ConfigMap 62 metadata: 63 name: ns 64 data: 65 namespace: mywordpress 66 EOF 67 ``` 68 69 ```shell 70 $ kpt fn eval wordpress -i set-namespace:v0.1 --fn-config /tmp/fn-config.yaml 71 ``` 72 73 ### CLI arguments 74 75 Many functions take a `functionConfig` of kind `ConfigMap` since they only need 76 simple key/value pairs as argument. For convenience, there is a way to provide 77 the key/value pairs as command line arguments. The following is equivalent to 78 what we showed previously: 79 80 ```shell 81 $ kpt fn eval wordpress -i set-namespace:v0.1 -- namespace=mywordpress 82 ``` 83 84 Note that the arguments must come after the separator `--`. 85 86 ## Specifying `selectors` 87 88 Selectors can be used to target specific resources for a function execution. 89 90 For example, you can selectively add an annotation to the resources if it has kind 91 `Deployment` AND name `wordpress`: 92 93 ```shell 94 $ kpt fn eval wordpress -i set-annotations:v0.1 --match-kind Deployment --match-name wordpress -- foo=bar 95 ``` 96 97 Here is the list of available selector matcher flags: 98 99 1. `match-api-version` 100 2. `match-kind` 101 3. `match-name` 102 4. `match-namespace` 103 5. `match-annotations` 104 6. `match-labels` 105 106 ## Specifying `exclusions` 107 108 Exclusions can be used to exclude specific resources for a function execution. 109 110 For example, you can set the namespace of all resources in the wordpress package, 111 except for the ones with the label `foo: bar`: 112 113 ```shell 114 $ kpt fn eval wordpress -i set-namespace:v0.1 --exclude-labels foo=bar -- namespace=my-namespace 115 ``` 116 117 If you use multiple exclusions, it will exclude resources that match all provided exclusions. For 118 example, you can set the namespace of all resources, except for those that have both kind "Deployment" 119 and name "nginx": 120 121 `$ kpt fn eval wordpress -i set-namespace:v0.1 --exclude-kind Deployment --exclude-name nginx -- namespace=my-namespace` 122 123 Here is the list of available exclusion flags: 124 125 1. `exclude-api-version` 126 2. `exclude-kind` 127 3. `exclude-name` 128 4. `exclude-namespace` 129 5. `exclude-annotations` 130 6. `exclude-labels` 131 132 ## Privileged Execution 133 134 Since the function is provided explicitly by the user, `eval` can be more 135 privileged and low-level than a declarative invocation using `render`. For 136 example, it can have access to the host system. 137 138 In general, we recommend against having functions that require privileged access 139 to the host since they can only be executed imperatively and pose a challenge in 140 terms of security, correctness, portability and speed. If at all possible, 141 functions should be executed hermetically with all required dependencies either 142 passed in as KRM resources (input items or functionConfig) or included in the 143 container image. However, there are some legitimate use cases where the only 144 available option requires either network access or mounting a volume from the 145 host. In those situations, you can use `eval` as described below. 146 147 ### Network Access 148 149 By default, functions cannot access the network. You can enable network access 150 using the `--network` flag. 151 152 For example, `kubeval` function can download a JSON schema file: 153 154 ```shell 155 $ kpt fn eval wordpress -i kubeval:v0.1 --network -- schema_location="https://kubernetesjsonschema.dev" 156 ``` 157 158 ### Mounting Directories 159 160 By default, functions cannot access the host file system. You can use the 161 `--mount` flag to mount host volumes. kpt accepts the same options to `--mount` 162 specified on the [Docker Volumes] page. 163 164 For example, `kubeval` function can consume a JSON schema file: 165 166 ```shell 167 $ kpt fn eval -i kubeval:v0.1 --mount type=bind,src="/path/to/schema-dir",dst=/schema-dir --as-current-user wordpress -- schema_location=file:///schema-dir 168 ``` 169 170 Note that the `--as-current-user` flag may be required to run the function as 171 your uid instead of the default `nobody` to access the host filesystem. 172 173 All volumes are mounted readonly by default. Specify `rw=true` to mount volumes 174 in read-write mode. 175 176 ``` 177 --mount type=bind,src="/path/to/schema-dir",dst=/schema-dir,rw=true 178 ``` 179 180 ## Chaining functions using the Unix pipe 181 182 As an alternative to declaring a pipeline in the `Kptfile`, you can chain 183 functions using the Unix pipe. 184 185 Here is an example: 186 187 ```shell 188 $ kpt fn source wordpress \ 189 | kpt fn eval - -i set-namespace:v0.1 -- namespace=mywordpress \ 190 | kpt fn eval - -i set-labels:v0.1 -- app=wordpress env=prod \ 191 | kpt fn sink my-wordpress 192 ``` 193 194 ?> Refer to the command reference for usage of [source][source-doc] and 195 [sink][sink-doc] commands. 196 197 The following describes the above pipeline: 198 199 1. The `source` command is used to read the resources in the package hierarchy 200 (`wordpress` and `mysql` packages). The output of the `source` command 201 follows the KRM Function Specification standard, which we are going to look 202 at in chapter 5. 203 2. The output of the `source` function is piped into the `set-namespace` 204 function. `eval` function is instructed to read inputs items from the `stdin` 205 using `-`. This is the convention used in all commands in kpt that can read 206 from `stdin`. The `set-namespace` function mutates the input items and emits 207 the output items. 208 3. The output of the `set-namespace` function is piped into `set-labels` 209 function which adds the given labels to all resources. 210 4. The `sink` command writes the output of `set-labels` to the filesystem. 211 212 This is a low-level and less abstracted approach to executing functions. You can 213 instead write the output of the pipeline to a different directory instead of 214 mutating the directory in-place. You can also pipe to other programs (e.g. 215 `sed`, `yq`) that are not functions. Be mindful that the cost of this low-level 216 flexibility is not having benefits provided by functions: scalability, 217 reusability, and encapsulation. 218 219 [eval-doc]: /reference/cli/fn/eval/ 220 [source-doc]: /reference/cli/fn/source/ 221 [sink-doc]: /reference/cli/fn/sink/ 222 [docker volumes]: https://docs.docker.com/storage/volumes/