ansible - Ansible 和/或 Jinja2 中的子字符串

标签 ansible jinja2

我正在尝试取消挂载所有挂载点,除非它们属于当前列表的一部分:

excluded: ['home', 'cdrom', 'tmpfs', 'sys', 'run', 'dev', 'root']

仅限 fstab 的设备示例:

  • /dev/mapper/vgroot-local_home
  • devtmpfs
  • tmpfs

/dev/mapper/vgroot-local_home 应排除在卸载之外,因为子字符串 home 存在于数组中,对于 devtmpfs 也一样> 子字符串tmpfs。对于 tmpfs,我们有一个完美的匹配。目标是检查设备。

检查完所有Ansible filters后和 Jinja2 documentation ,我没有找到解决这个问题的方法。所有 Ansible 事实均已收集。

- name: Ensure the mountpoint is on the excluded list
  ansible.posix.mount:
    path: '{{ mount.device }}'
    state: unmounted
  when: {{ ??? }}
  with_items: '{{ ??? }}'
  become: true
  tags: mountpoints

最佳答案

为了测试 Jinja 中的字符串是否包含子字符串,我们使用 in 测试,就像 Python 一样:

"somestring" in somevariable

在您的情况下,您想要检查给定字符串是否包含排除列表中的任何子字符串。从概念上讲,我们想要的是类似 Python 表达式的东西

if any(x in mount.device for x in excluded)

使用 Jinja 过滤器,我们需要稍微颠倒我们的逻辑。我们 可以使用 select 过滤器从 给定目标字符串中包含的排除列表(例如 mount.device)像这样:

excluded|select('in', item)

如果itemexcluded列表中的任何内容匹配,则上面的内容 表达式将产生一个非空列表(其计算结果为true 当在 bool 上下文中使用时)。

在剧本中使用,它看起来像这样:

- hosts: localhost
  gather_facts: false
  vars:
    excluded: ['home', 'cdrom', 'tmpfs', 'sys', 'run', 'dev', 'root']
    mounts:
      - /dev/mapper/vgroot-local_home
      - devtmpfs
      - tmpfs
      - something/else
  tasks:
    - debug:
        msg: "unmount {{ item }}"
      when: not excluded|select('in', item)
      loop: "{{ mounts }}"

上面的剧本产生输出:

TASK [debug] *******************************************************************
skipping: [localhost] => (item=/dev/mapper/vgroot-local_home) 
skipping: [localhost] => (item=devtmpfs) 
skipping: [localhost] => (item=tmpfs) 
ok: [localhost] => (item=something/else) => {
    "msg": "unmount something/else"
}

也就是说,当当前循环项包含一个时,它会跳过任务 排除列表中的子字符串。

假设您的目标是“卸载除以下文件系统之外的所有文件系统” 其中设备名称包含排除列表中的子字符串”, 你可能会写:

- name: Unmount filesystems that aren't excluded
  ansible.posix.mount:
    path: '{{ mount.device }}'
    state: unmounted
  when: not excluded|select('in', item.device)
  loop: "{{ ansible_mounts }}"
  become: true
  tags: mountpoints

关于ansible - Ansible 和/或 Jinja2 中的子字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72346000/

相关文章:

python - 迭代器的自定义 jinja2 过滤器

python - 您如何调试 Mako 模板?

amazon-web-services - 如何通过 Ansible 向 AWS 安全组添加标签?

azure - 通过 SSH 对同一主机但不同端口上的 Azure VM 进行 Ansible 访问

ansible - 使用 Ansible Git 模块时如何传递用户名和密码?

python - Jinja2 简写条件

python - Python 中的科学报告

Ansible 错误地提示未引用的值

docker - 如何更改 elasticsearch docker 容器内目录的所有者权限?

jinja2 - 如果传入模板中不存在的变量,则会在jinja中引发异常