我有一个Ansible YAML文件格式如下所示。注意- name和- when部件。
- name: populate package facts
package_facts:
- name: install auditd
apt:
name: auditd
state: present
register: apt_status
until: apt_status is success
retries: 12
delay: 10
- name: touch stig.rules
file:
path: /etc/audit/rules.d/stig.rules
state: touch
mode: '0640'
modification_time: preserve
access_time: preserve
# R-238197 UBTU-20-010002
- name: stigrule_238197__etc_gdm3_greeter_dconf_defaults_enable
ini_file:
path: /etc/gdm3/greeter.dconf-defaults
section: org/gnome/login-screen
option: banner-message-enable
value: "{{ ubuntu2004STIG_stigrule_238197__etc_gdm3_greeter_dconf_defaults_enable_Value }}"
no_extra_spaces: yes
notify: dconf_update
when:
- ubuntu2004STIG_stigrule_238197_Manage
- "'gdm3' in packages"我处理它并删除一些元素,然后使用下面的方法将其转储到文件中:
def dump(path: str, export: list) -> None:
yaml: YAML = YAML()
yaml.default_flow_style = False
yaml.preserve_quotes = True
yaml.width = 4096 # Prevent line breaks
yaml.indent(mapping=2, sequence=2, offset=0) # Default values
with open(path, "w", encoding=ENCODING) as fp:
yaml.dump(export, fp)对于默认缩进,结果如下所示:
- name: populate package facts
package_facts:
- name: install auditd
apt:
name: auditd
state: present
register: apt_status
until: apt_status is success
retries: 12
delay: 10
- name: touch stig.rules
file:
path: /etc/audit/rules.d/stig.rules
state: touch
mode: '0640'
modification_time: preserve
access_time: preserve
# R-238197 UBTU-20-010002
- name: stigrule_238197__etc_gdm3_greeter_dconf_defaults_enable
ini_file:
path: /etc/gdm3/greeter.dconf-defaults
section: org/gnome/login-screen
option: banner-message-enable
value: "{{ ubuntu2004STIG_stigrule_238197__etc_gdm3_greeter_dconf_defaults_enable_Value }}"
no_extra_spaces: yes
notify: dconf_update
when:
- ubuntu2004STIG_stigrule_238197_Manage
- "'gdm3' in packages"如您所见,Ansible文件已经是一个元素列表,从偏移量0开始。然后,- when之后的列表项也将使用该0偏移量值。如何将原始缩进-offset 0保存为- name,而对所有其他缩进保留2?
发布于 2022-11-23 19:39:53
使用ruamel.yaml,所有映射只能有一个缩进,所有序列只能有一个缩进。
如果要保留不一致性,则需要缩进4和偏移量2,并删除开始每一行的额外两个空格(有效地增加根级序列):
import sys
import ruamel.yaml
YAML = ruamel.yaml.YAML
from pathlib import Path
def dump(path: str, export: list) -> None:
def strip_first_two(s):
res = []
for x in s.splitlines(True):
xl = x.lstrip()
# do not dedent full comment lines
if xl and xl[0] == '#' or not x.startswith(' '):
res.append(x)
else:
res.append(x[2:])
return ''.join(res)
yaml: YAML = YAML()
yaml.default_flow_style = False # default
yaml.width = 4096 # Prevent line breaks
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.dump(export, Path(path), transform=strip_first_two)
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = yaml.load(Path('input.yaml'))
dump('output.yaml', data)
print(Path('output.yaml').read_text())这意味着:
- name: populate package facts
package_facts:
- name: install auditd
apt:
name: auditd
state: present
register: apt_status
until: apt_status is success
retries: 12
delay: 10
- name: touch stig.rules
file:
path: /etc/audit/rules.d/stig.rules
state: touch
mode: '0640'
modification_time: preserve
access_time: preserve
# R-238197 UBTU-20-010002
- name: stigrule_238197__etc_gdm3_greeter_dconf_defaults_enable
ini_file:
path: /etc/gdm3/greeter.dconf-defaults
section: org/gnome/login-screen
option: banner-message-enable
value: "{{ ubuntu2004STIG_stigrule_238197__etc_gdm3_greeter_dconf_defaults_enable_Value }}"
no_extra_spaces: yes
notify: dconf_update
when:
- ubuntu2004STIG_stigrule_238197_Manage
- "'gdm3' in packages"如果您有任何行尾注释,这些都会向左移动两个位置。如果您没有嵌入注释标记的多行标量,那么可以在strip_first_two中通过在每一行中用' #'替换' #'来轻松地处理这些问题。如果两者都有,这并不是那么简单,而且您必须在转储和调整每个EOL注释的每个开始列之前遍历数据结构。
设置yaml.default_flow_style = False不是必要的,因为这是往返转储的默认设置(另一方面,显式要比隐式好)。但是您不应该在您的yaml.preserve_quotes函数中对YAML实例设置dump,因为它只在加载YAML文档时才能工作,因此实际上可能会误导某人。
我还倾向于使用pathlib.Path实例,让ruamel.yaml在编码和打开方面做正确的事情('w‘vs 'wb')。
https://stackoverflow.com/questions/74551635
复制相似问题