Ansible:添加行同时保留修改

Ansible:添加行同时保留修改

我正在寻找一种修改配置文件并保留本地修改的方法。配置文件的格式类似于以下内容:

entry1: This is a local
entry2: modification.
entry3:

该文件由可变数量的键(entry1、entry2、entry3,以及可能稍后的entry4等 - 它可能最多为 100 个,将来甚至可能多达 2000 个左右)组成,这些键应由 Ansible 进行设置,然后是另一个程序将添加到配置文件中的附加选项。

我希望 Ansible 能够向文件添加新密钥,同时保留任何现有的本地修改。

最自然的选择似乎是 lineinfile - 但不幸的是,它只给了我任何一个保留本地修改(使用 backref=yes),或者添加新键(backref=yes 不会添加新行)。

有什么好方法可以实现我的需要吗?

我可以通过启用 lineinfile 和 backref 来修改现有条目:

- lineinfile:
  path: myfile.conf
  regexp: "^{{ item }}: (.*)"
  backref: yes
  line: "{{ item }}: \1"
  with_items:
    - entry1
    - entry2
    - entry3
    - entry4

但这不会将 entry4 添加到我的文件中。

或者我可以使用 backref: no

- lineinfile:
  path: myfile.conf
  regexp: "^{{ item }}: (.*)"
  backref: no
  line: "{{ item }}:"
  with_items:
    - entry1
    - entry2
    - entry3
    - entry4

但这会破坏entry1、entry2和entry3的本地修改。

或者我可以改变正则表达式:

- lineinfile:
  path: myfile.conf
  regexp: "^"
  backref: no
  line: "{{ item }}:"
  with_items:
    - entry1
    - entry2
    - entry3
    - entry4

但这当然会在每次运行时添加每个键。

我也研究过使用模板(但还没有找到一种简单的方法来用它来操作现有文件)。

当然我可以编写自己的 Python 模块,但是一定有更简单的方法来做到这一点?

答案1

如果您正在修改众所周知的配置文件,则可以使用 Augeas 和以下 ansible augeas 插件:https://github.com/paluh/ansible-augeas

这是如何使用 augeas 的一个示例:

- name: Force password on sudo group
  action: augeas path=/files/etc/sudoers/spec[user=\"sudo\"]/host_group/command/tag value=PASSWD

另一个选择是使用 lineinfile 命令来确保所需的行在文件中可用:http://docs.ansible.com/ansible/latest/lineinfile_module.html

例子:

- lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: 'SELINUX=enforcing'

答案2

我找到了一种方法来做到这一点。诀窍是首先使用 grep 仅查找缺失的条目。

如果文件不存在,grep 将出错,因此我首先创建该文件:

copy: dest: myfile.conf content: "" force: no # set mode, owner, group to taste

现在使用 grep 来查找缺失的项目。如果条目已经存在,Grep 将返回 0,如果不存在,则返回 1。通常,返回代码 1 表示 Ansible 失败。failed_when: True 会改变这种情况。由于这只是检索信息而不是更改任何内容,因此它永远不会报告为“已更改”,因此也需要设置changed_when。

command: 'grep "^{{ item }}" myfile.conf' with_items: - entry1 - entry2 - entry3 - entry4 failed_when: False changed_when: False register: grep_output

Grep 会将输出结果存入已注册的变量 grep_output。在循环中使用时,grep_output 将包含一个名为 results 的数组,其中包含循环中每个项目的哈希值。在该数组中,我们找到了所需的所有信息:返回代码(称为 rc)和循环中的原始项目(称为 item)。

现在我们可以通过检查 rc 来添加缺失的条目。我不确定这里是否需要正则表达式。

lineinfile: path: myfile.conf regexp: "^{{ item.item }} *(.*)" insertafter: EOF line: '{{ item.item }}' state: present when: "item.rc > 0" with_items: "{{ grep_output.results }}"

答案3

 lineinfile: path: myfile.conf regexp: "^{{ item }}: (.*)" backref: no line: "{{ item }}:" with_items: - entry1 - entry2 - entry3 - entry4

相关内容