gpt4 book ai didi

json - 如何创建自定义 json 结构(ansible inventory)

转载 作者:数据小太阳 更新时间:2023-10-29 03:23:06 28 4
gpt4 key购买 nike

我正在从 cloudstack API listVirtualMachines 获取数据,并尝试创建一个将提供 dynamic ansible inventory 的 Web 服务对于某些主机。

在我的第一次尝试中,目前我正在通过连接请求获取所有数据,然后在一个循环中解析所有输出:

vms, _ := cs.Request(&cs.ListVirtualMachines{})

// use for the metadata _meta['hostvars']['IP']['key'] = val
hostvars := make(map[string]map[string]string)

// used per each host ['name']['hosts'] = [list]
hosts := make(map[string]map[string][]string)

for _, vm := range vms(*cs.ListVirtualMachinesResponse).VirtualMachine {
ip := vm.Nic[0].IPAddress.String()
if ip == "" {
continue
}
hostvars[ip] = map[string]string{
vm.DisplayName: vm.DisplayName,
"ansible_ssh_common_args": "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
}
if hosts[vm.DisplayName] == nil {
hosts[vm.DisplayName] = map[string][]string{}
}
hosts[vm.DisplayName]["hosts"] = append(hosts[vm.DisplayName]["hosts"], ip)
}

我想要的输出需要这种 JSON 格式:

{
"_meta": {
"hostvars": {
"172.16.0.3": {
"ansible_ssh_common_args": "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
"displayname": "server 1"
},
"172.16.0.4": {
"ansible_ssh_common_args": "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
"displayname": "server 2"
},
"172.16.0.5": {
"ansible_ssh_common_args": "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
"displayname": "server 3"
}
}
},
"group1": {
"hosts": [
"172.16.0.3",
"172.16.0.4",
"172.16.0.5"
]
},
"sandbox": {
"children": [
"server1",
"server2",
"server3"
]
},
"server1": {
"hosts": [
"172.16.0.3"
]
},
"server2": {
"hosts": [
"172.16.0.4"
]
},
"server3": {
"hosts": [
"172.16.0.5"
]
}
}

我的第一个尝试是创建一个巨大的 map :

inventory := map[string]map[string]map[string]string{}

但这只涵盖了 _meta 键的结构:

{
"_meta": {
"hostvars": {
"x.x.x.x": {
"key": "value"
},
"x.x.x.y": {
"key": "value"
}
}
}
}

后来我来了一个struct:

type Ansible struct {
Metadata Hostvars `json:"_meta"`
Hosts map[string]map[string][]string `json:",inline"` // want to remove the Hosts key
}

type Hostvars struct {
Hosts map[string]map[string]string `json:"hostvars"`
}

inventory := &Ansible{
Hostvars{hostvars},
hosts,
}


if err := json.NewEncoder(os.Stdout).Encode(inventory); err != nil {
log.Println(err)
}

这种方法的问题在于返回的 JSON 同时添加了键 _metahosts:

{
"_meta": {
"hostvars": {
"x.x.x.x": {
"key": "value"
},
"x.x.x.y": {
"key": "value"
}
}
},
"hosts": { <--- want to remove this
"server1": {
"hosts": [
"172.16.0.3"
]
}
...
}
}

我只想拥有 key _meta 并在同一级别(内联)为每个主机名拥有每个 key ,例如:

{
"_meta": {...},
"server1": {
"hosts": []
},
"group1": {
"hosts": []
},
"sandbox": {
"children": []
}
}

我猜测这可能可以通过 map[string]interface{} 来解决,也许这可以允许具有动态键名称/结构的动态 JSON 对象,不确切知道,因此,我们将不胜感激。

最佳答案

您最好的选择可能是让 Ansible 实现 json.Marshaler即时“扁平化”JSON 文档。

package main

import (
"encoding/json"
"fmt"
)

func main() {
a := &Ansible{
Metadata: Hostvars{
Hosts: map[string]map[string]string{
"172.16.0.3": map[string]string{
"displayname": "server 1",
},
},
},
Hosts: map[string]Group{
"group1": Group{Hosts: []string{"172.16.0.3", "172.16.0.4", "172.16.0.5"}},
"sandbox": Group{Children: []string{"server1", "server2", "server3"}},
"server1": Group{Hosts: []string{"172.16.0.3"}},
},
}

b, err := json.MarshalIndent(a, "", " ")
fmt.Println(string(b), err)
}

type Ansible struct {
Metadata Hostvars
Hosts map[string]Group
}

type Hostvars struct {
Hosts map[string]map[string]string `json:"hostvars"`
}

// I don't *think* Ansible supports anything else in host groups, so it makes
// sense to define it as a struct.
type Group struct {
Hosts []string `json:"hosts,omitempty"`
Children []string `json:"children,omitempty"`
}

// MarshalJSON implements json.Marshaler
func (a *Ansible) MarshalJSON() ([]byte, error) {
// Define a map that we will encode at the end of the function.
doc := make(map[string]interface{})

// Add all the groups.
for k, v := range a.Hosts {
doc[k] = v
}

// Add the _meta key.
doc["_meta"] = a.Metadata

return json.Marshal(doc)
}

在 Playground 上试试:https://play.golang.org/p/OKQHAG3vqIG

关于json - 如何创建自定义 json 结构(ansible inventory),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49783039/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com