-
-
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 ...