github.com/kubewharf/katalyst-core@v0.5.3/pkg/client/control/spd.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package control 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/types" 26 "k8s.io/apimachinery/pkg/util/strategicpatch" 27 28 apis "github.com/kubewharf/katalyst-api/pkg/apis/workload/v1alpha1" 29 clientset "github.com/kubewharf/katalyst-api/pkg/client/clientset/versioned" 30 "github.com/kubewharf/katalyst-core/pkg/util/general" 31 "github.com/kubewharf/katalyst-core/pkg/util/native" 32 ) 33 34 // ServiceProfileControl is used to update ServiceProfileDescriptor CR 35 // todo: use patch instead of update to avoid conflict 36 type ServiceProfileControl interface { 37 CreateSPD(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.CreateOptions) (*apis.ServiceProfileDescriptor, error) 38 UpdateSPD(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.UpdateOptions) (*apis.ServiceProfileDescriptor, error) 39 UpdateSPDStatus(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.UpdateOptions) (*apis.ServiceProfileDescriptor, error) 40 PatchSPD(ctx context.Context, oldSPD, newSPD *apis.ServiceProfileDescriptor) (*apis.ServiceProfileDescriptor, error) 41 DeleteSPD(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.DeleteOptions) error 42 } 43 44 type DummySPDControl struct{} 45 46 func (d *DummySPDControl) CreateSPD(_ context.Context, _ *apis.ServiceProfileDescriptor, _ metav1.CreateOptions) (*apis.ServiceProfileDescriptor, error) { 47 return nil, nil 48 } 49 50 func (d *DummySPDControl) UpdateSPD(_ context.Context, _ *apis.ServiceProfileDescriptor, _ metav1.UpdateOptions) (*apis.ServiceProfileDescriptor, error) { 51 return nil, nil 52 } 53 54 func (d *DummySPDControl) UpdateSPDStatus(_ context.Context, _ *apis.ServiceProfileDescriptor, _ metav1.UpdateOptions) (*apis.ServiceProfileDescriptor, error) { 55 return nil, nil 56 } 57 58 func (d *DummySPDControl) PatchSPD(_ context.Context, _, _ *apis.ServiceProfileDescriptor) (*apis.ServiceProfileDescriptor, error) { 59 return nil, nil 60 } 61 62 func (d *DummySPDControl) DeleteSPD(_ context.Context, _ *apis.ServiceProfileDescriptor, _ metav1.DeleteOptions) error { 63 return nil 64 } 65 66 type SPDControlImp struct { 67 client clientset.Interface 68 } 69 70 func NewSPDControlImp(client clientset.Interface) *SPDControlImp { 71 return &SPDControlImp{ 72 client: client, 73 } 74 } 75 76 func (r *SPDControlImp) CreateSPD(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.CreateOptions) (*apis.ServiceProfileDescriptor, error) { 77 if spd == nil { 78 return nil, fmt.Errorf("can't update a nil spd") 79 } 80 81 return r.client.WorkloadV1alpha1().ServiceProfileDescriptors(spd.Namespace).Create(ctx, spd, opts) 82 } 83 84 func (r *SPDControlImp) UpdateSPD(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.UpdateOptions) (*apis.ServiceProfileDescriptor, error) { 85 if spd == nil { 86 return nil, fmt.Errorf("can't update a nil spd") 87 } 88 89 return r.client.WorkloadV1alpha1().ServiceProfileDescriptors(spd.Namespace).Update(ctx, spd, opts) 90 } 91 92 func (r *SPDControlImp) UpdateSPDStatus(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.UpdateOptions) (*apis.ServiceProfileDescriptor, error) { 93 if spd == nil { 94 return nil, fmt.Errorf("can't update a nil spd's status") 95 } 96 97 return r.client.WorkloadV1alpha1().ServiceProfileDescriptors(spd.Namespace).UpdateStatus(ctx, spd, opts) 98 } 99 100 func (r *SPDControlImp) PatchSPD(ctx context.Context, oldSPD, newSPD *apis.ServiceProfileDescriptor) (*apis.ServiceProfileDescriptor, error) { 101 if oldSPD == nil || newSPD == nil { 102 return nil, fmt.Errorf("can't patch a nil spd") 103 } 104 105 oldData, err := json.Marshal(oldSPD) 106 if err != nil { 107 return nil, err 108 } 109 110 newData, err := json.Marshal(newSPD) 111 if err != nil { 112 return nil, err 113 } 114 115 patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, &apis.ServiceProfileDescriptor{}) 116 if err != nil { 117 return nil, fmt.Errorf("failed to create merge patch for spd %q: %v", native.GenerateUniqObjectNameKey(oldSPD), err) 118 } 119 if general.JsonPathEmpty(patchBytes) { 120 return oldSPD, nil 121 } 122 123 return r.client.WorkloadV1alpha1().ServiceProfileDescriptors(oldSPD.Namespace).Patch(ctx, oldSPD.Name, types.MergePatchType, patchBytes, metav1.PatchOptions{}) 124 } 125 126 func (r *SPDControlImp) DeleteSPD(ctx context.Context, spd *apis.ServiceProfileDescriptor, opts metav1.DeleteOptions) error { 127 if spd == nil { 128 return fmt.Errorf("can't delete a nil spd ") 129 } 130 131 return r.client.WorkloadV1alpha1().ServiceProfileDescriptors(spd.Namespace).Delete(ctx, spd.Name, opts) 132 }