无法使用 Python 将 AnsibleVault 正确转储到 yaml 中

Eri*_*ema 3 python yaml ansible ansible-vault

我有一个 python 字典,其中一个 AnsibleVault 作为值。我似乎无法将其正确转储到具有正确格式的 yaml 输出中。我正在使用该ansible-vault包生成加密数据,如下所示:

from ansible_vault import Vault
import yaml

vault = Vault('secretpassword')
data = "secretvalue"
Run Code Online (Sandbox Code Playgroud)

为了加密数据,我执行以下操作:

password = (vault.dump(data))
Run Code Online (Sandbox Code Playgroud)

这会生成正确的 AnsibleVault

$ANSIBLE_VAULT;1.1;AES256
36323830636261313833333932326661613063663361656362626432303232636463643030396366
3132623365633138613862333034626261336638613233650a653765386332666537613231626537
37666461653439616564343133656263613134643235363539396435616461626338393338616365
3339383030373532310a366662386665326132373535393930663737383136363735646361383066
65623033343262643138633839666237643735366465373932316233373339643835
Run Code Online (Sandbox Code Playgroud)

为了能够在保管库中使用它,我将以下内容附加到它:

$ANSIBLE_VAULT;1.1;AES256
36323830636261313833333932326661613063663361656362626432303232636463643030396366
3132623365633138613862333034626261336638613233650a653765386332666537613231626537
37666461653439616564343133656263613134643235363539396435616461626338393338616365
3339383030373532310a366662386665326132373535393930663737383136363735646361383066
65623033343262643138633839666237643735366465373932316233373339643835
Run Code Online (Sandbox Code Playgroud)

这样我就可以在 host_var 中使用它。然后我将它添加到带有其他一些值的字典中,然后我将使用 yaml 转储这些值。

password = "!vault |\n" + (vault.dump(data))
Run Code Online (Sandbox Code Playgroud)

直到这里一切看起来都很好,当我尝试将上面的字典输出到 yaml 输出时,事情就出了问题。

hostvar_dict = {
    "a": "1",
    "secret_item": password,
    "b": "2"
}
Run Code Online (Sandbox Code Playgroud)

给我以下输出:

print(yaml.dump(hostvar_dict))
Run Code Online (Sandbox Code Playgroud)

我查看了yaml.dump 的答案,在多行字符串中添加不需要的换行符,但这些没有给出正确的输出。我想要得到的是:

a: '1'
b: '2'
secret_item: '!vault |

  $ANSIBLE_VAULT;1.1;AES256

  36353763313938663936303630306161393433633765353936656139363937373365376563623937

  3762633462623434393036316264646535316233346166660a396634386439656437343162613365

  34613661366163643333393163333335343632356330343939396133333665336566623037306432

  3539366466353030310a313936376361366366316338636161303564346633373237363463373966

  39353731323564393365633465303663373932613631353364626437633561643134

  '
Run Code Online (Sandbox Code Playgroud)

我尝试过的 yaml.dump 选项有:default_style="|", default_flow_style=False

有没有办法按照我想要的方式正确地将 ansible-vault 值转储到 yaml 文件中?

Ant*_*hon 5

您预期的输出 YAML文档!vault中的 是一个标签。标签以感叹号开头,如果将字符串转储到以感叹号开头的 YAML,则需要将该字符串加引号。

类似地,竖线 ( |) 表示您想要一个字面样式标量,并将其包含在字符串中,不会得到这个结果。

我不知道你是否可以使用 PyYAML 做到这一点,但ruamel.yaml你可以这样做:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()

secret = ruamel.yaml.comments.TaggedScalar("""\
$ANSIBLE_VAULT;1.1;AES256
36353763313938663936303630306161393433633765353936656139363937373365376563623937
3762633462623434393036316264646535316233346166660a396634386439656437343162613365
34613661366163643333393163333335343632356330343939396133333665336566623037306432
3539366466353030310a313936376361366366316338636161303564346633373237363463373966
39353731323564393365633465303663373932613631353364626437633561643134
""", style='|', tag='!vault')

data = dict(a=1, b=2, secret_item=secret)
yaml.dump(data, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

这使:

a: 1
b: 2
secret_item: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  36353763313938663936303630306161393433633765353936656139363937373365376563623937
  3762633462623434393036316264646535316233346166660a396634386439656437343162613365
  34613661366163643333393163333335343632356330343939396133333665336566623037306432
  3539366466353030310a313936376361366366316338636161303564346633373237363463373966
  39353731323564393365633465303663373932613631353364626437633561643134
Run Code Online (Sandbox Code Playgroud)

如前所述,最好的办法是尝试往返您的预期输出。一旦明确ruamel.yaml可以保留布局,就可以分析加载的数据。在这种情况下,您将看到该键的值secret_item将是 a TaggedScalar