当前位置: 首页 > 科技观察

要避免的七个YAML陷阱

时间:2023-03-21 23:42:48 科技观察

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