⚠️ Work in Progress
You are viewing development documentation built from the latest commit on main. APIs and features are subject to change.

Using Kure as a Library

Using Kure as a Library

Kure is primarily a Go library. This guide covers the basics of importing it, creating resources, and generating YAML output.

Installation

go get github.com/go-kure/kure

Creating Resources

A constructor gives you an object with an identity and nothing else: its apiVersion and kind from the scheme, its metadata.name, and its metadata.namespace for a namespaced kind. From there the upstream Go struct is the API, so you set fields on it directly.

import (
    appsv1 "k8s.io/api/apps/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/utils/ptr"
    "github.com/go-kure/kure/pkg/kubernetes"
)

dep := kubernetes.CreateDeployment("web", "default")   // identity only
dep.Spec.Replicas = ptr.To[int32](3)
dep.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{"app": "web"}}
dep.Spec.Template.Spec.ServiceAccountName = "web"

kubernetes.Create[appsv1.Deployment]("web", "default") is the generic form; the per-kind wrappers are generated from the scheme and carry the scope in their signature, so a cluster-scoped kind takes only a name (kubernetes.CreateNamespace("platform")).

Kure adds a helper only where a plain assignment is awkward: appending to a list, inserting into a map, setting a pointer field, or composing a small upstream struct. A helper never defaults, never validates, and never touches a field you did not name.

kubernetes.AddLabel(dep, "tier", "frontend")       // works on any kind
kubernetes.SetDeploymentReplicas(dep, 3)

The Kubernetes Builders page is the normative contract: what constructors emit, which helpers exist and why, and the migration notes for the constructor defaults that earlier releases injected and no longer do. If you upgraded and a field you relied on is now empty, that page lists it.

FluxCD Resources

import (
    "time"

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    kustv1 "github.com/fluxcd/kustomize-controller/api/v1"
    sourcev1 "github.com/fluxcd/source-controller/api/v1"
    "github.com/go-kure/kure/pkg/kubernetes/fluxcd"
)

// Create a GitRepository source
repo := fluxcd.CreateGitRepository("my-repo", "flux-system")
repo.Spec.URL = "https://github.com/org/repo"
fluxcd.SetGitRepositoryReference(repo, &sourcev1.GitRepositoryRef{Branch: "main"})
repo.Spec.Interval = metav1.Duration{Duration: 5 * time.Minute}

// Create a Kustomization that references the source
ks := fluxcd.CreateKustomization("my-app", "flux-system")
ks.Spec.SourceRef = kustv1.CrossNamespaceSourceReference{
    Kind: "GitRepository",
    Name: "my-repo",
}
ks.Spec.Path = "./clusters/production"
ks.Spec.Interval = metav1.Duration{Duration: 10 * time.Minute}
ks.Spec.Prune = true

See the FluxCD Builders reference for all available resource types.

Beyond FluxCD, the Kubernetes Builders package provides typed constructors for core resources (Deployment, Service, Ingress, CronJob, NetworkPolicy, HTTPRoute), PSA security context helpers, ResourceRequirements builders, and more. The Prometheus Builders sub-package covers ServiceMonitor, PodMonitor, and PrometheusRule CRDs.

Generating YAML

Use the io package to serialize resources:

import "github.com/go-kure/kure/pkg/io"

// Serialize a single object
data, err := io.Marshal(deployment)

// Write multiple objects to stdout as YAML
err := io.PrintObjectsAsYAML(objects, os.Stdout)

// Save to file
err := io.SaveFile("output.yaml", deployment)

Clean YAML encoding

When encoding resources exported from a cluster, server-managed metadata fields (managedFields, resourceVersion, uid, etc.) clutter the output. The default encoding strips all of these automatically:

// Default: strips all server-set fields and uses standard key order
data, err := io.EncodeObjectsToYAMLWithOptions(objects, io.EncodeOptions{
    KubernetesFieldOrder: true,
})

Use ServerFieldStripping to control the level of stripping:

// Preserve server fields (e.g. for debugging)
data, err := io.EncodeObjectsToYAMLWithOptions(objects, io.EncodeOptions{
    ServerFieldStripping: io.StripServerFieldsNone,
})

See the IO reference for all output formats and stripping options.

Working with the Domain Model

For more complex scenarios, use the Stack package to define cluster topologies:

import "github.com/go-kure/kure/pkg/stack"

cluster := stack.NewClusterBuilder("production").
    WithNode("apps").
        WithBundle("web").
            WithApplication("frontend", frontendConfig).
        End().
    End().
    Build()

Then use the Flux Engine and Layout Engine to generate a complete GitOps repository structure. See the Generating Flux Manifests guide for the full workflow.

Error Handling

All Kure packages use the errors package:

import "github.com/go-kure/kure/pkg/errors"

if err != nil {
    return errors.Wrap(err, "failed to generate manifests")
}

Next Steps