英文:
How can I marshall a golang nested structs with YAML
问题
我如何表示这个结构的匹配标签部分以便打印出来。我尝试以类似于元数据的格式添加'NetworkPolicySpecPodSelector'结构,但我的格式是不正确的。
package main
import (
"fmt"
"io/ioutil"
"gopkg.in/yaml.v2"
)
type Metadata struct {
Name string `yaml:"name"`
Namespace string `yaml:"namespace"`
}
type Spec struct {
PodSelector NetworkPolicySpecPodSelector `yaml:"Spec"`
}
type NetworkPolicySpecPodSelector struct {
MatchLabels map[string][]string `yaml:"matchLabels"`
}
type Ingress struct {
}
type NetworkPolicy struct {
ApiVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata Metadata `yaml:"metadata"`
Spec struct {
PodSelector NetworkPolicySpecPodSelector
}
PolicyTypes []string `yaml:"policyTypes"`
}
func main() {
np := NetworkPolicy{
ApiVersion: "networking.k8s.io/v1",
Kind: "NetworkPolicy",
Metadata: Metadata{
Name: "allow-ingress",
Namespace: "default",
},
PolicyTypes: []string{"Ingress"},
}
np.Spec.PodSelector.MatchLabels = make(map[string][]string)
np.Spec.PodSelector.MatchLabels["env"] = []string{"prod"}
yamlData, err := yaml.Marshal(&np)
if err != nil {
fmt.Printf("Error while Marshaling. %v", err)
}
fileName := "test.yaml"
err = ioutil.WriteFile(fileName, yamlData, 0644)
if err != nil {
panic("Unable to write data into the file")
}
}
期望的输出是:
apiversion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress
namespace: default
spec:
podselector:
matchLabels:
env: prod
policyTypes:
- Ingress
目前还需要进一步完善,但我在这部分遇到了困难。项目的目标是使用YAML输出Kubernetes网络策略。
英文:
How do I represent the match labels section of this struct to print out.
I try to add the 'NetworkPolicySpecPodSelector' struct in a format like metadata but my format is incorrect.
package main
import (
"fmt"
"io/ioutil"
"gopkg.in/yaml.v2"
)
type Metadata struct {
Name string `yaml:"name"`
Namespace string `yaml:"namespace"`
}
type Spec struct {
PodSelector NetworkPolicySpecPodSelector `yaml:"Spec"`
}
type NetworkPolicySpecPodSelector struct {
MatchLabels map[string][]string `yaml:"matchLabels"`
}
type Ingress struct {
}
type NetworkPolicy struct {
ApiVersion string `yaml:"apiVersion`
Kind string `yaml:"kind"`
Metadata Metadata `yaml:"metadata"`
Spec struct {
PodSelector NetworkPolicySpecPodSelector
}
PolicyTypes []string `yaml:"policyTypes"`
}
func main() {
np := NetworkPolicy{
ApiVersion: "networking.k8s.io/v1",
Kind: "NetworkPolicy",
Metadata: Metadata{
Name: "allow-ingress",
Namespace: "default",
},
PolicyTypes: []string{"Ingress"},
}
yamlData, err := yaml.Marshal(&np)
if err != nil {
fmt.Printf("Error while Marshaling. %v", err)
}
fileName := "test.yaml"
err = ioutil.WriteFile(fileName, yamlData, 0644)
if err != nil {
panic("Unable to write data into the file")
}
}
My output is here:
apiversion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress
namespace: default
spec:
podselector:
matchLabels: {}
policyTypes:
- Ingress
Desired output:
apiversion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress
namespace: default
spec:
podselector:
matchLabels:
env:prod
policyTypes:
- Ingress
still needs to grow but Im struggling with this part. Goal of the project is to output a Kubernetes network policy using YAML.
答案1
得分: 0
首先,你需要修复结构字段标签,以反映你期望的结构。NetworkPolicy
中的 Spec
需要序列化为键 spec
,它的字段 PodSelector
应该是 podselector
:
type NetworkPolicy struct {
ApiVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata Metadata `yaml:"metadata"`
Spec Spec `yaml:"spec"`
PolicyTypes []string `yaml:"policyTypes"`
}
type Spec struct {
PodSelector NetworkPolicySpecPodSelector `yaml:"podselector"`
}
然后,你可以简单地使用字面量:
np := NetworkPolicy{
ApiVersion: "networking.k8s.io/v1",
Kind: "NetworkPolicy",
Metadata: Metadata{
Name: "allow-ingress",
Namespace: "default",
},
Spec: Spec{
PodSelector: NetworkPolicySpecPodSelector{
MatchLabels: map[string][]string{
"env": []string{"prod"},
},
},
},
PolicyTypes: []string{"Ingress"},
}
这是在 playground 上的完整示例:https://go.dev/play/p/xJ-mmCVcv2M
注意:在你的代码片段中,MatchLabels
的类型是 map[string][]string
。尽管从示例中看起来你想要的是 map[string]string
,但我保持了原样。
英文:
First you need to fix struct field tags to reflect your desired structure. Spec
in NetworkPolicy
needs to serialize as key spec
and its field PodSelector
as podselector
:
type NetworkPolicy struct {
ApiVersion string `yaml:"apiVersion`
Kind string `yaml:"kind"`
Metadata Metadata `yaml:"metadata"`
Spec Spec `yaml:"spec"`
PolicyTypes []string `yaml:"policyTypes"`
}
type Spec struct {
PodSelector NetworkPolicySpecPodSelector `yaml:"podselector"`
}
Then you can simply use literals:
np := NetworkPolicy{
ApiVersion: "networking.k8s.io/v1",
Kind: "NetworkPolicy",
Metadata: Metadata{
Name: "allow-ingress",
Namespace: "default",
},
Spec: Spec{
PodSelector: NetworkPolicySpecPodSelector{
MatchLabels: map[string][]string{
"env": []string{"prod"},
},
},
},
PolicyTypes: []string{"Ingress"},
}
Here is full example on playground: https://go.dev/play/p/xJ-mmCVcv2M
NOTE: In your code snippet the type of MatchLabels
is map[string][]string
. I kept it like that although from example it looks like you want map[string]string
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论