昨天遇到一个问题场景,我需要修改一个 ini 配置文件,ansible 的 ini_file 模块里需要定义 section, option 和 value 三个数据。
那么,我如何可以通过一个通用的变量数组,把数据套用到 ini 文件里呢?
假设我的 ini 文件内容是:
[log]
level = info
max_size = 100
[storage]
data_path = /mnt/data
log_path = /mnt/log
我写了一个 yaml 格式的字典,如下:
node_config_ini:
log:
level: warn
max_size: 200
storage:
data_path: /tmp/data
log_path: /tmp/log
摸索的过程就不详细写了,反正 ansible 的 loop 功能没有适合我的。于是我选择直接用 python 的嵌套循环来生成一个 list:
- hosts: localhost
gather_facts: false
vars:
node_config_ini:
log:
level: warn
max_size: 200
storage:
data_path: /tmp/data
log_path: /tmp/log
tasks:
- set_fact:
ini_items: "{{ item.split(';') }}"
with_items: >-
{%- for section in node_config_ini | dict2items -%}
{%- for option in section.value | dict2items -%}
{{ section.key }},{{ option.key }},{{ option.value }}
{%- if loop.nextitem is defined -%};{%- endif -%}
{%- endfor -%}
{%- if loop.nextitem is defined -%};{%- endif -%}
{%- endfor -%}
loop_control:
label: "{{ item.split(';') }}"
- debug:
msg: "{{ item.split(',') }}"
loop: "{{ ini_items }}"
set_fact 和 debug 打印出来的内容如下:
TASK [set_fact] *******************************************************************************
星期二 22 二月 2022 15:22:42 +0800 (0:00:00.055) 0:00:00.072 ****************
ok: [localhost] => (item=['log,level,warn', 'log,max_size,200', 'storage,data_path,/tmp/data', 'storage,log_path,/tmp/log'])
TASK [debug] *******************************************************************************
星期二 22 二月 2022 15:22:42 +0800 (0:00:00.057) 0:00:00.130 ****************
ok: [localhost] => (item=log,level,warn) => {
"msg": [
"log",
"level",
"warn"
]
}
ok: [localhost] => (item=log,max_size,200) => {
"msg": [
"log",
"max_size",
"200"
]
}
ok: [localhost] => (item=storage,data_path,/tmp/data) => {
"msg": [
"storage",
"data_path",
"/tmp/data"
]
}
ok: [localhost] => (item=storage,log_path,/tmp/log) => {
"msg": [
"storage",
"log_path",
"/tmp/log"
]
}
这样,我就可以再根据 ,
来分割数据,填入 ini 文件里,如下:
- ini_file:
path: /tmp/test.ini
create: true
section: "{{ item.split(',')[0] }}"
option: "{{ item.split(',')[1] }}"
value: "{{ item.split(',')[2] }}"
loop: "{{ ini_items }}"
顺利地把 ini 内容修改了:
cat /tmp/test.ini
[log]
level = warn
max_size = 200
[storage]
data_path = /tmp/data
log_path = /tmp/log