Home

Awesome

CircleCI

apiextensions

This library provides generated Kubernetes clients for the Giant Swarm infrastructure.

Usage

Contributing

Setup

While the generation scripts can run without a GitHub token defined, you may encounter rate limit errors without one. The token will be loaded from the GITHUB_TOKEN environment variable if it exists. Giant Swarm engineers can generally use export GITHUB_TOKEN=$OPSCTL_GITHUB_TOKEN to configure this before running make.

Changing Existing Custom Resources

Naming Convention

Custom resource structs are placed in packages corresponding to the endpoints in Kubernetes API. For example, structs in package github.com/giantswarm/apiextensions/pkg/apis/infrastructure/v1alpha2 are created from objects under /apis/infrastructure.giantswarm.io/v1alpha2/ endpoint.

As this is common to have name collisions between field type names in different custom objects sharing the same group and version (e.g. Spec or Status) we prefix all type names referenced inside custom object with the name of the parent object.

Example:

package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type NewObj struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`
	Spec              NewObjSpec `json:"spec"`
}

type NewObjSpec struct {
	Field string `json:"field"`
}

Adding a New Custom Resource

This is example skeleton for adding new object.

package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NewObj godoc.
type NewObj struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`
	Spec              NewObjSpec `json:"spec"`
}

// NewObjSpec godoc.
type NewObjSpec struct {
	FieldName string `json:"fieldName"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NewObjList godoc.
type NewObjList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`
	Items           []NewObj `json:"items"`
}

Adding a New Group and/or Version

This is example skeleton for adding new group and/or version.

Example doc.go content.

// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register

// +groupName=GROUP.giantswarm.io
package VERSION

Example register.go content.

package VERSION

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
)

const (
	group   = "GROUP.giantswarm.io"
	version = "VERSION"
)

// knownTypes is the full list of objects to register with the scheme. It
// should contain pointers of zero values of all custom objects and custom
// object lists in the group version.
var knownTypes = []runtime.Object{
		//&Object{},
		//&ObjectList{},
}

// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{
	Group:   group,
	Version: version,
}

var (
	schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)

	// AddToScheme is used by the generated client.
	AddToScheme = schemeBuilder.AddToScheme
)

// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
	scheme.AddKnownTypes(SchemeGroupVersion, knownTypes...)
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
	return nil
}

Updating dependencies

Upstream CRDs

apiextensions generates Giant Swarm CRDs based on code in the pkg/apis directory and also aggregates CRDs from various sources. Any repository that publishes CRDs as a YAML-formatted manifest of CRDs attached as an asset to a GitHub release ("upstream" CRDs) or in a source tree ("remote" CRDs) can be used. The current set of CRDs including target version is defined in hack/assets.go in the upstreamReleaseAssets and remoteRepositories variables for upstream and remote CRDs respectively. Update the values and re-run make to update the aggregated CRDs.

Code Generation Tools

To change the version of a tool, edit the version manually in hack/tools/<tool>/go.mod and run go mod tidy in that directory so that go.sum is updated.

Versioning

This library uses standard semantic versioning. Versioning of CRDs is a separate issue covered in the Kubernetes deprecation policy. In short, if an API field needs to be removed, a new version must be created, and any versions served concurrently must be convertible in both directions without data loss.

Code generation

This library uses code generation to generate several components so that they do not need to be maintained manually and to reduce the chance of mistakes such as when, for example, defining an OpenAPIV3 schema for a CRD.

Makefile

The Makefile at the root of the repository ensures that required tools (defined below) are installed in hack/tools/bin and then runs each step of the code generation pipeline sequentially.

The main code generation steps are as follows:

These can all be run with make generate or simply make as generate is the default rule.

Extra commands are provided including:

Tools

Tools are third-party executables which perform a particular action as part of the code generation pipeline. They are defined in hack/tools in separate directories. Versions for the tools are defined in the go.mod file in their respective directories. A common go.mod isn't used so that their dependencies don't interfere.

controller-gen

Generates a custom resource definition (CRD) for each custom resource using special comments such as // +kubebuilder:validation:Optional.

goimports

Updates Go import lines by adding missing ones and removing unreferenced ones. This is required because CI checks for imports ordered in three sections (standard library, third-party, local) but certain code generators only generate source files with two sections.

Annotation Documentation

Docs generator has support for documenting annotations. This is achieved by creating code annotations in YAML on the definition of the variables like:

// support:
//   - crd: awsclusters.infrastructure.giantswarm.io
//     apiversion: v1alpha2
//     release: Since 14.0.0
// documentation:
//   Here is the documentation related to this annotation

Check AWS Annotations for examples.

The documentation is later on parsed as Markdown syntax. Annotations that don't have this YAML format are ignored and not published to the public docs. Annotations belong to specific API Version of the CRDs but they can be linked to multiple CRDs and multiple API Versions.