Documentation ¶
Overview ¶
Package bootstrap implements utilities for boostrapping a kube cluster with resources on controller start.
This is typically used to bootstrap CRDs and CRs (of the types defined by the CRDs) so that a controller can be continuously deployed and still include breaking changes.
The bootstrap approach allows the controller to determine when and how to coordinate updates to the apis it manages. It should not typically be used by end-users of an operator, who may be using one or more other tools to manage the deployment of the operator and the resources it manages, and may not wish to grant the privileges required to bootstrap.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CRD ¶
CRD installs the CRDs in the filesystem into the kube cluster configured by the rest config.
Example ¶
package main import ( "embed" "k8s.io/client-go/rest" ) //go:embed example/*.yaml var crdFS embed.FS func main() { _ = CRD(&rest.Config{}, crdFS, "example") }
Output:
func ResourceFromFile ¶
func ResourceFromFile[O KubeResourceObject](ctx context.Context, fieldManager string, gvr schema.GroupVersionResource, dclient dynamic.Interface, configPath string, lastHash uint64) (uint64, error)
ResourceFromFile creates a KubeResourceObject with the given config file
Example ¶
package main import ( "bytes" "context" "fmt" "time" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/client-go/dynamic/fake" "k8s.io/client-go/testing" "k8s.io/klog/v2/klogr" ) func main() { ctx, cancel := context.WithCancel(logr.NewContext(context.Background(), klogr.New())) defer cancel() secretGVR := corev1.SchemeGroupVersion.WithResource("secrets") scheme := runtime.NewScheme() if err := corev1.AddToScheme(scheme); err != nil { panic(err) } scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.Secret{}) client := secretApplyPatchHandlingFakeClient(scheme) // create the object from the file // the example is a secret, but it could be any built-in or CRD-defined type _, err := ResourceFromFile[*corev1.Secret](ctx, "bootstrapped-secret", secretGVR, client, "./example.yaml", 0) if err != nil { panic(err) } for { secret, err := client.Resource(secretGVR).Namespace("test").Get(ctx, "example", metav1.GetOptions{}) if err == nil { fmt.Printf("%s/%s", secret.GetNamespace(), secret.GetName()) break } time.Sleep(1 * time.Millisecond) } } // secretApplyPatchHandlingFakeClient creates a fake client that handles // apply patch types (for corev1.Secret only). func secretApplyPatchHandlingFakeClient(scheme *runtime.Scheme) *fake.FakeDynamicClient { client := fake.NewSimpleDynamicClientWithCustomListKinds(scheme, map[schema.GroupVersionResource]string{}) client.PrependReactor("patch", "secrets", func(action testing.Action) (handled bool, ret runtime.Object, err error) { decoder := yaml.NewYAMLToJSONDecoder(bytes.NewReader(action.(testing.PatchAction).GetPatch())) var secret corev1.Secret if err := decoder.Decode(&secret); err != nil { return true, nil, err } // server-side apply creates the object if it doesn't exist if err := client.Tracker().Add(&secret); err != nil { return true, nil, err } return true, &secret, nil }) return client }
Output: test/example