feat(dao/dp): use external patch method to create json patch
parent
c534fbb75e
commit
8cb9da07b1
|
|
@ -4,8 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/client"
|
"github.com/derailed/k9s/internal/client"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
|
@ -231,16 +229,11 @@ func (d *Deployment) SetImages(ctx context.Context, path string, images map[stri
|
||||||
if !auth {
|
if !auth {
|
||||||
return fmt.Errorf("user is not authorized to patch a deployment")
|
return fmt.Errorf("user is not authorized to patch a deployment")
|
||||||
}
|
}
|
||||||
var nameStrB strings.Builder
|
|
||||||
var imageStrB strings.Builder
|
|
||||||
|
|
||||||
for name, image := range images {
|
jsonPatch, err := SetImageJsonPatch(images)
|
||||||
nameStrB.WriteString(fmt.Sprintf(`{"name":"%s"},`, name))
|
if err != nil {
|
||||||
imageStrB.WriteString(fmt.Sprintf(`{"image":"%s","name":"%s"},`, image, name))
|
return err
|
||||||
}
|
}
|
||||||
namesJson := strings.TrimSuffix(nameStrB.String(), ",")
|
|
||||||
imagesJson := strings.TrimSuffix(imageStrB.String(), ",")
|
|
||||||
patchJson := `{"spec":{"template":{"spec":{"$setElementOrder/containers":[` + namesJson + `],"containers":[` + imagesJson + `]}}}}`
|
|
||||||
dial, err := d.Client().Dial()
|
dial, err := d.Client().Dial()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -249,7 +242,7 @@ func (d *Deployment) SetImages(ctx context.Context, path string, images map[stri
|
||||||
ctx,
|
ctx,
|
||||||
n,
|
n,
|
||||||
types.StrategicMergePatchType,
|
types.StrategicMergePatchType,
|
||||||
[]byte(patchJson),
|
[]byte(jsonPatch),
|
||||||
metav1.PatchOptions{},
|
metav1.PatchOptions{},
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package dao
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
type JsonPatch struct {
|
||||||
|
Spec Spec `json:"spec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Spec struct {
|
||||||
|
Template Template `json:"template"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Template struct {
|
||||||
|
Spec ImagesSpec `json:"spec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImagesSpec struct {
|
||||||
|
SetElementOrders []Element `json:"$setElementOrder/containers"`
|
||||||
|
Containers []Element `json:"containers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Element struct {
|
||||||
|
Image string `json:"image,omitempty"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a json patch string to update PodSpec images
|
||||||
|
func SetImageJsonPatch(images map[string]string) (string, error) {
|
||||||
|
elementOrders := make([]Element, 0)
|
||||||
|
containers := make([]Element, 0)
|
||||||
|
for key, value := range images {
|
||||||
|
elementOrders = append(elementOrders, Element{Name: key})
|
||||||
|
containers = append(containers, Element{Name: key, Image: value})
|
||||||
|
}
|
||||||
|
jsonPatch := JsonPatch{
|
||||||
|
Spec: Spec{
|
||||||
|
Template: Template{
|
||||||
|
Spec: ImagesSpec{
|
||||||
|
SetElementOrders: elementOrders,
|
||||||
|
Containers: containers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
bytes, err := json.Marshal(jsonPatch)
|
||||||
|
return string(bytes), err
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSetImageJsonPatch(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
images map[string]string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "simple",
|
||||||
|
args: args{
|
||||||
|
images: map[string]string{"nginx": "nginx:latest"},
|
||||||
|
},
|
||||||
|
want: "",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := SetImageJsonPatch(tt.args.images)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("SetImageJsonPatch() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("SetImageJsonPatch() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue