为了账号安全,请及时绑定邮箱和手机立即绑定

更新特定的 yaml 属性

更新特定的 yaml 属性

Go
万千封印 2022-11-23 20:38:53

我试图解析一个 yaml 文件并只更新一个属性,问题是类型是RAW,当我更新一个字段时它会更新整个对象,


我想要的是仅更新 NatIPNamesfromtest1到test2,但不更改(10000)的值minPortsPerVM我该怎么做?


这是山药


apiVersion: core.gardener.cloud/v1beta1

kind: Shoot

metadata:

  name: test

  namespace: ns

spec:

  provider:

    type: aaa

    infrastructureConfig:

      apiVersion: gcp.provider.extensions.gardener.cloud/v1alpha1

      kind: InfrastructureConfig

      networks:

        cloudNAT:

          minPortsPerVM: 10000

          natIPNames:

            - name: test1

这是代码


package main


import (

    "encoding/json"

    "fmt"

    gcpv1alpha1 "github.com/gardener/gardener-extension-provider-gcp/pkg/apis/gcp/v1alpha1"

    "github.com/gardener/gardener/pkg/apis/core/v1beta1"

    "io/ioutil"

    "k8s.io/apimachinery/pkg/runtime"

    "k8s.io/apimachinery/pkg/util/yaml"

)


func main() {

    shoot, e := parseShoot("test.yaml")

    if e != nil {

        fmt.Println(e)

    }


    shoot.Spec.Provider.InfrastructureConfig.Raw = encode(&gcpv1alpha1.InfrastructureConfig{

        Networks: gcpv1alpha1.NetworkConfig{

            CloudNAT: &gcpv1alpha1.CloudNAT{

                //MinPortsPerVM: ,

                NatIPNames: []gcpv1alpha1.NatIPName{

                    {Name: "test2"},

                },

            },

        },

    })

    fmt.Println(shoot.Spec.Provider.InfrastructureConfig)

}


func parseShoot(path string) (*v1beta1.Shoot, error) {

    var shootSpec *v1beta1.Shoot

    bytes, err := ioutil.ReadFile(path)

    if err != nil {

        return nil, err

    }

    err = yaml.Unmarshal(bytes, &shootSpec)

    if err != nil {

        return nil, err

    }

    return shootSpec, nil

}


func encode(obj runtime.Object) []byte {

    data, _ := json.Marshal(obj)

    return data

}


查看完整描述

1 回答

?
茅侃侃

TA贡献1559条经验 获得超21个赞

我不太了解园丁的财产。但是您可以做的是为InfrastructureConfig下面的内容创建一个结构


type InfraConfig struct {

    APIVersion string `json:"apiVersion"`

    Kind       string `json:"kind"`

    Networks   struct {

        CloudNAT struct {

            MinPortsPerVM int `json:"minPortsPerVM"`

            NatIPNames    []struct {

                Name string `json:"name"`

            } `json:"natIPNames"`

        } `json:"cloudNAT"`

    } `json:"networks"`

}

并创建一个引用该对象的变量并将其解组Raw为如下所示。


    var existingInfraConfig InfraConfig

    err := json.Unmarshal(shoot.Spec.Provider.InfrastructureConfig.Raw, &existingInfraConfig)

然后您可以编辑名称(您可能想添加一些逻辑来验证切片以更新正确的索引)并将其编组并将其分配回 InfraConfig,如下所示。


    existingInfraConfig.Networks.CloudNAT.NatIPNames[0].Name = "test2"

    byteData, _ := json.Marshal(existingInfraConfig)


    shoot.Spec.Provider.InfrastructureConfig = &runtime.RawExtension{

        Raw:    byteData,

        Object: nil,

    }

总的来说,就像


package main


import (

    "encoding/json"

    "fmt"

    "github.com/gardener/gardener/pkg/apis/core/v1beta1"

    "io/ioutil"

    "k8s.io/apimachinery/pkg/runtime"

    "k8s.io/apimachinery/pkg/util/yaml"

)


type InfraConfig struct {

    APIVersion string `json:"apiVersion"`

    Kind       string `json:"kind"`

    Networks   struct {

        CloudNAT struct {

            MinPortsPerVM int `json:"minPortsPerVM"`

            NatIPNames    []struct {

                Name string `json:"name"`

            } `json:"natIPNames"`

        } `json:"cloudNAT"`

    } `json:"networks"`

}


func main() {

    shoot, e := parseShoot("test.yaml")

    if e != nil {

        fmt.Println(e)

    }


    var existingInfraConfig InfraConfig

    err := json.Unmarshal(shoot.Spec.Provider.InfrastructureConfig.Raw, &existingInfraConfig)

    fmt.Println(err)


    existingInfraConfig.Networks.CloudNAT.NatIPNames[0].Name = "test2"

    byteData, _ := json.Marshal(existingInfraConfig)


    shoot.Spec.Provider.InfrastructureConfig = &runtime.RawExtension{

        Raw:    byteData,

        Object: nil,

    }

    fmt.Println(string(shoot.Spec.Provider.InfrastructureConfig.Raw))


}


func parseShoot(path string) (*v1beta1.Shoot, error) {

    var shootSpec *v1beta1.Shoot

    bytes, err := ioutil.ReadFile(path)

    if err != nil {

        return nil, err

    }

    err = yaml.Unmarshal(bytes, &shootSpec)

    if err != nil {

        return nil, err

    }

    return shootSpec, nil

}


查看完整回答
反对 回复 2022-11-23

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信