【问题标题】:How to iterate over a multi-document YAML file to pipe to a command?如何遍历多文档 YAML 文件以通过管道传输到命令?
【发布时间】:2021-08-24 01:58:08
【问题描述】:

我有一个命令生成一个秘密文件,其中包含多个由--- 分隔的yaml 文档,类似于以下输出:

## THE COMMAND THAT RUNS
kubectl kustomize .

## SENDS THE FOLLOWING TO STDOUT
data:
  firebase-dev-credentials.json: |
    MY_BASE_64_CREDENTIALS
kind: Secret
metadata:
  name: nodejs-firebase-credentials-989t6dg7m2
type: Opaque
---
apiVersion: v1
data:
  AGENDA_DATABASE_URL: |
    MY_BASE_64_URL
kind: Secret
metadata:
  name: nodejs-secrets-c229fkh579
type: Opaque

现在,我必须将yaml 文档传送到另一个命令进行处理,例如:

kubectl kustomize . | kubeseal

但是,kubeseal 命令不接受多文档yaml。所以我想我需要将yaml 拆分为--- 并将每个单独的文档发送到kubeseal 命令?

使用bash,完成此任务的首选方法是什么?

例如,我想我不能做这样简单的事情,因为 stdout 是多行的?

export IFS=";"
sentence="one;two;three"
for word in $sentence; do
  echo "$word"
done

【问题讨论】:

  • for item in $string 本身就是一种不当行为,主要是因为BashPitfalls #1 给出的原因是在相同的语法下不迭代lsfind。只有数组应该被迭代——依赖字符串拆分也会调用全局扩展。请注意,如果您愿意,您当然可以将文档插入到数组中。

标签: bash kubernetes yaml


【解决方案1】:

您可以通过yq eval 'select(di == N)' 选择文档N。但实际上,您不会这样做。您将在 Kustomize 配置中包含已经密封的数据,这不是您想要自动运行的东西。

【讨论】:

  • 我明白了,所以不要使用 kustomize 的 secretGenerator 功能来创建秘密 yaml,而是建议预先创建密封的秘密,然后将它们添加为 resources 中的 kustomization.yaml代替?
  • 没错,使用密封机密的全部原因是您可以安全地将加密表单提交到源代码控制。这意味着这需要是磁盘上的实际内容。
  • 是的!我仍然计划存储在源代码管理中。目标是通过kubeseal 命令将密封的机密信息存储在 SC 中。但是我遇到的问题是循环每个单独的秘密,因为kubeseal 不允许在 YAML 文件中使用多个秘密:/
  • 是的,第一次设置东西时会很烦人,但之后还不错。很久以前,我只是手动将它们分解成文件:)
【解决方案2】:

每隔一段时间,可能会有不同的解决方案,但一种方法是:

IFS="" # retain front tabs
buf=""
while read line
do
    if [ "$line" == "---" ]
    then
        echo -e $buf | kubeseal
        buf=""
    else
        if [ "$buf" == "" ] # prevent empty first newline
        then
            buf="$line"
        else
            buf=$(echo "$buf\\n$line")
        fi
    fi
done < yml

# get last section
echo -e $buf | kubeseal

【讨论】:

  • 使用echo -e $buf,这是用当前目录中的文件名列表替换*(尽管严格来说它是一行中的唯一输入,因为您清除了IFS),并替换了两个- 字符序列\n,带有单字符换行符;这些都不是可取的行为。
  • 另外,将-r 参数添加到read,这样您就不会在输入中吃掉文字反斜杠。
  • 真的,虽然echo 应该被完全删除并替换为printf 以避免在退出的过程中修改输入;参见unix.stackexchange.com/a/65819/3113——即使shell 100% 肯定是bash,编译时和(环境可继承的)运行时标志都可以使echo -e 在输出时打印-e;还有几个更严格符合 POSIX 标准的外壳开箱即用。
  • 例如,buf="$buf"$'\n'"$line" 将把$line 附加到$buf,而不需要替换命令(因此分叉子shell 对性能的影响很大);但它会更有效地写成buf+=$'\n'"$line"
  • @CharlesDuffy 感谢您提供详细的解释性反馈!
【解决方案3】:

如果仅使用bash 解析,

x="$(kubectl kustomize .)"
while [[ -n "$x" ]]
do ary+=("${x%%---*}")
if [[ "$x" =~ --- ]]; then x="${x#*---}"; else x=''; fi
done
for yml in "${ary[@]}"; do kubeseal<<<"$yml"; done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 2018-08-18
    相关资源
    最近更新 更多