gpt4 book ai didi

go - 基于拆分字符串和键值对生成动态嵌套映射

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

我正在尝试根据返回项目接口(interface)的 API 调用生成值映射。{}我真的不确定如何更好地解释它,但这是我的情况。

我正在使用 Vault 来存储 secret ,这些 secret 将生成要在集群协调器中使用的动态映射。一个例子是:

secret /集群

secret /集群可以有无限嵌套的 secret ,例如

secret/cluster/team1/secreta/

secret/cluster/team2/secretb/app1/
secret/cluster/global

secret/cluster/team1/secreta 将具有表示 secret 的键值对

例如

secret/cluster/team1/secreta
username: user
password: pass
database: db1
secret/cluster/team1
checksum: xxxxx

我写了一个函数,它将遍历每个嵌套的集群并返回需要检查的每条路径的一部分:

func getChildSecrets(path string) []string {

for _, v := range vault.List(path) {
if strings.HasSuffix(v, "/") {
return append([]string{path}, getChildSecrets(fmt.Sprintf("%s%s", path, v))...)
}
}
return []string{path}
}

我的下一步是根据名称 secret 路径及其值设置一个map[string]interface{}:

map[cluster][team1][secreta]{username: user, password: pass, database:db1}
map[cluster][team1]{checksum:xxxx}

最佳答案

如果我对您的问题的理解正确,您是在尝试将 Vault 的路径转换为 ​​map[string]interface{}?这不会很有帮助,因为您将不得不在每次读取时执行类型断言。请注意,这是针对 Vault 的非常昂贵的 N^2 操作,您提出的算法可能会丢失数据,因为文件夹和叶子共享相同的名称是有效的。尽管如此,你去吧。我想您会发现它比您预期的要复杂得多:

package main

import (
"encoding/json"
"fmt"
"strings"

vault "github.com/hashicorp/vault/api"
)

func main() {
// Create a client object.
client, err := vault.NewClient(vault.DefaultConfig())
if err != nil {
panic(err)
}

// Convert everything at the path to a map. This will only work with KV v1.
m, err := SecretsToMap(client, "secret/")
if err != nil {
panic(err)
}

// Dump the result as JSON for easier viewing.
j, err := json.MarshalIndent(m, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s", j)
}

// SecretsToMap recursively reads all paths in the root and converts them to a
// map by each path segment.
func SecretsToMap(client *vault.Client, root string) (map[string]interface{}, error) {
var m = make(map[string]interface{})
if err := secretsToMap(client, m, root); err != nil {
return nil, err
}
return m, nil
}

func secretsToMap(client *vault.Client, m map[string]interface{}, root string) error {
// List everything at this path
r, err := client.Logical().List(root)
if err != nil {
return fmt.Errorf("failed to list %s: %s", root, err)
}

// Do nothing if the leaf is empty - this might be undesireable depending on
// your use case (you may want the empty leaf here with {}). Modify as
// appropriate.
if r == nil || len(r.Data) == 0 {
return nil
}

// Type conversions to get the response as []string.
keysRaw, ok := r.Data["keys"]
if !ok {
return nil
}
keys, ok := keysRaw.([]interface{})
if !ok {
return fmt.Errorf("%q is not []interface{}", keysRaw)
}
list := make([]string, len(keys))
for i, v := range keys {
str, ok := v.(string)
if !ok {
return fmt.Errorf("%q is not string", v)
}
list[i] = str
}

// Iterate over each response
for _, v := range list {
// pth is the full path (root + child)
pth := root + v

// If this is a folder, recurse.
if strings.HasSuffix(v, "/") {
if err := secretsToMap(client, m, pth); err != nil {
return err
}
} else {
// Not a folde,r read the secret, handing errors and nil/empty data
secret, err := client.Logical().Read(pth)
if err != nil {
return fmt.Errorf("failed to read secret %s: %s", pth, err)
}

// This might not be what you want - modify as appropriate.
if secret == nil || secret.Data == nil {
return nil
}

// Iterate over the folder parts and make a map entry if it does not
// exist. This will panic and fail if you have leafs and folders with the
// same name, but I'm just following your example.
ptr := m
for _, v := range strings.Split(root, "/") {
p := strings.Trim(v, "/")
if p == "" {
continue
}

// If there's no value at ptr (which is a moving target within the map),
// create a container for data.
if _, ok := ptr[p]; !ok {
ptr[p] = map[string]interface{}{}
}

// Advance the map pointer deeper into the map.
ptr = ptr[p].(map[string]interface{})
}

// We've reached the leaf, set the data.
ptr[v] = secret.Data
}
}

return nil
}

关于go - 基于拆分字符串和键值对生成动态嵌套映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57204930/

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