Automatic generate kubernetes custom resources api go language code
Why does this article exist because when we use Kubesphere. the go client code need to use the client objects of K8s but dosen’t provider the s2ibinary object client code. https://github.com/kubesphere/s2ioperator/tree/master/pkg/client/clientset/versioned/typed/devops/v1alpha1
-
Prepare directory structure and resource defination files
- The
doc.go
include content:
1// +k8s:deepcopy-gen=package,register
2// +k8s:defaulter-gen=TypeMeta
3// +groupName=devops.kubesphere.io
4package v1alpha1
- The
register.go
main defination custom resources GroupName and GroupVersion
1package v1alpha1
2
3import (
4 "k8s.io/apimachinery/pkg/runtime/schema"
5 "sigs.k8s.io/controller-runtime/pkg/scheme"
6)
7
8type CodeFramework string
9
10const (
11 Ruby CodeFramework = "ruby"
12 Go CodeFramework = "go"
13 Java CodeFramework = "Java"
14 JavaTomcat CodeFramework = "JavaTomcat"
15 Nodejs CodeFramework = "Nodejs"
16 Python CodeFramework = "python"
17 GroupName string = "devops.kubesphere.io"
18 GroupVersion string = "v1alpha1"
19)
20
21var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: GroupVersion}
22
23var (
24 SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
25 AddToScheme = SchemeBuilder.AddToScheme
26)
27
28// Resource is required by pkg/client/listers/...
29func Resource(resource string) schema.GroupResource {
30 return SchemeGroupVersion.WithResource(resource).GroupResource()
31}
- The
types.go
mainly include CRD’s Object using in library
1package v1alpha1
2
3import (
4 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
5)
6
7// +genclient
8// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
9// S2iBinary is the Schema for the s2ibinary API
10type S2iBinary struct {
11 metav1.TypeMeta `json:",inline"`
12 metav1.ObjectMeta `json:"metadata,omitempty"`
13 Spec S2iBinarySpec `json:"spec,omitempty"`
14 Status S2iBinaryStatus `json:"status,omitempty"`
15}
16
17type S2iBinarySpec struct {
18 DownloadURL string `json:"downloadURL,omitempty"`
19 FileName string `json:"fileName, omitempty"`
20 Md5 string `json:"md5, omitempty"`
21 Size int `json:"size, omitempty"`
22 UploadTimeStamp string `json:"uploadTimeStamp, omitempty"`
23}
24
25type S2iBinaryStatus struct {
26 Phase string `json:"phase, omitempty"`
27}
28
29// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
30// S2iBinaryList contains a list of S2iBinary
31type S2iBinaryList struct {
32 metav1.TypeMeta `json:",inline"`
33 metav1.ListMeta `json:"metadata,omitempty"`
34 Items []S2iBinary `json:"items"`
35}
Note: The annotations is important and no blank lines.
-
Use Dockerfile as build client code environment
1 FROM golang:1.11.2
2 ENV GO111MODULE=off
3
4 RUN go get k8s.io/code-generator; exit 0
5 RUN go get k8s.io/apimachinery; exit 0
6 RUN go get github.com/spf13/pflag; exit 0
7 RUN go get k8s.io/gengo; exit 0
8 RUN go get k8s.io/klog; exit 0
9 RUN go get golang.org/x/tools; exit 0
10 RUN go get golang.org/x/mod; exit 0
11 RUN go get golang.org/x/xerrors; exit 0
12 ARG repo="${GOPATH}/src/github.com/xiao.chen/s2ibinary"
13 RUN mkdir -p $repo
14 WORKDIR $GOPATH/src/k8s.io/code-generator
15 VOLUME $repo
-
Use bash script generate clients library
1#!/bin/bash -e
2
3CURRENT_DIR=$(pwd)
4GEN_DIR=$(dirname $0)
5REPO_DIR="$CURRENT_DIR/$GEN_DIR/"
6
7PROJECT_MODULE="devops/s2ibinary"
8IMAGE_NAME="k8s-codegen:latest"
9
10CUSTOM_RESOURCE_NAME="devops"
11CUSTOM_RESOURCE_VERSION="v1alpha1"
12
13echo "Building codegen Docker image..."
14docker build -f "${GEN_DIR}/Dockerfile" \
15 -t "${IMAGE_NAME}" \
16 "${REPO_DIR}"
17
18cmd="./generate-groups.sh all \
19 "$PROJECT_MODULE/pkg/client" \
20 "$PROJECT_MODULE/pkg/apis" \
21 $CUSTOM_RESOURCE_NAME:$CUSTOM_RESOURCE_VERSION"
22
23echo "Generating client codes..."
24docker run --rm \
25 -v "${REPO_DIR}:/go/src/${PROJECT_MODULE}" \
26 "${IMAGE_NAME}" $cmd
This bash script should take pkg/apis/devops/v1alpha1 generate to client code through doc.go types.go and register.go with types.go file include’s annotations
- exectue
./gen-client.sh
late, will generate client and deepcopy.go in pkg directory
-
And it turns out there’s a simpler way to do it
1package main
2
3import (
4 logs "github.com/prometheus/common/log"
5 "golang.org/x/net/context"
6 v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7 "k8s.io/apimachinery/pkg/runtime/schema"
8 "k8s.io/client-go/dynamic"
9 "snc.com/cleanup/resources/config"
10)
11
12func main() {
13 k8sClient, err := config.NewK8s()
14 if err != nil {
15 logs.Fatal("Init kubernetes error.", err)
16 }
17
18 dyClient, err := dynamic.NewForConfig(k8sClient.Config)
19 dyResource := dyClient.Resource(schema.GroupVersionResource{Version: "v1alpha1", Group: "devops.kubesphere.io", Resource: "s2ibinaries"})
20 result, _ := dyResource.List(context.TODO(), v1.ListOptions{})
21 for _, item := range result.Items {
22 logs.Info("Name:", item.GetName(), "\t Namespace: ", item.GetNamespace())
23 }
24
25}
Use Dynamic resource interface so easy!