AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1144338
Accepted
markfree
markfree
Asked: 2023-09-24 08:14:44 +0800 CST2023-09-24 08:14:44 +0800 CST 2023-09-24 08:14:44 +0800 CST

Ansible 变量寄存器在两个任务中之一或另一个

  • 772

我有一个 Ansible 角色来操作一些 Zabbix 组件。该角色具有这组任务来检查 Zabbix Agent 类型(1 或 2)和版本。

- name: Check if Zabbix Agent 2 is installed
  ansible.builtin.shell:
    cmd: which zabbix_agent2
  register: zabbix_agent2_installed
  ignore_errors: yes

- name: Check if Zabbix Agent D is installed
  ansible.builtin.shell:
    cmd: which zabbix_agentd
  when: not zabbix_agent2_installed.stdout
  register: zabbix_agentd_installed
  ignore_errors: yes

- name: Stop if there is no Agent installed
  ansible.builtin.fail:
    msg: |
      Zabbix Agent is not installed.
  when: not zabbix_agent2_installed.stdout and not zabbix_agentd_installed.stdout and zabbix_component == "agent"

- name: Fetch Zabbix Agent 2 version
  ansible.builtin.shell:
    cmd: zabbix_agent2 -V | grep "zabbix_agent" | cut -d' ' -f3
  when: zabbix_agent2_installed.stdout
  register: zabbix_agent_ver_old
  failed_when: zabbix_agent_ver_old.stderr

- name: Fetch Zabbix Agent D version
  ansible.builtin.shell:
    cmd: zabbix_agentd -V | grep "zabbix_agent" | cut -d' ' -f4
  when: not zabbix_agentd_installed.skipped
  register: zabbix_agent_ver_old
  failed_when: zabbix_agent_ver_old.stderr

当我运行剧本时,变量“zabbix_agentd_ver_old”在最后两个任务中以相同的名称注册了两次。即使最后一个任务被跳过,该变量也会被注册为已跳过。

TASK [zabbix_ansible : Check if Zabbix Agent 2 is installed] *********************************************************************
changed: [zbxproxy]

TASK [zabbix_ansible : Check if Zabbix Agent D is installed] *********************************************************************
skipping: [zbxproxy]

TASK [zabbix_ansible : Stop if there is no Agent installed] **********************************************************************
skipping: [zbxproxy]

TASK [zabbix_ansible : Fetch Zabbix Agent 2 version] *****************************************************************************
changed: [zbxproxy]

TASK [zabbix_ansible : Fetch Zabbix Agent D version] *******************************************************************************
skipping: [zbxproxy]

TASK [zabbix_ansible : ansible.builtin.debug] ************************************************************************************
ok: [zbxproxy] =>
  zabbix_agent_ver_old:
    changed: false
    skip_reason: Conditional result was False
    skipped: true

我想避免更改变量名称,因此我需要在最后两个任务之一中注册变量,而不是同时注册两个任务。

如果不满足最后一个任务的条件,如何完全跳过最后一个任务,包括注册?

ansible
  • 2 2 个回答
  • 75 Views

2 个回答

  • Voted
  1. John Mahowald
    2023-09-25T05:55:23+08:002023-09-25T05:55:23+08:00

    在 Ansible 中编写基于微小变化的多个任务分支很烦人,并且由于任务开销而运行缓慢。有时这可以折叠成一个带有变量的脚本。这是我用几行 shell 进行的快速而肮脏的尝试。免责声明:我没有用zabbix测试过,虽然一般概念并不难。

      - name: Fetch Zabbix Agent version
        register: zabbix_agent_ver_result
        shell:
          # Note use of YAML multiple line to embed script  http://yaml-multiline.info/
          # Although much longer should probably go in a separate file with and a script task
          cmd: |
            WHICHZAGENT=$(which zabbix_agent2 || which zabbix_agentd );
            case $WHICHZAGENT in
              *agent2 )
                   VERFIELD=3
                  ;;
              *agentd )
                   VERFIELD=4
                  ;;
            esac;
            ${WHICHZAGENT}  --version  | grep 'zabbix_agent' | cut -d' ' -f ${VERFIELD};
    
    
      - name: zabbix agent ver short name
        set_fact:
          zabbix_agent_ver: "{{ zabbix_agent_ver_result.stdout }}"
    
      - debug:
          var: zabbix_agent_ver
    
    

    注册:将覆盖存在的同名(主机范围)变量。这并不是说跳过的任务不返回任何内容,而是返回跳过的状态。这很令人困惑,我建议所有注册的任务变量名称都是唯一的。

    在 Ansible 任务中编写分支流并不像在许多编程语言中那样好。


    另请参阅:community.zabbix集合具有community.zabbix.zabbix_agent角色,具有不同的处理方式。从软件存储库安装代理包,然后安装模板配置文件,其中大多数可能的值可以来自变量。Ansible 非常常见的模式。

    就我个人而言,我更喜欢安装应该存在的软件包的风格。它可以修复丢失的代理,而且您不必弄清楚主机上有什么。

    • 1
  2. Best Answer
    Vladimir Botka
    2023-09-26T20:46:42+08:002023-09-26T20:46:42+08:00

    这是一个典型的定制事实案例。通过将可执行脚本zabbix.fact添加到远程主机上的/etc/ansible/facts.d来创建有关 Zabbix 的动态事实。

    以下脚本测试列表zabbix_agent_list中是否存在可执行文件,并返回 JSON 字典ansible_custom_zabix_agent以及存在的以逗号分隔的项目

    shell> cat zabbix.fact
    #!/bin/sh
    
    zabbix_agent_list="/usr/local/bin/zabbix_agentd \
                       /usr/local/bin/zabbix_agent2"
    
    zabbix_agent=""
    for a in $zabbix_agent_list; do
        if [ -x $a ]; then
            zabbix_agent="$zabbix_agent $a"
        fi
    done
    
    zabbix_agent=`echo $zabbix_agent | tr ' ' ','`
    echo '{"'ansible_custom_zabix_agent'"': '"'$zabbix_agent'"}'
    

    将此脚本分发到您想要提供此自定义事实的远程主机

    - hosts: all
    
      tasks:
    
        - file:
            state: directory
            dest: /etc/ansible/facts.d
    
        - copy:
            src: zabbix.fact
            dest: /etc/ansible/facts.d
            mode: '0755'
    

    测试一下。给定远程主机test_11和test_13

    shell> ssh admin@test_11 ls -1 /usr/local/bin/zabbix_agent2
    /usr/local/bin/zabbix_agent2
    
    shell> ssh admin@test_13 ls -1 /usr/local/bin/zabbix_agentd
    /usr/local/bin/zabbix_agentd
    

    下面播放

    - hosts: all
    
      vars:
    
        zabbix_agent: "{{ ansible_facts.ansible_local.zabbix.ansible_custom_zabix_agent|
                          default('')|
                          split(',')|
                          first }}"
      tasks:
    
        - setup:
            gather_subset: local
        - debug:
            var: ansible_facts.ansible_local.zabbix.ansible_custom_zabix_agent
        - debug:
            var: zabbix_agent
    

    给出(删节)

    ok: [test_11] => 
      zabbix_agent: /usr/local/bin/zabbix_agent2
    ok: [test_13] => 
      zabbix_agent: /usr/local/bin/zabbix_agentd
    

    笔记:

    • 默认情况下,每场比赛都会收集事实。在这种情况下,您不必运行任务设置。

    • 如果您禁用事实收集,或者如果您想刷新事实,请运行任务设置

    • 通过限制当地事实来加速事实收集。放gather_subset: local

    • 变量ansible_custom_zabix_agent将被追加到字典ansible_facts.ansible_local.zabbix.ansible_custom_zabix_agent

      • ansible_local:本地事实(gather_subset:local)

      • zabbix: zabbix.fact收集的事实

      • ansible_custom_zabix_agent:以逗号分隔的代理列表

    • 如果zabbix_agent_list列表中存在更多项目,则上面的例子中的变量ansible_custom_zabix_agent可能是逗号分隔项目的列表。在本例中,将字符串拆分为列表并获取第一项。

    • 您可以向脚本添加其他功能并返回其他事实。

    • 用户可以使用任何其他语言,例如Python,来编写脚本。


    Python 脚本示例

    shell> cat /etc/ansible/facts.d/apache.fact
    #!/usr/bin/env python3
    
    import shutil
    import subprocess
    import yaml
    import json
    
    
    def main():
    
        name = 'httpd'
    
        path = shutil.which(name)
        if path:
            result = subprocess.run([name, '-v'], capture_output=True, text=True)
            version = yaml.safe_load(result.stdout)
        else:
            version = None
    
        ansible_custom_facts = {
            'path': path,
            'version': version
        }
    
        print(json.dumps(ansible_custom_facts))
    
    
    if __name__ == '__main__':
        main()
    

    例如给出,

      ansible_facts.ansible_local:
        apache:
          path: /usr/local/sbin/httpd
          version:
            Server built: unknown
            Server version: Apache/2.4.46 (FreeBSD)
    
    • 0

相关问题

  • Ansible:将字符串转换为字典

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve