Ansible 数据标签为什么在字符串操作后丢失?何时使用 transform_to_native_types

Ansible 数据标签为什么在字符串操作后丢失?何时使用 transform_to_native_types Ansible 数据标签为什么在字符串操作后丢失何时使用 transform_to_native_types【免费下载链接】ansibleAnsible is a radically simple IT automation platform that makes your applications and systems easier to deploy and maintain. Automate everything from code deployment to network configuration to cloud management, in a language that approaches plain English, using SSH, with no agents to install on remote systems. https://docs.ansible.com.项目地址: https://gitcode.com/GitHub_Trending/ans/ansible如果你在 Ansible 控制器侧写代码自定义插件、内部工具或执行器逻辑处理的变量往往不是纯的str/dict/list而是带数据标签data tag的值。一个典型问题对这些值调用str.strip、to_text之类的字符串操作后得到的新值是一个没有标签的普通值原来的 origin、模板信任等元信息随之消失。本文基于仓库中的 context/data-tagging.md 及对应源码、单元测试说明标签为什么会在字符串操作后丢失、哪些情况必须去掉标签以及此时如何使用transform_to_native_types()。数据标签记录了什么仓库内部实现 lib/ansible/_internal/_datatag/_tags.py 定义了以下几种标签Origin记录值来源的元数据path、description、行号、列号docstring 明确说明它面向取证/诊断用途不保证一定存在或准确不应基于它做运行时判断VaultedValue打在 vault 加密字符串上携带原始密文以支持往返round-tripping。它的_get_tag_to_propagate只在新值与原值相等时才把标签传播过去防止标签被复制到一个不同的值上后被按原密文序列化TrustedAsTemplate表示该字符串可被信任地解析并渲染为模板。docstring 警告不要把它打到不可信来源的数据上否则等于允许模板渲染时注入代码SourceWasEncrypted仅内部使用表示值来自加密文件目前只由DataLoader相关文件读取路径打上。也就是说一个带标签的字符串除了字符串内容本身还携带来源与模板信任信息。字符串操作为什么丢掉标签context/data-tagging.md 的 How not to break things 一节直接给出了规则Avoid unnecessary mutation of values, such as callingstr.striporto_text, etc. as these will drop tags, losing things like origin and trust for templating.即避免不必要的值变更。str.strip、to_text这类调用会丢弃标签丢失的正是 origin 和模板信任trust这类信息。原因很直接它们返回的是一个新的原生值而标签挂在原值上不会自动跟过去。该文档接着给出两条操作准则默认不做 mutation能直接使用带标签的值就不要加工如果必须变更值要仔细考虑结果值需要传播哪些标签哪些需要、哪些不需要不能默认它们会保留。何时必须去掉标签transform_to_native_types同一篇文档的 When tags must be removed 一节划定了必须移除标签的边界有些 API 不认识带标签的类型也不会自动把它们当作未加标签的等价物处理包括三类接口执行精确类型检查exact type checks的 C 实现 Python API拒绝派生类型的序列化库serialization libraries任何消费方要求 plain 类型的接口。此时文档指定的做法是使用ansible.utils.vars中的transform_to_native_types()在把值交给上述 API 之前将其转为原生类型。该函数定义在 lib/ansible/utils/vars.py签名为def transform_to_native_types( value: object, redact: bool True, ) - t.Any: Recursively transform the given value to Python native types. Potentially sensitive values such as individually vaulted variables will be redacted unless redactFalse is passed. Which values are considered potentially sensitive may change in future releases. Types which cannot be converted to Python native types will result in an error. 按 docstring 和实现要点递归地把整个结构转换为 Python 原生类型键也会被转换实现中显式传入visit_keysTrueredact默认为True潜在敏感值例如单独 vault 加密的变量会被脱敏redact传redactFalse则不脱敏文档同时声明哪些值算潜在敏感可能随版本变化无法转换为原生类型的值会直接报错不会静默降级。仓库里就有一处真实用法lib/ansible/utils/jsonrpc.py 在把结果序列化返回前先做整体转换result to_text(pickle.dumps(transform_to_native_types(result, redactFalse)))这里pickle序列化正是要求 plain 类型的场景所以先用transform_to_native_types处理并传redactFalse使敏感值按解密后的明文形式参与序列化而不是被脱敏占位。如何验证转换行为仓库单元测试 test/units/utils/test_vars.py 提供了可直接参照的行为示例以下为文档示例摘自该测试from ansible._internal._datatag._tags import Origin from ansible.parsing.vault import EncryptedString from ansible.utils.vars import transform_to_native_types value { Origin(descriptionblah).tag(tagged_key): Origin(descriptionblah).tag(value with tagged key), # use a bogus EncryptedString instance with no VaultSecretsContext active; # ensures that transform with redaction does not attempt decryption redact_this: EncryptedString(ciphertextbogus), } result transform_to_native_types(value) assert result dict(tagged_keyvalue with tagged key, redact_thisredacted) assert all(type(key) is str for key in result.keys()) assert all(type(value) is str for value in result.values())这个示例验证了两点带标签的键和值都变成了原生str注意type(key) is str是精确类型检查而非isinstance在没有激活 vault 上下文的EncryptedString上默认redactTrue时不会尝试解密而是得到占位值redacted。如果要取回明文用redactFalse。同文件中的test_transform_to_native_types_unredacted测试通过VaultTestHelper.make_encrypted_string(hello)构造加密串并在_vault_secrets_contextfixture激活的 vault 秘密上下文下断言result dict(encplaintext)。这个路径依赖测试环境提供的 vault 上下文 fixture不能直接照搬进普通脚本。使用边界transform_to_native_types只用于值要交给不认标签的原生 API的场景不是通用字符串处理函数能带标签直接传递的值不要主动转一遍默认redactTrue会脱敏敏感值。调用方确实需要原始内容时才传redactFalse并记住哪些值算敏感的集合在文档声明中是可能变化的无法转换的类型会报错需要保证传入值都在可转换范围内Origin元数据只作诊断用途不保证存在和准确不要拿它做运行时判断。标签丢失的根源是字符串操作生成了新的原生值标签不会自动跟随。仓库文档给出的准则是不要不必要的 mutation必须变更时自己决定传播哪些标签而当你确实要把值交给只认原生类型的接口时先用transform_to_native_types做整体转换并根据调用方是否需要原始内容选择redact再用仓库自带单元测试中的断言方式核对转换结果。【免费下载链接】ansibleAnsible is a radically simple IT automation platform that makes your applications and systems easier to deploy and maintain. Automate everything from code deployment to network configuration to cloud management, in a language that approaches plain English, using SSH, with no agents to install on remote systems. https://docs.ansible.com.项目地址: https://gitcode.com/GitHub_Trending/ans/ansible创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考