io

package
v0.2.0-beta.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

README

IO - YAML Serialization and Resource Printing

Go Reference

The io package provides utilities for parsing, serializing, and printing Kubernetes resources. It supports multiple output formats including YAML, JSON, and kubectl-compatible table views.

Overview

This package handles the I/O boundary of Kure: reading Kubernetes manifests from files, serializing resources to YAML/JSON, and printing resources in human-readable formats. It integrates with Kure's registered scheme for type-aware parsing.

Parsing

Parse YAML Files
import "github.com/go-kure/kure/pkg/io"

// Parse a multi-document YAML file into typed Kubernetes objects
objects, err := io.ParseFile("manifests/deployment.yaml")

// Parse YAML bytes directly
objects, err := io.ParseYAML(yamlData)
Unstructured Fallback

By default, only GVKs registered in the kure scheme are accepted. To parse arbitrary Kubernetes YAML (CRDs, custom operators, etc.) use ParseYAMLWithOptions or ParseFileWithOptions with AllowUnstructured:

opts := io.ParseOptions{AllowUnstructured: true}
objects, err := io.ParseYAMLWithOptions(yamlData, opts)
// Known types are returned as typed objects (e.g. *corev1.Pod).
// Unknown types are returned as *unstructured.Unstructured.
Load and Save
// Load a single object from file
obj, err := io.LoadFile("service.yaml")

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

Serialization

Marshal and Unmarshal
// Serialize to YAML bytes
data, err := io.Marshal(deployment)

// Deserialize from YAML bytes
var obj appsv1.Deployment
err := io.Unmarshal(data, &obj)
Encode Multiple Objects
// Encode as multi-document YAML
yamlData, err := io.EncodeObjectsToYAML(objects)

// Encode as JSON array
jsonData, err := io.EncodeObjectsToJSON(objects)
Deterministic Field Ordering
// Encode with Kubernetes-conventional field ordering
opts := io.EncodeOptions{KubernetesFieldOrder: true}
yamlData, err := io.EncodeObjectsToYAMLWithOptions(objects, opts)
// Output: apiVersion, kind, metadata, spec, ... status (last)
Server-Set Field Stripping

By default, encoding strips server-managed metadata fields that should not appear in client-generated manifests: managedFields, resourceVersion, uid, generation, selfLink, the kubectl.kubernetes.io/last-applied-configuration annotation, null creationTimestamp, and empty status.

// Default behavior — full stripping (zero value of ServerFieldStripping)
yamlData, err := io.EncodeObjectsToYAML(objects)

// Explicit full stripping with field ordering
opts := io.EncodeOptions{
    KubernetesFieldOrder: true,
    ServerFieldStripping: io.StripServerFieldsFull,
}
yamlData, err := io.EncodeObjectsToYAMLWithOptions(objects, opts)

// Basic stripping (only null creationTimestamp and empty status)
opts := io.EncodeOptions{
    ServerFieldStripping: io.StripServerFieldsBasic,
}
yamlData, err := io.EncodeObjectsToYAMLWithOptions(objects, opts)

// No stripping — preserve all fields as-is
opts := io.EncodeOptions{
    ServerFieldStripping: io.StripServerFieldsNone,
}
yamlData, err := io.EncodeObjectsToYAMLWithOptions(objects, opts)

Printing

Output Formats

The package supports kubectl-compatible output formats:

Format Constant Description
YAML OutputFormatYAML Full YAML output
JSON OutputFormatJSON Full JSON output
Table OutputFormatTable Columnar table view
Wide OutputFormatWide Extended table with extra columns
Name OutputFormatName Resource names only
Usage
// Print as YAML to stdout
err := io.PrintObjectsAsYAML(objects, os.Stdout)

// Print as table
err := io.PrintObjectsAsTable(objects, false, false, os.Stdout)

// Use ResourcePrinter for configurable output
printer := io.NewResourcePrinter(io.PrintOptions{
    OutputFormat: io.OutputFormatTable,
    ShowLabels:   true,
})
err := printer.Print(objects, os.Stdout)

// Format-agnostic printing (selects printer by format string)
err := io.PrintObjects(objects, "yaml", os.Stdout)

// Validate a format string before use
err := io.ValidateOutputFormat("table")
  • errors - Error types for parse failures
  • kubernetes - Scheme registration for type-aware parsing

Documentation

Overview

Package io provides utilities for reading, writing and parsing YAML representations of Kubernetes resources. It acts as a thin wrapper around sigs.k8s.io/yaml and the Kubernetes runtime scheme from client-go.

YAML helpers

Basic marshalling and unmarshalling is performed through the Marshal and Unmarshal functions which operate on the standard io.Reader and io.Writer interfaces. When persisting data to disk the SaveFile and LoadFile helpers wrap file creation and reading so callers need only provide the destination path and the object to encode or decode.

For in-memory operations the Buffer type implements both io.Reader and io.Writer and exposes Marshal and Unmarshal methods. A Buffer can be reused for multiple round trips without allocating new byte slices:

buf := new(io.Buffer)
if err := buf.Marshal(obj); err != nil {
    log.Fatalf("marshal object: %v", err)
}
if err := buf.Unmarshal(&out); err != nil {
    log.Fatalf("unmarshal object: %v", err)
}

Parsing runtime objects

Kubernetes manifests frequently contain multiple YAML documents separated by `---`. ParseFile reads such a manifest and decodes each document into a runtime.Object using the client-go scheme. Several additional API schemes from projects like FluxCD, cert-manager and MetalLB are registered so their custom resources can be parsed without further setup.

Any decoding errors are aggregated in a ParseErrors value which implements the error interface. Successful objects are returned alongside the error so callers may continue processing valid resources while reporting individual failures.

objs, err := io.ParseFile("./manifests.yaml")
if err != nil {
    var pe *io.ParseErrors
    if errors.As(err, &pe) {
        for _, e := range pe.Errors {
            log.Printf("parse error: %v", e)
        }
    }
}

Unstructured fallback

By default the parser rejects objects whose GroupVersionKind is not registered in the kure scheme. ParseYAMLWithOptions and ParseFileWithOptions accept a ParseOptions value. When AllowUnstructured is true, unknown GVKs are decoded as *unstructured.Unstructured instead of returning an error, making it possible to process arbitrary Kubernetes YAML including CRDs that are not compiled into the binary:

opts := io.ParseOptions{AllowUnstructured: true}
objs, err := io.ParseYAMLWithOptions(data, opts)
for _, obj := range objs {
    if u, ok := obj.(*unstructured.Unstructured); ok {
        fmt.Println("unstructured:", u.GetKind(), u.GetName())
    }
}

Resource printing

The io package includes comprehensive resource printing capabilities compatible with kubectl output formats. The ResourcePrinter provides unified formatting for YAML, JSON, table, wide, and name output modes:

printer := io.NewResourcePrinter(io.PrintOptions{
	OutputFormat: io.OutputFormatTable,
	NoHeaders:    false,
	ShowLabels:   true,
})
err := printer.Print(resources, os.Stdout)

Table output includes resource-specific column formatting for different Kubernetes kinds (Pod, Deployment, Service, ConfigMap) with appropriate status indicators, age formatting, and wide-mode additional details.

For simple table printing, use the SimpleTablePrinter which provides kubectl-style table output without external dependencies:

printer := io.NewSimpleTablePrinter(wide, noHeaders)
printer.Print(resources, os.Stdout)

Convenience functions are available for common operations:

io.PrintObjectsAsYAML(resources, os.Stdout)
io.PrintObjectsAsJSON(resources, os.Stdout)
io.PrintObjectsAsTable(resources, wide, noHeaders, os.Stdout)

Deterministic field ordering

EncodeObjectsToYAMLWithOptions accepts EncodeOptions to control YAML output. When KubernetesFieldOrder is true, top-level fields are emitted in the conventional order used by kubectl, Helm, and Kustomize: apiVersion, kind, metadata, spec, data, stringData, then remaining fields alphabetically, with status last.

Server-set field stripping

Resources exported from a cluster via `kubectl get -o yaml` include server-managed metadata fields (managedFields, resourceVersion, uid, generation, selfLink, and the kubectl.kubernetes.io/last-applied-configuration annotation) that should not appear in client-generated manifests.

The ServerFieldStripping option on EncodeOptions controls which of these fields are removed during encoding:

Because the zero value of ServerFieldStripping is StripServerFieldsFull, all existing callers of EncodeObjectsToYAML benefit from enhanced stripping without code changes.

The package forms the foundation for the other packages within this repository but can be imported directly by any program that requires lightweight YAML handling, runtime object parsing, and kubectl-compatible resource printing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EncodeObjectsTo

func EncodeObjectsTo(objects []*client.Object, yamlOutput bool) ([]byte, error)

func EncodeObjectsToJSON

func EncodeObjectsToJSON(objects []*client.Object) ([]byte, error)

func EncodeObjectsToYAML

func EncodeObjectsToYAML(objects []*client.Object) ([]byte, error)

EncodeObjectsToYAML encodes Kubernetes objects to clean YAML, stripping all known server-managed metadata fields by default (see StripServerFieldsFull).

func EncodeObjectsToYAMLWithOptions

func EncodeObjectsToYAMLWithOptions(objects []*client.Object, opts EncodeOptions) ([]byte, error)

EncodeObjectsToYAMLWithOptions encodes Kubernetes objects to clean YAML with configurable output options. When opts.KubernetesFieldOrder is true, top-level fields are emitted in the conventional order used by kubectl, Helm, and Kustomize (apiVersion, kind, metadata, spec, ..., status last).

func FormatAge

func FormatAge(t *metav1.Time) string

FormatAge returns a human-readable age string for a resource

func GetDetailedStatus

func GetDetailedStatus(obj client.Object) string

GetDetailedStatus provides additional status information for wide output

func GetResourceAge

func GetResourceAge(obj client.Object) string

GetResourceAge returns the age of a resource based on its creation timestamp

func GetResourceStatus

func GetResourceStatus(obj client.Object) string

GetResourceStatus attempts to extract a status string from common status fields

func LoadFile

func LoadFile(path string, obj any) (retErr error)

LoadFile reads YAML from the given path and unmarshals it into obj.

func Marshal

func Marshal(w io.Writer, obj any) error

Marshal writes the YAML representation of obj to w.

func ParseFile

func ParseFile(path string) ([]client.Object, error)

ParseFile reads the YAML file at path and returns the runtime objects defined within. Each object is decoded using the k8s scheme. An error is returned if the file cannot be read or if decoding any document fails.

func ParseFileWithOptions

func ParseFileWithOptions(path string, opts ParseOptions) ([]client.Object, error)

ParseFileWithOptions reads the YAML file at path and returns the runtime objects defined within. Behavior is controlled by opts; see ParseOptions.

func ParseYAML

func ParseYAML(data []byte) ([]client.Object, error)

ParseYAML parses YAML bytes and returns the runtime objects defined within. Each object is decoded using the k8s scheme. An error is returned if decoding any document fails.

func ParseYAMLWithOptions

func ParseYAMLWithOptions(data []byte, opts ParseOptions) ([]client.Object, error)

ParseYAMLWithOptions parses YAML bytes and returns the runtime objects defined within. Behavior is controlled by opts; see ParseOptions.

func PrintObjects

func PrintObjects(objects []*client.Object, format OutputFormat, options PrintOptions, w io.Writer) error

PrintObjects prints objects using the specified output format and options

func PrintObjectsAsJSON

func PrintObjectsAsJSON(objects []*client.Object, w io.Writer) error

PrintObjectsAsJSON is a convenience function for JSON output

func PrintObjectsAsTable

func PrintObjectsAsTable(objects []*client.Object, wide, noHeaders bool, w io.Writer) error

PrintObjectsAsTable prints objects in table format using the simple table printer

func PrintObjectsAsYAML

func PrintObjectsAsYAML(objects []*client.Object, w io.Writer) error

PrintObjectsAsYAML is a convenience function for YAML output

func SaveFile

func SaveFile(path string, obj any) (retErr error)

SaveFile marshals obj as YAML and writes it to the given file path.

func Unmarshal

func Unmarshal(r io.Reader, obj any) error

Unmarshal reads YAML from r into obj.

Types

type Buffer

type Buffer struct {
	bytes.Buffer
}

Buffer is a simple in-memory buffer that implements io.Reader and io.Writer and can marshal and unmarshal YAML representations of objects.

func (*Buffer) Marshal

func (b *Buffer) Marshal(obj any) error

Marshal writes the YAML representation of obj to the buffer.

func (*Buffer) Unmarshal

func (b *Buffer) Unmarshal(obj any) error

Unmarshal parses the buffer contents as YAML into obj.

type EncodeOptions

type EncodeOptions struct {
	// KubernetesFieldOrder emits top-level resource keys in the
	// conventional order used by kubectl, Helm, and Kustomize:
	// apiVersion, kind, metadata, spec, data, stringData, type,
	// then remaining keys alphabetically, with status last.
	// Nested maps remain alphabetically sorted.
	KubernetesFieldOrder bool

	// ServerFieldStripping controls removal of server-managed metadata
	// fields during encoding. The zero value (StripServerFieldsFull)
	// strips all known server-set fields by default.
	ServerFieldStripping ServerFieldStripping
}

EncodeOptions controls how Kubernetes objects are serialized to YAML.

type OutputFormat

type OutputFormat string

OutputFormat represents the supported output formats for printing resources

const (
	OutputFormatYAML  OutputFormat = "yaml"
	OutputFormatJSON  OutputFormat = "json"
	OutputFormatTable OutputFormat = "table"
	OutputFormatWide  OutputFormat = "wide"
	OutputFormatName  OutputFormat = "name"
)

func ValidateOutputFormat

func ValidateOutputFormat(format string) (OutputFormat, error)

ValidateOutputFormat checks if the given format string is valid

type ParseOptions

type ParseOptions struct {
	// AllowUnstructured enables fallback decoding for GVKs not registered
	// in the kure scheme. When true, unknown objects are returned as
	// *unstructured.Unstructured instead of producing an error.
	AllowUnstructured bool
}

ParseOptions controls how Kubernetes YAML documents are decoded.

type PrintOptions

type PrintOptions struct {
	// OutputFormat specifies the desired output format
	OutputFormat OutputFormat
	// NoHeaders suppresses table headers when true
	NoHeaders bool
	// ShowLabels displays resource labels in table output
	ShowLabels bool
	// ColumnLabels is a list of label keys to display as columns
	ColumnLabels []string
	// SortBy specifies the column to sort by (for table output)
	SortBy string
}

PrintOptions contains configuration for resource printing

type ResourcePrinter

type ResourcePrinter struct {
	// contains filtered or unexported fields
}

ResourcePrinter provides a unified interface for printing Kubernetes resources in various formats, compatible with kubectl output styles

func NewResourcePrinter

func NewResourcePrinter(options PrintOptions) *ResourcePrinter

NewResourcePrinter creates a new ResourcePrinter with the given options

func NewTablePrinter

func NewTablePrinter(options PrintOptions) *ResourcePrinter

NewTablePrinter creates a table printer configured for Kure resources

func (*ResourcePrinter) Print

func (rp *ResourcePrinter) Print(resources []*client.Object, w io.Writer) error

Print outputs the given resources to the writer using the configured format

func (*ResourcePrinter) PrintSingle

func (rp *ResourcePrinter) PrintSingle(resource client.Object, w io.Writer) error

PrintSingle is a convenience function for printing a single resource

func (*ResourcePrinter) PrintToString

func (rp *ResourcePrinter) PrintToString(resources []*client.Object) (string, error)

PrintToString returns the printed output as a string instead of writing to a writer

type ServerFieldStripping

type ServerFieldStripping int

ServerFieldStripping controls which server-managed metadata fields are removed during YAML encoding.

const (
	// StripServerFieldsFull removes all known server-set metadata fields:
	// managedFields, resourceVersion, uid, generation, selfLink,
	// the kubectl.kubernetes.io/last-applied-configuration annotation,
	// null creationTimestamp, and empty status.
	StripServerFieldsFull ServerFieldStripping = iota

	// StripServerFieldsBasic removes only null creationTimestamp and
	// empty status (the pre-v0.1 behavior).
	StripServerFieldsBasic

	// StripServerFieldsNone disables all server-field stripping.
	StripServerFieldsNone
)

type SimpleTablePrinter

type SimpleTablePrinter struct {
	// contains filtered or unexported fields
}

SimpleTablePrinter provides a basic table printer implementation without k8s.io/cli-runtime dependency

func NewSimpleTablePrinter

func NewSimpleTablePrinter(wide, noHeaders bool) *SimpleTablePrinter

NewSimpleTablePrinter creates a simple table printer with default columns

func NewSimpleTablePrinterWithColumns

func NewSimpleTablePrinterWithColumns(columns []TableColumn, wide, noHeaders bool) *SimpleTablePrinter

NewSimpleTablePrinterWithColumns creates a simple table printer with custom columns

func (*SimpleTablePrinter) Print

func (stp *SimpleTablePrinter) Print(resources []*client.Object, w io.Writer) error

Print outputs resources in table format using the simple table printer

type TableColumn

type TableColumn struct {
	Header   string
	Width    int
	Accessor func(client.Object) string
	Priority int  // Lower values are shown first, higher values in wide mode
	WideOnly bool // Only shown in wide output
}

TableColumn represents a column in table output

func DefaultColumns

func DefaultColumns() []TableColumn

DefaultColumns returns the default column set for Kubernetes resources

func KindSpecificColumns

func KindSpecificColumns(gvk metav1.GroupVersionKind) []TableColumn

KindSpecificColumns returns columns tailored for specific Kubernetes resource kinds

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL