要避免的 7 个丑陋的 YAML 陷阱——以及如何避免它们



YAML(“YAML Ain't Markup Language”)配置语言是许多现代应用程序的核心,包括 Kubernetes、Ansible、CircleCI 和 Salt。毕竟,YAML 提供了许多优势,例如可读性、灵活性以及处理 JSON 文件的能力。但是对于没有经验或粗心的人来说,YAML 也是陷阱和陷阱的来源。
YAML 行为的许多方面都考虑到了暂时的便利,但代价是以后会出现意想不到的曲折或曲折。即使是具有丰富组装或部署 YAML 经验的人也可能会被这些问题所困扰,这些问题通常以看似无害的行为为幌子而浮出水面。 您可以采取以下七个步骤来防范 YAML 中最棘手的问题。
编写 YAML 时可以采用的最强大的防御实践:引用所有应为字符串的内容。 YAML 最著名的怪癖之一是您可以在不引用的情况下编写字符串: - movie:title: Blade Runner year: 1982 在本例中,键movie、title 和year 将被解释为字符串,值Blade Runner 也是如此。值 1982 将被解析为数字。
- 电影:片名:1979 年:2016 没错——电影片名将被解释为一个数字。这甚至还不是可能发生的最糟糕的事情: - 电影:标题:无年份:2012 这个标题被解释为布尔值的几率是多少? 如果您想绝对确保键和值将被解释为字符串,并防止任何潜在的歧义(很多歧义可能会潜入 YAML),请引用您的字符串: - "movie": "title": "Blade Runner" "year": 1982 如果由于某种原因无法引用字符串,可以使用速记前缀来指示类型。这些使 YAML 比引用的字符串读起来更嘈杂,但它们与引用一样明确: YAML 有多种方式来表示多行字符串,具体取决于这些字符串的格式。
例如,当前缀为 > 时,未加引号的字符串可以简单地跨多行断开: 长字符串: > 这是一个跨越多行的长字符串。请注意,使用 > 会自动在字符串末尾附加一个 \n。如果您不想要尾随的新行,请使用 >- 而不是 >。
如果使用带引号的字符串,则需要在每个换行符前加上反斜杠: 长字符串:“这是一个跨越多行的长字符串 \。”请注意,换行后的任何空格都被解释为 YAML 格式,而不是字符串的一部分。这就是为什么在上例中在反斜杠之前插入空格的原因。它确保单词字符串和不一起运行。 正如上面所暗示的,YAML 的另一个大问题之一是布尔值。在 YAML 中指定布尔值的方法有很多,因此很容易将预期的字符串解释为布尔值。
一个臭名昭著的例子是两位数的国家代码问题。如果您所在的国家/地区是美国或英国,则可以。如果你的国家是挪威,国家代码是 NO,那不再是一个字符串——它是一个布尔值,计算结果为 false! 在可能的情况下,有意明确地使用布尔值和可能被误解为布尔值的较短字符串。
YAML 的布尔值速记前缀是 !!bool。 这是一个不为人知的问题,但它可能很麻烦。 YAML 1.
1 使用与 YAML 1.2 不同的八进制数表示法。在 YAML 1.
1 中,八进制数看起来像 0777。在 YAML 1.2 中,相同的八进制数变成 0o777。
它不那么模棱两可了。 Kubernetes 是 YAML 的最大用户之一,它使用 YAML 1.1。
如果您将 YAML 与使用规范 1.2 版的其他应用程序一起使用,请特别注意不要使用错误的八进制表示法。由于如今八进制通常仅用于文件权限,因此与其他 YAML 陷阱相比,它是一个极端情况。
不过,如果您不小心,YAML 八进制可能会咬您一口。 可执行 YAML?是的。许多 YAML 库(例如 Python 的 PyYAML)允许在反序列化 YAML 时执行任意命令。
令人惊讶的是,这不是错误,而是 YAML 设计允许的功能。 在 PyYAML 的案例中,反序列化的默认行为最终被更改为仅支持 YAML 的一个安全子集,它不允许这种事情。可以手动恢复原始行为(有关如何执行此操作的详细信息,请参阅上面的链接),但您应该尽可能避免使用此功能,如果尚未禁用,则默认禁用它。
YAML 的另一个潜在问题是跨不同编程语言的不同 YAML 处理库有时会产生不同的结果。 考虑:如果您有一个包含表示为 true 和 false 的布尔值的 YAML 文件,并且您使用将布尔值表示为 y 和 n 或 on 和 off 的不同库将其重新序列化为 YAML,您可能会得到意想不到的结果。即使代码在功能上保持不变,它也可能看起来完全不同。
避免 YAML 问题的最通用方法是什么?不要使用它。或者至少,不要直接使用它。 如果您必须将 YAML 编写为配置过程的一部分,那么以 JSON 或本机代码(例如 Python 字典)编写代码会更安全,然后将其序列化为 YAML。您可以更好地控制对象的类型,并且可以更轻松地使用已经使用过的语言。
如果做不到这一点,您可以使用 yamllint 之类的 linter 来检查常见的 YAML 问题。例如,您可以禁止 YES 或 off 之类的真值,以支持简单的真假,或强制字符串引用..

Yorumlar

Bu blogdaki popüler yayınlar

只需50美元即可训练成为一名熟练的Python编码器

DataStax 使 Astra 流媒体服务普遍可用

TypeScript 4.1 Beta带来了模板文字类型