PyYAML读取含!vault标签的YAML文件时找不到构造器如何解决?
问题原因
PyYAML的SafeLoader默认没有内置Ansible自定义的!vault标签构造器,遇到该标签时无法完成解析,因此抛出对应报错。
解决方案
根据是否需要解密!vault对应密文,可选择以下两种实现方式:
场景1:无需解密!vault内容,仅读取其他明文字段
只需给SafeLoader注册自定义的!vault标签构造器,直接将标签后的密文内容作为字符串返回即可,修改后代码如下:
import yaml from yaml.loader import SafeLoader # 自定义!vault标签的构造器 def vault_constructor(loader, node): # 直接返回!vault后面的密文字符串 return loader.construct_scalar(node) # 给SafeLoader注册!vault标签的构造器 yaml.add_constructor('!vault', vault_constructor, Loader=SafeLoader) with open('test.yml' ) as stream: try: inventory_info = yaml.safe_load(stream) except yaml.YAMLError as exc: print(exc) User = inventory_info['all']['children']['linux']['vars']['user'] key = inventory_info['all']['children']['linux']['vars']['key_file'] # 也可直接获取vault对应的密文字符串 vault_pwd = inventory_info['all']['children']['linux']['vars']['ansible_password']
场景2:需要解密!vault内容获取明文密码
如果需要直接解析出明文密码,需要借助Ansible官方库实现解密操作,首先安装依赖:pip install ansible
对应实现代码如下:
from ansible.parsing.vault import VaultLib, VaultSecret from ansible.module_utils.common.text.converters import to_bytes import yaml from yaml.loader import SafeLoader # 替换为加密该vault字段时使用的密码 VAULT_PASSWORD = "你的vault解密密码" def vault_constructor(loader, node): vault_text = loader.construct_scalar(node) # 初始化vault解密工具 vault = VaultLib(secrets=[('default', VaultSecret(_bytes=to_bytes(VAULT_PASSWORD)))]) # 解密返回明文 return vault.decrypt(vault_text) yaml.add_constructor('!vault', vault_constructor, Loader=SafeLoader) with open('test.yml' ) as stream: try: inventory_info = yaml.safe_load(stream) except yaml.YAMLError as exc: print(exc) User = inventory_info['all']['children']['linux']['vars']['user'] key = inventory_info['all']['children']['linux']['vars']['key_file'] # 此时获取到的就是解密后的明文密码 plain_pwd = inventory_info['all']['children']['linux']['vars']['ansible_password']
内容的提问来源于stack exchange,提问作者Eva
相关产品推荐
相关产品推荐

