pcm-kubernetes/internal/logic/applyyamllogic.go

108 lines
3.1 KiB
Go

package logic
import (
"bytes"
"context"
"fmt"
"gitlink.org.cn/jcce-pcm/pcm-participant-kubernetes/internal/svc"
"gitlink.org.cn/jcce-pcm/pcm-participant-kubernetes/kubernetes"
"gitlink.org.cn/jcce-pcm/utils/tool"
"io"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
syaml "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/yaml"
"github.com/zeromicro/go-zero/core/logx"
sigyaml "sigs.k8s.io/yaml"
)
type ApplyYamlLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewApplyYamlLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ApplyYamlLogic {
return &ApplyYamlLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *ApplyYamlLogic) ApplyYaml(in *kubernetes.ApplyReq) (*kubernetes.ApplyResp, error) {
// todo: add your logic here and delete this line
resp := &kubernetes.ApplyResp{
Code: "200",
Msg: "success",
}
d := yaml.NewYAMLOrJSONDecoder(bytes.NewBufferString(in.YamlString), 4096)
var err error
for {
var rawObj runtime.RawExtension
err = d.Decode(&rawObj)
if err == io.EOF {
break
}
if err != nil {
return nil, fmt.Errorf("decode is err %v", err)
}
obj := &unstructured.Unstructured{}
syaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme).Decode(rawObj.Raw, nil, obj)
if err != nil {
return nil, fmt.Errorf("rawobj is err%v", err)
}
unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil {
return nil, fmt.Errorf("tounstructured is err %v", err)
}
unstructureObj := &unstructured.Unstructured{Object: unstructuredMap}
gvr, err := tool.GetGVR(l.svcCtx.ClientSet, unstructureObj.GroupVersionKind())
if err != nil {
return nil, err
}
unstructuredYaml, err := sigyaml.Marshal(unstructureObj)
if err != nil {
return nil, fmt.Errorf("unable to marshal resource as yaml: %w", err)
}
if unstructureObj.GetNamespace() == "" {
unstructureObj.SetNamespace("default")
}
_, getErr := l.svcCtx.DynamicClient.Resource(gvr).Namespace(unstructureObj.GetNamespace()).Get(context.Background(), unstructureObj.GetName(), metav1.GetOptions{})
if getErr != nil {
_, createErr := l.svcCtx.DynamicClient.Resource(gvr).Namespace(unstructureObj.GetNamespace()).Create(context.Background(), unstructureObj, metav1.CreateOptions{})
if createErr != nil {
return nil, createErr
}
}
force := true
_, err = l.svcCtx.DynamicClient.Resource(gvr).
Namespace(unstructureObj.GetNamespace()).
Patch(context.Background(),
unstructureObj.GetName(),
types.ApplyPatchType,
unstructuredYaml, metav1.PatchOptions{
FieldManager: unstructureObj.GetName(),
Force: &force,
})
resp.DataSet = append(resp.DataSet, &kubernetes.DataSet{
ApiVersion: unstructureObj.GetAPIVersion(),
Kind: unstructureObj.GetKind(),
Namespace: unstructureObj.GetNamespace(),
Name: unstructureObj.GetName(),
})
if err != nil {
return nil, fmt.Errorf("unable to patch resource: %w", err)
}
}
return resp, nil
}