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  }