Несогласованный отступ списка в файле Ansible/Yaml

У меня есть файл 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. Как я могу сохранить исходный отступ - смещение 0 для - name, но смещение 2 для всех остальных?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С 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' против 'wb').

Спасибо за подробную информацию. Вы добавили больше предложений, чем было задано, и я действительно ценю это.

Zafer Balkan 24.11.2022 11:00

Мне просто нужно добавить еще один комментарий. Так как я пытаюсь свести разницу к минимуму, необходимо yaml.preserve_quotes. В противном случае одинарные кавычки могут быть преобразованы в двойные кавычки во время дампа, даже если они используются при загрузке. Итак, в моем случае это необходимо как при чтении, так и при дампе.

Zafer Balkan 24.11.2022 13:09

Другие вопросы по теме