Skip to content

Commit

Permalink
refactor: kpt-kcl code
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy committed May 8, 2024
1 parent 285217f commit fe48b1b
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 198 deletions.
85 changes: 21 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,57 +83,27 @@ items:
selector:
app: MyApp
functionConfig:
apiVersion: v1
kind: ConfigMap
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: set-replicas
annotations:
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'fn-config.yaml'
internal.config.kubernetes.io/index: '0'
internal.config.kubernetes.io/path: 'fn-config.yaml'
internal.config.kubernetes.io/seqindent: 'compact'
data:
replicas: "5"
source: |
resources = option("resource_list")
setReplicas = lambda items, replicas {
[item | {if item.kind == "Deployment": spec.replicas = replicas} for item in items]
}
setReplicas(resources.items or [], resources.functionConfig.data.replicas)
name: conditionally-add-annotations
spec:
params:
replicas: "5"
source: |
params = option("params")
replicas = params.replicas
setReplicas = lambda items, replicas {
[item | {if item.kind == "Deployment": spec.replicas = replicas} for item in items]
}
items = setReplicas(option("items"), replicas)
```
Thus, the `spec.replicas` of `Deployment` in the `resource_list.yaml` is changed to `5` from `2`.

## FunctionConfig

There are 2 kinds of `functionConfig` supported by this function:

+ ConfigMap
+ A custom resource of kind `KCLRun`

To use a ConfigMap as the functionConfig, the KCL script source must be specified in the data.source field. Additional parameters can be specified in the data field.

Here's an example:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: set-replicas
data:
replicas: "5"
source: |
resources = option("resource_list")
setReplicas = lambda items, replicas {
[item | {if item.kind == "Deployment": spec.replicas = replicas} for item in items]
}
setReplicas(resources.items or [], resources.functionConfig.data.replicas)
```

In the example above, the script accesses the replicas parameters using `option("resource_list").functionConfig.data.replicas`.

To use a KCLRun as the functionConfig, the KCL source must be specified in the source field. Additional parameters can be specified in the params field. The params field supports any complex data structure as long as it can be represented in YAML.
The KCL source must be specified in the source field. Additional parameters can be specified in the params field. The params field supports any complex data structure as long as it can be represented in YAML.

```yaml
apiVersion: krm.kcl.dev/v1alpha1
Expand All @@ -148,20 +118,19 @@ spec:
configmanagement.gke.io/managed: disabled
source: |
resource = option("resource_list")
items = resource.items
params = resource.functionConfig.spec.params
toMatch = params.toMatch
toAdd = params.toAdd
[item | {
items = [item | {
# If all annotations are matched, patch more annotations
if all key, value in toMatch {
item.metadata.annotations[key] == value
}:
metadata.annotations: toAdd
} for item in items]
} for item in resource.items]
```

In the example above, the script accesses the `toMatch` parameters using `option("resource_list").functionConfig.spec.params.toMatch`.
In the example above, the script accesses the `toMatch` parameters using `option("params").toMatch`.

## Integrate the Function into kpt

Expand All @@ -175,26 +144,15 @@ export TAG=<Your KRM function tag>
docker build . -t ${FN_CONTAINER_REGISTRY}/${FUNCTION_NAME}:${TAG}
```

There are 2 ways to run the function declaratively.

+ Have your Kptfile with the inline ConfigMap as the functionConfig.
+ Have your Kptfile pointing to a functionConfig file that contains either a ConfigMap or a KCLRun.
Have your Kptfile pointing to a functionConfig file that contains either a KCLRun.

After that, you can render it in the folder that contains KRM with:

```bash
kpt fn render
```

There are 2 ways to run the function imperatively.

+ Run it using a ConfigMap that is generated from the command line arguments. The KCL script lives in `main.k` file.

```bash
kpt fn eval --image ${FN_CONTAINER_REGISTRY}/${FUNCTION_NAME}:${TAG} -- source="$(cat main.k)" param1=value1 param2=value2
```

+ Or use the function config file.
Or use the function config file.

```bash
kpt fn eval --image ${FN_CONTAINER_REGISTRY}/${FUNCTION_NAME}:${TAG} --fn-config fn-config.yaml
Expand All @@ -214,11 +172,10 @@ Then the Kubernetes resource file `resources.yaml` will be modified in place.

Here's what you can do in the KCL script:

+ Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md#krm-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`.
+ Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md#krm-functions-specification). You can read the input resources from `option("items")`.
+ Return a KPM list for output resources.
+ Return an error using `assert {condition}, {error_message}`.
+ Read the environment variables. e.g. `option("PATH")` (Not yet implemented).
+ Read the OpenAPI schema. e.g. `option("open_api")["definitions"]["io.k8s.api.apps.v1.Deployment"]` (Not yet implemented).
+ Read the environment variables. e.g. `option("PATH")`.

## Examples

Expand Down
25 changes: 14 additions & 11 deletions examples/resource_list/set_replicas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ items:
replicas: '2'
- kind: Service
functionConfig:
apiVersion: v1
kind: ConfigMap
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
name: set-replicas
data:
replicas: '5'
source: |
resources = option("resource_list")
setReplicas = lambda items, replicas {
[item | {if item.kind == "Deployment": spec.replicas = replicas} for item in items]
}
setReplicas(resources.items or [], resources.functionConfig.data.replicas)
name: conditionally-add-annotations
spec:
params:
replicas: "5"
source: |
params = option("params")
items = option("items")
replicas = params.replicas
setReplicas = lambda items, replicas {
[item | {if item.kind == "Deployment": spec.replicas = replicas} for item in items]
}
items = setReplicas(items, replicas)
78 changes: 40 additions & 38 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ go 1.21

require (
github.com/GoogleContainerTools/kpt-functions-sdk/go/fn v0.0.0-20230427202446-3255accc518d
kcl-lang.io/krm-kcl v0.8.0
kcl-lang.io/krm-kcl v0.8.7-0.20240508062136-5e7a4f68cdcf
sigs.k8s.io/kustomize/kyaml v0.16.0
)

require (
cloud.google.com/go v0.112.0 // indirect
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute v1.24.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/iam v1.1.6 // indirect
cloud.google.com/go/storage v1.36.0 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20220720212527-133180134b93 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
Expand All @@ -31,10 +33,11 @@ require (
github.com/chai2010/jsonv v1.1.3 // indirect
github.com/chai2010/protorpc v1.1.4 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/containerd v1.7.0 // indirect
github.com/containerd/containerd v1.7.11 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v23.0.1+incompatible // indirect
github.com/docker/cli v23.0.3+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v23.0.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
Expand All @@ -45,12 +48,12 @@ require (
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/getkin/kin-openapi v0.123.0 // indirect
github.com/getkin/kin-openapi v0.124.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-git/go-git/v5 v5.11.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.21.2 // indirect
github.com/go-openapi/errors v0.20.2 // indirect
Expand All @@ -68,7 +71,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
Expand All @@ -79,7 +82,7 @@ require (
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.3 // indirect
github.com/hashicorp/go-getter v1.7.4 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
Expand Down Expand Up @@ -109,7 +112,7 @@ require (
github.com/morikuni/aec v1.0.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc4 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/otiai10/copy v1.14.0 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
Expand All @@ -122,38 +125,38 @@ require (
github.com/qri-io/jsonpointer v0.1.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/thoas/go-funk v0.9.3 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/yuin/goldmark v1.7.0 // indirect
github.com/yuin/goldmark v1.7.1 // indirect
go.mongodb.org/mongo-driver v1.9.1 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
go.opentelemetry.io/otel v1.22.0 // indirect
go.opentelemetry.io/otel/metric v1.22.0 // indirect
go.opentelemetry.io/otel/trace v1.22.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.1 // indirect
golang.org/x/tools v0.20.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.155.0 // indirect
google.golang.org/api v0.162.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/grpc v1.62.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.63.2 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand All @@ -165,15 +168,14 @@ require (
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
kcl-lang.io/cli v0.8.0 // indirect
kcl-lang.io/kcl-go v0.8.0 // indirect
kcl-lang.io/kcl-openapi v0.5.5 // indirect
kcl-lang.io/kpm v0.8.0 // indirect
kcl-lang.io/lib v0.8.0 // indirect
kcl-lang.io/cli v0.8.7 // indirect
kcl-lang.io/kcl-go v0.8.6 // indirect
kcl-lang.io/kcl-openapi v0.6.1 // indirect
kcl-lang.io/kpm v0.8.6 // indirect
kcl-lang.io/lib v0.8.6 // indirect
oras.land/oras-go v1.2.3 // indirect
oras.land/oras-go/v2 v2.3.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/kyaml v0.16.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
Loading

0 comments on commit fe48b1b

Please sign in to comment.