client

package
v1.2.4 Latest Latest
Warning

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

Go to latest
Published: Jan 1, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

README

Kubernetes

Utilities for Kubernetes resource management with type-safe REST client operations.

Overview

The kubernetes package provides simplified interfaces for interacting with Kubernetes API servers through REST clients. It supports both in-cluster and external client configurations with generic type-safe operations for CRUD (Create, Read, Update, Delete) operations on Kubernetes resources.

Features

  • In-Cluster Client - Automatic configuration for pods running in Kubernetes
  • External Client - Configuration support for external applications
  • Generic Get - Type-safe resource retrieval
  • Create Operations - Post resources to Kubernetes API
  • Update Operations - Put updated resources
  • Delete Operations - Remove resources by name
  • Custom Resources - Full support for CRDs
  • Standard Resources - Support for all Kubernetes native resources

Installation

go get -u github.com/common-library/go/kubernetes/resource/client
go get -u k8s.io/client-go
go get -u k8s.io/api

Quick Start

In-Cluster Usage
import (
    "github.com/common-library/go/kubernetes/resource/client"
    coreV1 "k8s.io/api/core/v1"
)

// Inside a Kubernetes pod
restClient, err := client.GetClientForInCluster()
if err != nil {
    log.Fatal(err)
}

// Get a ConfigMap
configMap, err := client.Get[coreV1.ConfigMap](
    restClient,
    "",           // group (empty for core resources)
    "v1",         // version
    "default",    // namespace
    "configmaps", // resource type
    "app-config", // name
)
External Usage
import (
    "k8s.io/client-go/tools/clientcmd"
    "github.com/common-library/go/kubernetes/resource/client"
)

// Load kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
if err != nil {
    log.Fatal(err)
}

// Create client
restClient, err := client.GetClientUsingConfig(config)
if err != nil {
    log.Fatal(err)
}

// Use client...

API Reference

GetClientForInCluster
func GetClientForInCluster() (rest.Interface, error)

Creates a Kubernetes REST client for in-cluster use from within a pod.

Returns:

  • rest.Interface - Kubernetes REST client
  • error - Error if client creation fails

Requirements:

  • Must run inside a Kubernetes pod
  • Service account token must be mounted
  • CA certificate must be available
GetClientUsingConfig
func GetClientUsingConfig(config *rest.Config) (rest.Interface, error)

Creates a Kubernetes REST client using a provided configuration.

Parameters:

  • config - Kubernetes REST client configuration

Returns:

  • rest.Interface - Kubernetes REST client
  • error - Error if client creation fails
Get
func Get[T any](
    restClient rest.Interface,
    group, version, namespace, resource, name string,
) (T, error)

Retrieves a Kubernetes resource by name.

Type Parameters:

  • T - Target Go type for the resource

Parameters:

  • restClient - Kubernetes REST client
  • group - API group (empty for core resources)
  • version - API version (e.g., "v1")
  • namespace - Namespace (empty for cluster-scoped)
  • resource - Resource type in plural (e.g., "pods")
  • name - Resource name

Returns:

  • T - Retrieved resource
  • error - Error if retrieval fails
Post
func Post(
    restClient rest.Interface,
    resource string,
    object runtime.Object,
) error

Creates a new Kubernetes resource.

Parameters:

  • restClient - Kubernetes REST client
  • resource - Resource type in plural
  • object - Resource object to create

Returns:

  • error - Error if creation fails
Put
func Put(
    restClient rest.Interface,
    resource string,
    object runtime.Object,
) error

Updates an existing Kubernetes resource.

Parameters:

  • restClient - Kubernetes REST client
  • resource - Resource type in plural
  • object - Resource object with updates (must include ResourceVersion)

Returns:

  • error - Error if update fails
Delete
func Delete(
    restClient rest.Interface,
    group, version, namespace, resource, name string,
) error

Deletes a Kubernetes resource by name.

Parameters:

  • restClient - Kubernetes REST client
  • group - API group (empty for core resources)
  • version - API version
  • namespace - Namespace (empty for cluster-scoped)
  • resource - Resource type in plural
  • name - Resource name to delete

Returns:

  • error - Error if deletion fails

Complete Examples

ConfigMap Management
package main

import (
    "fmt"
    "log"
    
    "github.com/common-library/go/kubernetes/resource/client"
    coreV1 "k8s.io/api/core/v1"
    metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func main() {
    // Get client
    restClient, err := client.GetClientForInCluster()
    if err != nil {
        log.Fatal(err)
    }
    
    // Create ConfigMap
    configMap := &coreV1.ConfigMap{
        TypeMeta: metaV1.TypeMeta{
            APIVersion: "v1",
            Kind:       "ConfigMap",
        },
        ObjectMeta: metaV1.ObjectMeta{
            Name:      "app-config",
            Namespace: "default",
        },
        Data: map[string]string{
            "database.host": "localhost",
            "database.port": "5432",
            "app.mode":      "production",
        },
    }
    
    err = client.Post(restClient, "configmaps", configMap)
    if err != nil {
        log.Fatal("Failed to create ConfigMap:", err)
    }
    fmt.Println("ConfigMap created successfully")
    
    // Get ConfigMap
    retrieved, err := client.Get[coreV1.ConfigMap](
        restClient, "", "v1", "default", "configmaps", "app-config",
    )
    if err != nil {
        log.Fatal("Failed to get ConfigMap:", err)
    }
    fmt.Printf("ConfigMap data: %v\n", retrieved.Data)
    
    // Update ConfigMap
    retrieved.Data["app.mode"] = "staging"
    err = client.Put(restClient, "configmaps", &retrieved)
    if err != nil {
        log.Fatal("Failed to update ConfigMap:", err)
    }
    fmt.Println("ConfigMap updated successfully")
    
    // Delete ConfigMap
    err = client.Delete(restClient, "", "v1", "default", "configmaps", "app-config")
    if err != nil {
        log.Fatal("Failed to delete ConfigMap:", err)
    }
    fmt.Println("ConfigMap deleted successfully")
}
Deployment Management
package main

import (
    "fmt"
    "log"
    
    "github.com/common-library/go/kubernetes/resource/client"
    appsV1 "k8s.io/api/apps/v1"
    coreV1 "k8s.io/api/core/v1"
    metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func main() {
    restClient, err := client.GetClientForInCluster()
    if err != nil {
        log.Fatal(err)
    }
    
    // Create Deployment
    replicas := int32(3)
    deployment := &appsV1.Deployment{
        TypeMeta: metaV1.TypeMeta{
            APIVersion: "apps/v1",
            Kind:       "Deployment",
        },
        ObjectMeta: metaV1.ObjectMeta{
            Name:      "nginx-deployment",
            Namespace: "default",
            Labels: map[string]string{
                "app": "nginx",
            },
        },
        Spec: appsV1.DeploymentSpec{
            Replicas: &replicas,
            Selector: &metaV1.LabelSelector{
                MatchLabels: map[string]string{
                    "app": "nginx",
                },
            },
            Template: coreV1.PodTemplateSpec{
                ObjectMeta: metaV1.ObjectMeta{
                    Labels: map[string]string{
                        "app": "nginx",
                    },
                },
                Spec: coreV1.PodSpec{
                    Containers: []coreV1.Container{{
                        Name:  "nginx",
                        Image: "nginx:1.21",
                        Ports: []coreV1.ContainerPort{{
                            ContainerPort: 80,
                        }},
                    }},
                },
            },
        },
    }
    
    err = client.Post(restClient, "deployments", deployment)
    if err != nil {
        log.Fatal("Failed to create Deployment:", err)
    }
    fmt.Println("Deployment created")
    
    // Scale Deployment
    retrieved, err := client.Get[appsV1.Deployment](
        restClient, "apps", "v1", "default", "deployments", "nginx-deployment",
    )
    if err != nil {
        log.Fatal(err)
    }
    
    newReplicas := int32(5)
    retrieved.Spec.Replicas = &newReplicas
    
    err = client.Put(restClient, "deployments", &retrieved)
    if err != nil {
        log.Fatal("Failed to scale Deployment:", err)
    }
    fmt.Println("Deployment scaled to 5 replicas")
}
Secret Management
package main

import (
    "fmt"
    "log"
    
    "github.com/common-library/go/kubernetes/resource/client"
    coreV1 "k8s.io/api/core/v1"
    metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func main() {
    restClient, err := client.GetClientForInCluster()
    if err != nil {
        log.Fatal(err)
    }
    
    // Create Secret
    secret := &coreV1.Secret{
        TypeMeta: metaV1.TypeMeta{
            APIVersion: "v1",
            Kind:       "Secret",
        },
        ObjectMeta: metaV1.ObjectMeta{
            Name:      "db-credentials",
            Namespace: "default",
        },
        Type: coreV1.SecretTypeOpaque,
        StringData: map[string]string{
            "username": "admin",
            "password": "super-secret-password",
        },
    }
    
    err = client.Post(restClient, "secrets", secret)
    if err != nil {
        log.Fatal("Failed to create Secret:", err)
    }
    fmt.Println("Secret created")
    
    // Get Secret
    retrieved, err := client.Get[coreV1.Secret](
        restClient, "", "v1", "default", "secrets", "db-credentials",
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Secret has %d keys\n", len(retrieved.Data))
}
Service Management
package main

import (
    "fmt"
    "log"
    
    "github.com/common-library/go/kubernetes/resource/client"
    coreV1 "k8s.io/api/core/v1"
    metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/util/intstr"
)

func main() {
    restClient, err := client.GetClientForInCluster()
    if err != nil {
        log.Fatal(err)
    }
    
    // Create Service
    service := &coreV1.Service{
        TypeMeta: metaV1.TypeMeta{
            APIVersion: "v1",
            Kind:       "Service",
        },
        ObjectMeta: metaV1.ObjectMeta{
            Name:      "nginx-service",
            Namespace: "default",
        },
        Spec: coreV1.ServiceSpec{
            Selector: map[string]string{
                "app": "nginx",
            },
            Type: coreV1.ServiceTypeLoadBalancer,
            Ports: []coreV1.ServicePort{{
                Port:       80,
                TargetPort: intstr.FromInt(80),
                Protocol:   coreV1.ProtocolTCP,
            }},
        },
    }
    
    err = client.Post(restClient, "services", service)
    if err != nil {
        log.Fatal("Failed to create Service:", err)
    }
    fmt.Println("Service created")
}
Namespace Management
package main

import (
    "fmt"
    "log"
    
    "github.com/common-library/go/kubernetes/resource/client"
    coreV1 "k8s.io/api/core/v1"
    metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func main() {
    restClient, err := client.GetClientForInCluster()
    if err != nil {
        log.Fatal(err)
    }
    
    // Create Namespace
    namespace := &coreV1.Namespace{
        TypeMeta: metaV1.TypeMeta{
            APIVersion: "v1",
            Kind:       "Namespace",
        },
        ObjectMeta: metaV1.ObjectMeta{
            Name: "production",
            Labels: map[string]string{
                "environment": "production",
            },
        },
    }
    
    err = client.Post(restClient, "namespaces", namespace)
    if err != nil {
        log.Fatal("Failed to create Namespace:", err)
    }
    fmt.Println("Namespace created")
    
    // Get Namespace (cluster-scoped resource)
    retrieved, err := client.Get[coreV1.Namespace](
        restClient,
        "",            // group
        "v1",          // version
        "",            // namespace (empty for cluster-scoped)
        "namespaces",  // resource
        "production",  // name
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Namespace: %s\n", retrieved.Name)
    fmt.Printf("Labels: %v\n", retrieved.Labels)
}
Pod Management
package main

import (
    "fmt"
    "log"
    
    "github.com/common-library/go/kubernetes/resource/client"
    coreV1 "k8s.io/api/core/v1"
    metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func main() {
    restClient, err := client.GetClientForInCluster()
    if err != nil {
        log.Fatal(err)
    }
    
    // Create Pod
    pod := &coreV1.Pod{
        TypeMeta: metaV1.TypeMeta{
            APIVersion: "v1",
            Kind:       "Pod",
        },
        ObjectMeta: metaV1.ObjectMeta{
            Name:      "test-pod",
            Namespace: "default",
        },
        Spec: coreV1.PodSpec{
            Containers: []coreV1.Container{{
                Name:  "nginx",
                Image: "nginx:1.21",
                Ports: []coreV1.ContainerPort{{
                    ContainerPort: 80,
                }},
            }},
        },
    }
    
    err = client.Post(restClient, "pods", pod)
    if err != nil {
        log.Fatal("Failed to create Pod:", err)
    }
    fmt.Println("Pod created")
    
    // Get Pod status
    retrieved, err := client.Get[coreV1.Pod](
        restClient, "", "v1", "default", "pods", "test-pod",
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Pod phase: %s\n", retrieved.Status.Phase)
    fmt.Printf("Pod IP: %s\n", retrieved.Status.PodIP)
}
Custom Resource Management
package main

import (
    "fmt"
    "log"
    
    "github.com/common-library/go/kubernetes/resource/client"
    metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// Custom Resource Definition
type MyCustomResource struct {
    metaV1.TypeMeta   `json:",inline"`
    metaV1.ObjectMeta `json:"metadata,omitempty"`
    Spec              MySpec   `json:"spec,omitempty"`
    Status            MyStatus `json:"status,omitempty"`
}

type MySpec struct {
    Field1 string `json:"field1"`
    Field2 int    `json:"field2"`
}

type MyStatus struct {
    Ready bool `json:"ready"`
}

func main() {
    restClient, err := client.GetClientForInCluster()
    if err != nil {
        log.Fatal(err)
    }
    
    // Create Custom Resource
    cr := &MyCustomResource{
        TypeMeta: metaV1.TypeMeta{
            APIVersion: "example.com/v1alpha1",
            Kind:       "MyCustomResource",
        },
        ObjectMeta: metaV1.ObjectMeta{
            Name:      "my-instance",
            Namespace: "default",
        },
        Spec: MySpec{
            Field1: "value1",
            Field2: 42,
        },
    }
    
    err = client.Post(restClient, "mycustomresources", cr)
    if err != nil {
        log.Fatal("Failed to create Custom Resource:", err)
    }
    fmt.Println("Custom Resource created")
    
    // Get Custom Resource
    retrieved, err := client.Get[MyCustomResource](
        restClient,
        "example.com",        // group
        "v1alpha1",           // version
        "default",            // namespace
        "mycustomresources",  // resource (plural)
        "my-instance",        // name
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("CR Spec: %+v\n", retrieved.Spec)
}
External Client with Kubeconfig
package main

import (
    "fmt"
    "log"
    "os"
    "path/filepath"
    
    "github.com/common-library/go/kubernetes/resource/client"
    coreV1 "k8s.io/api/core/v1"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    // Get kubeconfig path
    home, _ := os.UserHomeDir()
    kubeconfig := filepath.Join(home, ".kube", "config")
    
    // Load config
    config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
    if err != nil {
        log.Fatal("Failed to load kubeconfig:", err)
    }
    
    // Create client
    restClient, err := client.GetClientUsingConfig(config)
    if err != nil {
        log.Fatal("Failed to create client:", err)
    }
    
    // List pods (using empty name to get list)
    // Note: This example shows the pattern, but you'd typically use
    // the List operation from client-go for listing
    
    // Get specific pod
    pod, err := client.Get[coreV1.Pod](
        restClient, "", "v1", "default", "pods", "my-pod",
    )
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Pod: %s, Status: %s\n", pod.Name, pod.Status.Phase)
}

Best Practices

1. Handle ResourceVersion for Updates
// Good: Get, modify, then put
configMap, _ := client.Get[coreV1.ConfigMap](
    restClient, "", "v1", "default", "configmaps", "app-config",
)
configMap.Data["key"] = "value"
client.Put(restClient, "configmaps", &configMap)

// Avoid: Creating object without ResourceVersion
// Will fail with conflict error
2. Use Proper API Groups
// Good: Core resources use empty group
client.Get[coreV1.Pod](restClient, "", "v1", "default", "pods", "my-pod")

// Good: Apps resources use "apps" group
client.Get[appsV1.Deployment](restClient, "apps", "v1", "default", "deployments", "my-app")

// Avoid: Wrong group
// client.Get[coreV1.Pod](restClient, "core", "v1", ...) // Wrong
3. Check Errors Properly
import "k8s.io/apimachinery/pkg/api/errors"

// Good: Check specific error types
pod, err := client.Get[coreV1.Pod](restClient, "", "v1", "default", "pods", "my-pod")
if err != nil {
    if errors.IsNotFound(err) {
        log.Println("Pod not found")
    } else if errors.IsUnauthorized(err) {
        log.Println("Unauthorized")
    } else {
        log.Fatal(err)
    }
}

// Avoid: Ignoring errors
// pod, _ := client.Get[...]
4. Set Required Metadata
// Good: Complete metadata
deployment := &appsV1.Deployment{
    TypeMeta: metaV1.TypeMeta{
        APIVersion: "apps/v1",
        Kind:       "Deployment",
    },
    ObjectMeta: metaV1.ObjectMeta{
        Name:      "my-app",
        Namespace: "default",
    },
    Spec: appsV1.DeploymentSpec{...},
}

// Avoid: Missing TypeMeta or ObjectMeta
5. Use Retry Logic for Conflicts
// Good: Retry on conflict
for i := 0; i < 3; i++ {
    configMap, err := client.Get[coreV1.ConfigMap](...)
    if err != nil {
        log.Fatal(err)
    }
    
    configMap.Data["key"] = "value"
    
    err = client.Put(restClient, "configmaps", &configMap)
    if err == nil {
        break
    }
    
    if !errors.IsConflict(err) {
        log.Fatal(err)
    }
}

Error Handling

Common Errors
import "k8s.io/apimachinery/pkg/api/errors"

pod, err := client.Get[coreV1.Pod](restClient, "", "v1", "default", "pods", "my-pod")
if err != nil {
    switch {
    case errors.IsNotFound(err):
        // Resource doesn't exist (404)
        log.Println("Pod not found")
        
    case errors.IsConflict(err):
        // Update conflict (409) - ResourceVersion mismatch
        log.Println("Conflict, retry with latest version")
        
    case errors.IsUnauthorized(err):
        // Authentication failed (401)
        log.Println("Unauthorized")
        
    case errors.IsForbidden(err):
        // Permission denied (403)
        log.Println("Forbidden")
        
    case errors.IsAlreadyExists(err):
        // Resource already exists (409)
        log.Println("Already exists")
        
    case errors.IsInvalid(err):
        // Invalid resource (422)
        log.Println("Invalid resource")
        
    default:
        log.Fatal("Unknown error:", err)
    }
}

Dependencies

  • k8s.io/client-go - Kubernetes client library
  • k8s.io/api - Kubernetes API types
  • k8s.io/apimachinery - Kubernetes API machinery

Further Reading

Documentation

Overview

Package client provides Kubernetes REST client utilities for resource management.

This package simplifies interactions with the Kubernetes API server by providing type-safe generic functions for common CRUD operations on Kubernetes resources.

Features:

  • In-cluster and external client configuration
  • Generic resource Get operations
  • Resource Create (Post) operations
  • Resource Update (Put) operations
  • Resource Delete operations
  • Support for custom resources

Example:

// In-cluster
restClient, _ := client.GetClientForInCluster()

// Get ConfigMap
cm, err := client.Get[v1.ConfigMap](restClient, "", "v1", "default", "configmaps", "my-config")

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Delete

func Delete(restClient rest.Interface, group, version, namespace, resource, name string) error

Delete removes a Kubernetes resource by name.

This function sends a DELETE request to the Kubernetes API server to remove the specified resource. The deletion may be immediate or graceful depending on the resource type and cluster configuration.

Parameters:

  • restClient: Kubernetes REST client interface
  • group: API group (empty "" for core resources)
  • version: API version (e.g., "v1", "v1beta1")
  • namespace: Namespace name (empty "" for cluster-scoped resources)
  • resource: Resource type in plural form (e.g., "pods", "configmaps")
  • name: Resource name to delete

Returns:

  • error: Error if deletion fails

Deletion behavior:

  • Pods: Graceful shutdown with termination period
  • Deployments: Cascading deletion of owned ReplicaSets and Pods
  • ConfigMaps/Secrets: Immediate deletion
  • Custom Resources: Depends on finalizers

Example - Delete ConfigMap:

err := client.Delete(
    restClient,
    "",           // group
    "v1",         // version
    "default",    // namespace
    "configmaps", // resource
    "app-config", // name
)
if err != nil {
    log.Fatal("Failed to delete ConfigMap:", err)
}

Example - Delete Deployment:

err := client.Delete(
    restClient,
    "apps",        // group
    "v1",          // version
    "production",  // namespace
    "deployments", // resource
    "web-app",     // name
)
if err != nil {
    log.Fatal("Failed to delete Deployment:", err)
}

Example - Delete Pod:

err := client.Delete(
    restClient,
    "",        // group
    "v1",      // version
    "default", // namespace
    "pods",    // resource
    "web-app-pod-12345",
)

Example - Delete Node (cluster-scoped):

err := client.Delete(
    restClient,
    "",      // group
    "v1",    // version
    "",      // namespace (empty for cluster-scoped)
    "nodes", // resource
    "worker-node-1",
)

Example - Delete Custom Resource:

err := client.Delete(
    restClient,
    "example.com",        // group
    "v1alpha1",           // version
    "default",            // namespace
    "mycustomresources",  // resource
    "my-instance",        // name
)

Example - Check if resource exists before deletion:

import "k8s.io/apimachinery/pkg/api/errors"

err := client.Delete(restClient, "", "v1", "default", "configmaps", "app-config")
if err != nil {
    if errors.IsNotFound(err) {
        log.Println("ConfigMap not found, already deleted")
    } else {
        log.Fatal("Failed to delete:", err)
    }
}

func Get

func Get[T any](restClient rest.Interface, group, version, namespace, resource, name string) (T, error)

Get retrieves a Kubernetes resource by name and returns it as type T.

This generic function fetches a single Kubernetes resource from the API server and unmarshals it into the specified Go type.

Type Parameters:

  • T: Target Go type (must match the resource being retrieved)

Parameters:

  • restClient: Kubernetes REST client interface
  • group: API group (empty "" for core resources like Pod, ConfigMap)
  • version: API version (e.g., "v1", "v1beta1")
  • namespace: Namespace name (empty "" for cluster-scoped resources)
  • resource: Resource type in plural form (e.g., "pods", "configmaps", "deployments")
  • name: Resource name

Returns:

  • T: Retrieved resource as type T
  • error: Error if request fails or unmarshaling fails

The function constructs the appropriate API path:

  • Core resources: /api/{version}/namespaces/{namespace}/{resource}/{name}
  • Group resources: /apis/{group}/{version}/namespaces/{namespace}/{resource}/{name}
  • Cluster-scoped: /api(s)/{group}/{version}/{resource}/{name}

Example - Get ConfigMap:

import coreV1 "k8s.io/api/core/v1"

configMap, err := client.Get[coreV1.ConfigMap](
    restClient,
    "",           // group (empty for core)
    "v1",         // version
    "default",    // namespace
    "configmaps", // resource
    "app-config", // name
)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("ConfigMap data: %v\n", configMap.Data)

Example - Get Deployment:

import appsV1 "k8s.io/api/apps/v1"

deployment, err := client.Get[appsV1.Deployment](
    restClient,
    "apps",         // group
    "v1",           // version
    "production",   // namespace
    "deployments",  // resource
    "web-app",      // name
)

Example - Get Node (cluster-scoped):

node, err := client.Get[coreV1.Node](
    restClient,
    "",      // group
    "v1",    // version
    "",      // namespace (empty for cluster-scoped)
    "nodes", // resource
    "worker-node-1",
)

Example - Get Custom Resource:

cr, err := client.Get[MyCustomResource](
    restClient,
    "example.com",     // group
    "v1alpha1",        // version
    "default",         // namespace
    "mycustomresources", // resource (plural)
    "my-instance",     // name
)

func GetClientForInCluster

func GetClientForInCluster() (rest.Interface, error)

GetClientForInCluster creates a Kubernetes REST client for in-cluster use.

This function is designed to be called from within a Kubernetes pod and uses the service account token and cluster CA certificate mounted by Kubernetes.

Returns:

  • rest.Interface: Kubernetes REST client interface
  • error: Error if client creation fails

The function performs these steps:

  1. Loads in-cluster configuration from environment and mounted files
  2. Creates a Kubernetes clientset using the configuration
  3. Returns the REST client from the clientset

In-cluster configuration requirements:

  • KUBERNETES_SERVICE_HOST environment variable
  • KUBERNETES_SERVICE_PORT environment variable
  • Service account token at /var/run/secrets/kubernetes.io/serviceaccount/token
  • CA certificate at /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Example:

// Inside a Kubernetes pod
restClient, err := client.GetClientForInCluster()
if err != nil {
    log.Fatal("Failed to create in-cluster client:", err)
}

// Use client to get a ConfigMap
configMap, err := client.Get[coreV1.ConfigMap](
    restClient,
    "",        // group (empty for core)
    "v1",      // version
    "default", // namespace
    "configmaps",
    "my-config",
)

Note: This function will fail when run outside a Kubernetes cluster. Use GetClientUsingConfig for external access.

func GetClientUsingConfig

func GetClientUsingConfig(config *rest.Config) (rest.Interface, error)

GetClientUsingConfig creates a Kubernetes REST client using a provided configuration.

This function is designed for clients running outside a Kubernetes cluster, such as CLI tools or external applications.

Parameters:

  • config: Kubernetes REST client configuration

Returns:

  • rest.Interface: Kubernetes REST client interface
  • error: Error if client creation fails

The configuration typically includes:

  • API server URL
  • Authentication credentials (token, certificate, or username/password)
  • TLS settings
  • Timeout settings

Example with kubeconfig:

import "k8s.io/client-go/tools/clientcmd"

// Load kubeconfig file
config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
if err != nil {
    log.Fatal(err)
}

// Create client
restClient, err := client.GetClientUsingConfig(config)
if err != nil {
    log.Fatal(err)
}

// Use client
pods, _ := client.Get[coreV1.PodList](restClient, "", "v1", "default", "pods", "")

Example with manual configuration:

config := &rest.Config{
    Host:        "https://k8s.example.com:6443",
    BearerToken: "your-token-here",
    TLSClientConfig: rest.TLSClientConfig{
        Insecure: false,
        CAFile:   "/path/to/ca.crt",
    },
}

restClient, err := client.GetClientUsingConfig(config)

func Post

func Post(restClient rest.Interface, resource string, object runtime.Object) error

Post creates a new Kubernetes resource.

This function sends a POST request to the Kubernetes API server to create a new resource. The resource's API group, version, and namespace are extracted from the object's metadata.

Parameters:

  • restClient: Kubernetes REST client interface
  • resource: Resource type in plural form (e.g., "pods", "configmaps", "deployments")
  • object: Kubernetes resource object to create (must implement runtime.Object)

Returns:

  • error: Error if creation fails

The object parameter must:

  • Implement runtime.Object interface
  • Have TypeMeta set (APIVersion and Kind)
  • Have ObjectMeta with at least Name and optionally Namespace
  • Not have ResourceVersion set (will be assigned by API server)

Example - Create ConfigMap:

import coreV1 "k8s.io/api/core/v1"
import metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"

configMap := &coreV1.ConfigMap{
    TypeMeta: metaV1.TypeMeta{
        APIVersion: "v1",
        Kind:       "ConfigMap",
    },
    ObjectMeta: metaV1.ObjectMeta{
        Name:      "app-config",
        Namespace: "default",
    },
    Data: map[string]string{
        "config.yaml": "key: value",
    },
}

err := client.Post(restClient, "configmaps", configMap)
if err != nil {
    log.Fatal("Failed to create ConfigMap:", err)
}

Example - Create Deployment:

import appsV1 "k8s.io/api/apps/v1"

replicas := int32(3)
deployment := &appsV1.Deployment{
    TypeMeta: metaV1.TypeMeta{
        APIVersion: "apps/v1",
        Kind:       "Deployment",
    },
    ObjectMeta: metaV1.ObjectMeta{
        Name:      "web-app",
        Namespace: "production",
    },
    Spec: appsV1.DeploymentSpec{
        Replicas: &replicas,
        Selector: &metaV1.LabelSelector{
            MatchLabels: map[string]string{"app": "web"},
        },
        Template: coreV1.PodTemplateSpec{
            ObjectMeta: metaV1.ObjectMeta{
                Labels: map[string]string{"app": "web"},
            },
            Spec: coreV1.PodSpec{
                Containers: []coreV1.Container{{
                    Name:  "web",
                    Image: "nginx:1.21",
                }},
            },
        },
    },
}

err := client.Post(restClient, "deployments", deployment)

Example - Create Custom Resource:

customResource := &MyCustomResource{
    TypeMeta: metaV1.TypeMeta{
        APIVersion: "example.com/v1alpha1",
        Kind:       "MyCustomResource",
    },
    ObjectMeta: metaV1.ObjectMeta{
        Name:      "my-instance",
        Namespace: "default",
    },
    Spec: MySpec{
        Field1: "value1",
    },
}

err := client.Post(restClient, "mycustomresources", customResource)

func Put

func Put(restClient rest.Interface, resource string, object runtime.Object) error

Put updates an existing Kubernetes resource.

This function sends a PUT request to the Kubernetes API server to update an existing resource. The resource must already exist and must include a valid ResourceVersion for optimistic concurrency control.

Parameters:

  • restClient: Kubernetes REST client interface
  • resource: Resource type in plural form (e.g., "pods", "configmaps", "deployments")
  • object: Kubernetes resource object with updates (must implement runtime.Object)

Returns:

  • error: Error if update fails

The object parameter must:

  • Implement runtime.Object interface
  • Have TypeMeta set (APIVersion and Kind)
  • Have ObjectMeta with Name, Namespace, and ResourceVersion
  • Match an existing resource on the server

Important: ResourceVersion must match the current version on the server, otherwise the update will fail with a conflict error. To ensure this, first Get the resource, modify it, then Put it back.

Example - Update ConfigMap:

import coreV1 "k8s.io/api/core/v1"

// First, get the current ConfigMap
configMap, err := client.Get[coreV1.ConfigMap](
    restClient, "", "v1", "default", "configmaps", "app-config",
)
if err != nil {
    log.Fatal(err)
}

// Modify the ConfigMap
configMap.Data["new-key"] = "new-value"

// Update the resource
err = client.Put(restClient, "configmaps", &configMap)
if err != nil {
    log.Fatal("Failed to update ConfigMap:", err)
}

Example - Update Deployment replicas:

import appsV1 "k8s.io/api/apps/v1"

// Get current deployment
deployment, err := client.Get[appsV1.Deployment](
    restClient, "apps", "v1", "production", "deployments", "web-app",
)
if err != nil {
    log.Fatal(err)
}

// Scale up
replicas := int32(5)
deployment.Spec.Replicas = &replicas

// Update
err = client.Put(restClient, "deployments", &deployment)
if err != nil {
    log.Fatal("Failed to scale deployment:", err)
}

Example - Update with retry on conflict:

import "k8s.io/apimachinery/pkg/api/errors"

for i := 0; i < 3; i++ {
    // Get latest version
    configMap, err := client.Get[coreV1.ConfigMap](
        restClient, "", "v1", "default", "configmaps", "app-config",
    )
    if err != nil {
        log.Fatal(err)
    }

    // Modify
    configMap.Data["key"] = "value"

    // Try to update
    err = client.Put(restClient, "configmaps", &configMap)
    if err == nil {
        break // Success
    }

    // Retry if conflict
    if !errors.IsConflict(err) {
        log.Fatal(err)
    }
}

Types

This section is empty.

Jump to

Keyboard shortcuts

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