-
-
Save dwmkerr/447692c8bba28929ef914239781c4e59 to your computer and use it in GitHub Desktop.
// Example showing how to patch kubernetes resources. | |
// This is the companion to my article 'Patching Kubernetes Resources in Golang': | |
// https://dwmkerr.com/patching-kubernetes-resources-in-golang/ | |
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
types "k8s.io/apimachinery/pkg/types" | |
"k8s.io/client-go/kubernetes" | |
_ "k8s.io/client-go/plugin/pkg/client/auth" | |
"k8s.io/client-go/tools/clientcmd" | |
) | |
var ( | |
// Leave blank for the default context in your kube config. | |
context = "" | |
// Name of the replication controller to scale, and the desired number of replicas. | |
replicationControllerName = "my-rc" | |
replicas = uint32(3) | |
) | |
// patchStringValue specifies a patch operation for a string. | |
type patchStringValue struct { | |
Op string `json:"op"` | |
Path string `json:"path"` | |
Value string `json:"value"` | |
} | |
// patchUint32Value specifies a patch operation for a uint32. | |
type patchUInt32Value struct { | |
Op string `json:"op"` | |
Path string `json:"path"` | |
Value uint32 `json:"value"` | |
} | |
func scaleReplicationController(clientSet *kubernetes.Clientset, replicasetName string, scale uint32) error { | |
payload := []patchUInt32Value{{ | |
Op: "replace", | |
Path: "/spec/replicas", | |
Value: scale, | |
}} | |
payloadBytes, _ := json.Marshal(payload) | |
_, err := clientSet. | |
CoreV1(). | |
ReplicationControllers("default"). | |
Patch(replicasetName, types.JSONPatchType, payloadBytes) | |
return err | |
} | |
func main() { | |
// Get the local kube config. | |
fmt.Printf("Connecting to Kubernetes Context %v\n", context) | |
config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( | |
clientcmd.NewDefaultClientConfigLoadingRules(), | |
&clientcmd.ConfigOverrides{CurrentContext: context}).ClientConfig() | |
if err != nil { | |
panic(err.Error()) | |
} | |
// Creates the clientset | |
clientset, err := kubernetes.NewForConfig(config) | |
if err != nil { | |
panic(err.Error()) | |
} | |
// Scale our replication controller. | |
fmt.Printf("Scaling replication controller %v to %v\n", replicationControllerName, replicas) | |
err = scaleReplicationController(clientset, replicationControllerName, replicas) | |
if err != nil { | |
panic(err.Error()) | |
} | |
} |
Well spotted! Thanks @Adirio, I've just fixed it now :)
Why do we need that patchStringValue
? I'm curious.
@zuthfreelancer - you don't for this sample, it's there in case you want to patch something else which is a string, sorry it's a bit odd!
Thank you
How can I escape the "statefulset.kubernetes.io/pod-name" if I use patchStringValue() func? API does not accept it. Thanks
If anyone is trying to patch something that is an array, like tolerations, I made a slight modification (thank you dwmkerr for the original code!):
type tolerationValue struct {
Key string `json:"key"`
Operator string `json:"operator"`
Value string `json:"value"`
Effect string `json:"effect"`
}
type structArrayPayload struct {
Op string `json:"op"`
Path string `json:"path"`
// tolerations are an array
Value []tolerationValue `json:"value"`
}
patchPayload := []structArrayPayload{
{
Op: "replace",
Path: "/spec/template/spec/tolerations",
Value: []tolerationValue{
{
Key: "toleration.key.here",
Operator: "Equal",
Value: "true",
Effect: "NoSchedule",
},
},
},
}
this seems to also work and avoids having to define lots of structs:
type patch struct {
Op string `json:"op"`
Path string `json:"path"`
Value interface{} `json:"value"`
}
How can I escape the "statefulset.kubernetes.io/pod-name" if I use patchStringValue() func? API does not accept it. Thanks
Did you find any solutions for this?
How can I escape the "statefulset.kubernetes.io/pod-name" if I use patchStringValue() func? API does not accept it. Thanks
Did you find any solutions for this?
I'm sorry, I can't remember how I solved it.
How can I escape the "statefulset.kubernetes.io/pod-name" if I use patchStringValue() func? API does not accept it. Thanks
For the records, the solution here is, assuming we are changing a pod label,
podLabel := `statefulset.kubernetes.io~1pod-name`
Resulting in path being,
path := fmt.Sprintf("/metadata/labels/%s", podLabel)
My 2 cents.
Line 32 has a typo, it should be
// patchUint32Value ...