Categorygithub.com/ericchiang/k8s
modulepackage
1.2.0
Repository: https://github.com/ericchiang/k8s.git
Documentation: pkg.go.dev

# README

A simple Go client for Kubernetes

GoDoc Build Status

A slimmed down Go client generated using Kubernetes' protocol buffer support. This package behaves similarly to official Kubernetes' Go client, but only imports two external dependencies.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ericchiang/k8s"
    corev1 "github.com/ericchiang/k8s/apis/core/v1"
)

func main() {
    client, err := k8s.NewInClusterClient()
    if err != nil {
        log.Fatal(err)
    }

    var nodes corev1.NodeList
    if err := client.List(context.Background(), "", &nodes); err != nil {
        log.Fatal(err)
    }
    for _, node := range nodes.Items {
        fmt.Printf("name=%q schedulable=%t\n", *node.Metadata.Name, !*node.Spec.Unschedulable)
    }
}

Requirements

Usage

Create, update, delete

The type of the object passed to Create, Update, and Delete determine the resource being acted on.

configMap := &corev1.ConfigMap{
    Metadata: &metav1.ObjectMeta{
        Name:      k8s.String("my-configmap"),
        Namespace: k8s.String("my-namespace"),
    },
    Data: map[string]string{"hello": "world"},
}

if err := client.Create(ctx, configMap); err != nil {
    // handle error
}

configMap.Data["hello"] = "kubernetes"

if err := client.Update(ctx, configMap); err != nil {
    // handle error
}

if err := client.Delete(ctx, configMap); err != nil {
    // handle error
}

Get, list, watch

Getting a resource requires providing a namespace (for namespaced objects) and a name.

// Get the "cluster-info" configmap from the "kube-public" namespace
var configMap corev1.ConfigMap
err := client.Get(ctx, "kube-public", "cluster-info", &configMap)

When performing a list operation, the namespace to list or watch is also required.

// Pods from the "custom-namespace"
var pods corev1.PodList
err := client.List(ctx, "custom-namespace", &pods)

A special value AllNamespaces indicates that the list or watch should be performed on all cluster resources.

// Pods in all namespaces
var pods corev1.PodList
err := client.List(ctx, k8s.AllNamespaces, &pods)

Watches require a example type to determine what resource they're watching. Watch returns an type which can be used to receive a stream of events. These events include resources of the same kind and the kind of the event (added, modified, deleted).

// Watch configmaps in the "kube-system" namespace
var configMap corev1.ConfigMap
watcher, err := client.Watch(ctx, "kube-system", &configMap)
if err != nil {
    // handle error
}
defer watcher.Close()

for {
    cm := new(corev1.ConfigMap)
    eventType, err := watcher.Next(cm)
    if err != nil {
        // watcher encountered and error, exit or create a new watcher
    }
    fmt.Println(eventType, *cm.Metadata.Name)
}

Both in-cluster and out-of-cluster clients are initialized with a primary namespace. This is the recommended value to use when listing or watching.

client, err := k8s.NewInClusterClient()
if err != nil {
    // handle error
}

// List pods in the namespace the client is running in.
var pods corev1.PodList
err := client.List(ctx, client.Namespace, &pods)

Custom resources

Client operations support user defined resources, such as resources provided by CustomResourceDefinitions and aggregated API servers. To use a custom resource, define an equivalent Go struct then register it with the k8s package. By default the client will use JSON serialization when encoding and decoding custom resources.

import (
    "github.com/ericchiang/k8s"
    metav1 "github.com/ericchiang/k8s/apis/meta/v1"
)

type MyResource struct {
    Metadata *metav1.ObjectMeta `json:"metadata"`
    Foo      string             `json:"foo"`
    Bar      int                `json:"bar"`
}

// Required for MyResource to implement k8s.Resource
func (m *MyResource) GetMetadata() *metav1.ObjectMeta {
    return m.Metadata
}

type MyResourceList struct {
    Metadata *metav1.ListMeta `json:"metadata"`
    Items    []MyResource     `json:"items"`
}

// Require for MyResourceList to implement k8s.ResourceList
func (m *MyResourceList) GetMetadata() *metav1.ListMeta {
    return m.Metadata
}

func init() {
    // Register resources with the k8s package.
    k8s.Register("resource.example.com", "v1", "myresources", true, &MyResource{})
    k8s.RegisterList("resource.example.com", "v1", "myresources", true, &MyResourceList{})
}

Once registered, the library can use the custom resources like any other.

func do(ctx context.Context, client *k8s.Client, namespace string) error {
    r := &MyResource{
        Metadata: &metav1.ObjectMeta{
            Name:      k8s.String("my-custom-resource"),
            Namespace: &namespace,
        },
        Foo: "hello, world!",
        Bar: 42,
    }
    if err := client.Create(ctx, r); err != nil {
        return fmt.Errorf("create: %v", err)
    }
    r.Bar = -8
    if err := client.Update(ctx, r); err != nil {
        return fmt.Errorf("update: %v", err)
    }
    if err := client.Delete(ctx, r); err != nil {
        return fmt.Errorf("delete: %v", err)
    }
    return nil
}

If the custom type implements proto.Message, the client will prefer protobuf when encoding and decoding the type.

Label selectors

Label selectors can be provided to any list operation.

l := new(k8s.LabelSelector)
l.Eq("tier", "production")
l.In("app", "database", "frontend")

var pods corev1.PodList
err := client.List(ctx, "custom-namespace", &pods, l.Selector())

Subresources

Access subresources using the Subresource option.

err := client.Update(ctx, &pod, k8s.Subresource("status"))

Creating out-of-cluster clients

Out-of-cluster clients can be constructed by either creating an http.Client manually or parsing a Config object. The following is an example of creating a client from a kubeconfig:

import (
    "io/ioutil"

    "github.com/ericchiang/k8s"

    "github.com/ghodss/yaml"
)

// loadClient parses a kubeconfig from a file and returns a Kubernetes
// client. It does not support extensions or client auth providers.
func loadClient(kubeconfigPath string) (*k8s.Client, error) {
    data, err := ioutil.ReadFile(kubeconfigPath)
    if err != nil {
        return nil, fmt.Errorf("read kubeconfig: %v", err)
    }

    // Unmarshal YAML into a Kubernetes config object.
    var config k8s.Config
    if err := yaml.Unmarshal(data, &config); err != nil {
        return nil, fmt.Errorf("unmarshal kubeconfig: %v", err)
    }
    return k8s.NewClient(&config)
}

Errors

Errors returned by the Kubernetes API are formatted as unversioned.Status objects and surfaced by clients as *k8s.APIErrors. Programs that need to inspect error codes or failure details can use a type cast to access this information.

// createConfigMap creates a configmap in the client's default namespace
// but does not return an error if a configmap of the same name already
// exists.
func createConfigMap(client *k8s.Client, name string, values map[string]string) error {
    cm := &v1.ConfigMap{
        Metadata: &metav1.ObjectMeta{
            Name:      &name,
            Namespace: &client.Namespace,
        },
        Data: values,
    }

    err := client.Create(context.TODO(), cm)

    // If an HTTP error was returned by the API server, it will be of type
    // *k8s.APIError. This can be used to inspect the status code.
    if apiErr, ok := err.(*k8s.APIError); ok {
        // Resource already exists. Carry on.
        if apiErr.Code == http.StatusConflict {
            return nil
        }
    }
    return fmt.Errorf("create configmap: %v", err)
}

# Packages

No description provided by the author
Package runtime is a generated protocol buffer package.
No description provided by the author
No description provided by the author

# Functions

Bool is a convenience for converting a bool literal to a pointer to a bool.
No description provided by the author
No description provided by the author
DeletePropagationBackground deletes the resources and causes the garbage collector to delete dependent resources in the background.
DeletePropagationForeground deletes the resources and causes the garbage collector to delete dependent resources and wait for all dependents whose ownerReference.blockOwnerDeletion=true.
DeletePropagationOrphan orphans the dependent resources during a delete.
Int is a convenience for converting an int literal to a pointer to an int.
Int32 is a convenience for converting an int32 literal to a pointer to an int32.
NewClient initializes a client from a client config.
No description provided by the author
NewInClusterClient returns a client that uses the service account bearer token mounted into Kubernetes pods.
QueryParam can be used to manually set a URL query parameter by name.
No description provided by the author
No description provided by the author
ResourceVersion causes watch operations to only show changes since a particular version of a resource.
String returns a pointer to a string.
Subresource is a way to interact with a part of an API object without needing permissions on the entire resource.
Timeout declares the timeout for list and watch operations.

# Constants

AllNamespaces is given to list and watch operations to signify that the code should list or watch resources in all namespaces.
Types for watch events.
No description provided by the author
No description provided by the author
No description provided by the author

# Structs

APIError is an error from a unexpected status code.
AuthInfo contains information that describes identity information.
AuthProviderConfig holds the configuration for a specified auth provider.
Client is a Kuberntes client.
Cluster contains information about how to communicate with a kubernetes cluster.
Config holds the information needed to build connect to remote kubernetes clusters as a given user.
Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with).
Discovery is a client used to determine the API version and supported resources of the server.
LabelSelector represents a Kubernetes label selector.
NamedAuthInfo relates nicknames to auth information.
NamedCluster relates nicknames to cluster information.
NamedContext relates nicknames to context information.
NamedExtension relates nicknames to extension information.
No description provided by the author
No description provided by the author
Watcher receives a stream of events tracking a particular resource within a namespace or across all namespaces.

# Interfaces

Option represents optional call parameters, such as label selectors.
Resource is a Kubernetes resource, such as a Node or Pod.
Resource is list of common Kubernetes resources, such as a NodeList or PodList.