github.com/SamarSidharth/kpt@v0.0.0-20231122062228-c7d747ae3ace/site/book/05-developing-functions/02-developing-in-Go.md (about) 1 You can develop a KRM function in Go using [the kpt function SDK]. 2 3 - **General-purpose language:** Compared to Domain Specific Languages (DSL), Go 4 is a general-purpose programming language that provides: 5 - Proper abstractions and language features 6 - An extensive ecosystem of tooling (e.g. IDE support) 7 - A comprehensive catalog of well-supported libraries 8 - Robust community support and detailed documentation 9 10 ## Prerequisites 11 12 - [Install kpt](https://kpt.dev/installation/) 13 14 - [Install Docker](https://docs.docker.com/get-docker/) 15 16 - [Golang](https://go.dev/dl/) (at least version 1.19) 17 18 ## Quickstart 19 20 In this quickstart, we will write a function that adds an annotation 21 `config.kubernetes.io/managed-by=kpt` to all `Deployment` resources. 22 23 ### Initialize your project 24 25 We start from a "get-started" package which contains a `main.go` file with some scaffolding code. 26 27 ```shell 28 # Set your KRM function name. 29 export FUNCTION_NAME=set-annotation 30 31 # Get the "get-started" package. 32 kpt pkg get https://github.com/GoogleContainerTools/kpt-functions-sdk.git/go/get-started@master ${FUNCTION_NAME} 33 34 cd ${FUNCTION_NAME} 35 36 # Initialize the Go module 37 go mod init 38 go mod tidy 39 ``` 40 41 ### Write the KRM function logic 42 43 Take a look at the `main.go` (as below) and complete the `Run` function. 44 45 ```go 46 // Copyright 2022 The kpt Authors 47 // 48 // Licensed under the Apache License, Version 2.0 (the "License"); 49 // you may not use this file except in compliance with the License. 50 // You may obtain a copy of the License at 51 // 52 // http://www.apache.org/licenses/LICENSE-2.0 53 // 54 // Unless required by applicable law or agreed to in writing, software 55 // distributed under the License is distributed on an "AS IS" BASIS, 56 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 57 // See the License for the specific language governing permissions and 58 // limitations under the License. 59 60 package main 61 62 import ( 63 "context" 64 "os" 65 66 "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" 67 ) 68 69 var _ fn.Runner = &YourFunction{} 70 71 // TODO: Change to your functionConfig "Kind" name. 72 type YourFunction struct { 73 FnConfigBool bool 74 FnConfigInt int 75 FnConfigFoo string 76 } 77 78 // Run is the main function logic. 79 // `items` is parsed from the STDIN "ResourceList.Items". 80 // `functionConfig` is from the STDIN "ResourceList.FunctionConfig". The value has been assigned to the r attributes 81 // `results` is the "ResourceList.Results" that you can write result info to. 82 func (r *YourFunction) Run(ctx *fn.Context, functionConfig *fn.KubeObject, items fn.KubeObjects, results *fn.Results) bool { 83 // TODO: Write your code. 84 return true 85 } 86 87 func main() { 88 runner := fn.WithContext(context.Background(), &YourFunction{}) 89 if err := fn.AsMain(runner); err != nil { 90 os.Exit(1) 91 } 92 } 93 ``` 94 95 The [`fn`] library provides a series of KRM level operations for [`ResourceList`]. 96 Basically, the KRM resource `ResourceList.FunctionConfig` and KRM resources `ResourceList.Items` are both converted to 97 `KubeObject` objects. You can use `KubeObject` similar as [`unstructured.Unstrucutred`]. 98 99 The set-annotation function (see below) iterates the `ResourceList.Items`, finds out the `Deployment` resources and 100 adds the annotation. After the iteration, it adds some user message to the `ResourceList.Results` 101 102 ```go 103 func (r *YourFunction) Run(ctx *fn.Context, functionConfig *fn.KubeObject, items fn.KubeObjects, results *fn.Results) bool { 104 for _, kubeObject := range items { 105 if kubeObject.IsGVK("apps", "v1", "Deployment") { 106 kubeObject.SetAnnotation("config.kubernetes.io/managed-by", "kpt") 107 } 108 } 109 // This result message will be displayed in the function evaluation time. 110 *results = append(*results, fn.GeneralResult("Add config.kubernetes.io/managed-by=kpt to all `Deployment` resources", fn.Info)) 111 return true 112 } 113 ``` 114 115 Learn more about the `KubeObject` from the [go doc](https://pkg.go.dev/github.com/GoogleContainerTools/kpt-functions-sdk/go/fn). 116 117 118 ### Test the KRM function 119 120 The "get-started" package contains a `./testdata` directory. You can use this to test out your functions. 121 122 ```shell 123 # Edit the `testdata/resources.yaml` with your KRM resources. 124 # resources.yaml already has a `Deployment` and `Service` as test data. 125 vim data/resources.yaml 126 127 # Convert the KRM resources and FunctionConfig resource to `ResourceList`, and 128 # then pipe the ResourceList as StdIn to your function 129 kpt fn source testdata | go run main.go 130 131 # Verify the KRM function behavior in the StdOutput `ResourceList` 132 ``` 133 134 ### Build the KRM function as a Docker image 135 136 Build the image 137 138 The "get-started" package provides the `Dockerfile` that you can download using: 139 ```shell 140 wget https://raw.githubusercontent.com/GoogleContainerTools/kpt-functions-sdk/master/go/kfn/commands/embed/Dockerfile 141 ``` 142 143 ```shell 144 export FN_CONTAINER_REGISTRY=<Your GCR or docker hub> 145 export TAG=<Your KRM function tag> 146 docker build . -t ${FN_CONTAINER_REGISTRY}/${FUNCTION_NAME}:${TAG} 147 ``` 148 149 To verify the image using the same `./testdata` resources 150 ```shell 151 kpt fn eval ./testdata/test1/resources.yaml --image ${FN_CONTAINER_REGISTRY}/${FUNCTION_NAME}:${TAG} 152 ``` 153 154 ## Next Steps 155 156 - See other [go doc examples] to use KubeObject. 157 - To contribute to KRM catalog functions, please follow the [contributor guide](https://github.com/GoogleContainerTools/kpt-functions-catalog/blob/master/CONTRIBUTING.md) 158 159 [the kpt function SDK]: https://pkg.go.dev/github.com/GoogleContainerTools/kpt-functions-sdk/go/fn 160 [go doc examples]: https://pkg.go.dev/github.com/GoogleContainerTools/kpt-functions-sdk/go/fn/examples 161 [`fn`]: https://pkg.go.dev/github.com/GoogleContainerTools/kpt-functions-sdk/go/fn 162 [`ResourceList`]: https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md 163 [`unstructured.Unstructured`]: https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured