How to user code-generator
In this article, we will focus on how to use the K8s code-generator from scratch.
Let's assume we want to create CRD in group "foo.com", and there is a type called "HelloType" with a "message" field in the spec:
# Definition
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: hellotypes.foo.com
spec:
group: foo.com
version: v1
scope: Namespaced
names:
kind: HelloType
shortNames: ht
plural: hellotypes
singular: hellotype
# HelloType
---
apiVersion: foo.com/v1
kind: HelloType
metadata:
name: superman-hello
spec:
message: hello world
There are two steps to generate the CRD resource code:
Write the type definition code with code generator tags
Run run the generator to create the client codes which include: clientset, informers, listers for your customer resource
Write type definition code
cd $GOPATH/src
mkdir -p github.com/superman/demo
cd $GOPATH/src/github.com/superman/demo
Create the skeleton files as below under
$GOPATH/src/github.com/superman/demo
pkg/
├── apis
└── foo
└── v1
├── doc.go
├── register.go
└── types.go
doc.go
// +k8s:deepcopy-gen=package
// +k8s:defaulter-gen=TypeMeta
// +groupName=foo.com
package v1
types.go
package v1
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// HelloType is a top-level type
type HelloType struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
// +optional
Status HelloTypeStatus `json:"status,omitempty"`
// This is where you can define
// your own custom spec
Spec HelloSpec `json:"spec,omitempty"`
}
// custom spec
type HelloSpec struct {
Message string `json:"message,omitempty"`
}
// custom status
type HelloTypeStatus struct {
Name string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// no client needed for list as it's been created in above
type HelloTypeList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `son:"metadata,omitempty"`
Items []HelloType `json:"items"`
}
register.go
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// Define your schema name and the version
var SchemeGroupVersion = schema.GroupVersion{
Group: "foo.com",
Version: "v1",
}
var (
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes)
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(
SchemeGroupVersion,
&HelloType{},
&HelloTypeList{},
)
scheme.AddKnownTypes(
SchemeGroupVersion,
&metav1.Status{},
)
metav1.AddToGroupVersion(
scheme,
SchemeGroupVersion,
)
return nil
}
Run code-generator to create client codes
go get -u k8s.io/code-generator/...
go get k8s.io/apimachinery
cd $GOPATH/src/k8s.io/code-generator
./generate-groups.sh all "github.com/superman/demo/pkg/client" "github.com/superman/demo/pkg/apis" "foo:v1"
After above steps, you will see the following file structure:
kubo@jumper:~/GoProjects/src/github.com/superman/demo/pkg$ tree client/
client/
├── clientset
│ └── versioned
│ ├── clientset.go
│ ├── doc.go
│ ├── fake
│ │ ├── clientset_generated.go
│ │ ├── doc.go
│ │ └── register.go
│ ├── scheme
│ │ ├── doc.go
│ │ └── register.go
│ └── typed
│ └── foo
│ └── v1
│ ├── doc.go
│ ├── fake
│ │ ├── doc.go
│ │ ├── fake_foo_client.go
│ │ └── fake_hellotype.go
│ ├── foo_client.go
│ ├── generated_expansion.go
│ └── hellotype.go
├── informers
│ └── externalversions
│ ├── factory.go
│ ├── foo
│ │ ├── interface.go
│ │ └── v1
│ │ ├── hellotype.go
│ │ └── interface.go
│ ├── generic.go
│ └── internalinterfaces
│ └── factory_interfaces.go
└── listers
└── foo
└── v1
├── expansion_generated.go
└── hellotype.go
16 directories, 22 files
References:
Last updated
Was this helpful?