首页 > 解决方案 > 确保用户在 ansible 中只提供一个标签

问题描述

我编写了一本剧本,其行为与提供给剧本的标签不同。我已确保用户在运行剧本时至少向剧本提供标签。但是,我需要确保用户只向剧本提供一个标签。有可能吗?我在互联网上搜索过,但结果是否定的。

-->cat foo.yml

- hosts: localhost
  gather_facts: yes
  tasks:
    - name: Check user inputs
      fail: msg="ERROR:User must use ONE TAG"

    - name: print message A
      debug:
        msg: "This is message A"
      tags:
         - printA

    - name: print message B
      debug:
        msg: "This is message B"
      tags:
         - printB

工作:当提供一个标签时,应该工作。

ansible-playbook -i localhost foo.yml --tags="printA"
ansible-playbook -i localhost foo.yml --tags="printB"

工作:当没有提供标签时,失败并退出

ansible-playbook -i localhost foo.yml
fatal: [localhost]: FAILED! => {"changed": false, "msg": "ERROR:User must use ONE TAG"}

不确定如何执行此操作:提供多个标签的位置。失败并退出

ansible-playbook -i localhost foo.yml --tags="printB, printA"

更新:

这是来自@ilias-sp 答案的更新 PB:

---
- hosts: localhost
  gather_facts: yes
  tasks:
  tasks:
    - name: Check how many tags were provided
      fail:
        msg: "0 or more than 1 tags were provided. Exiting.."
      failed_when: hostvars['localhost']['ansible_run_tags']|length > 1 or
                   (hostvars['localhost']['ansible_run_tags']|length == 1 and hostvars['localhost']['ansible_run_tags'][0] == 'all')
      tags:
         - always
    - name: print message A
      debug:
        msg: "This is message A"
      tags:
         - printA

    - name: print message B
      debug:
        msg: "This is message B"
      tags:
         - printB

结果:

ansible-playbook foo.yml --tags="printA, printB"  # failing
ansible-playbook foo.yml --tags="printA"          #failing
ansible-playbook foo.yml                          #failing

错误:

TASK [Check how many tags were provided] *************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The conditional check 'hostvars['localhost']['ansible_run_tags']|length > 1 or (hostvars['localhost']['ansible_run_tags']|length == 1 and hostvars['localhost']['ansible_run_tags'][0] == 'all')' failed. The error was: error while evaluating conditional (hostvars['localhost']['ansible_run_tags']|length > 1 or (hostvars['localhost']['ansible_run_tags']|length == 1 and hostvars['localhost']['ansible_run_tags'][0] == 'all')): 'dict object' has no attribute 'ansible_run_tags'"}

标签: ansible

解决方案


您可以使用此fail模块任务检查 PB 中的标签,当您提供 0 个或多个标签时,它将使 PB 失败:

  - name: Check how many tags were provided
    fail:
      msg: "0 or more than 1 tags were provided. Exiting.."
    failed_when: hostvars['localhost']['ansible_run_tags']|length > 1 or
                 (hostvars['localhost']['ansible_run_tags']|length == 1 and hostvars['localhost']['ansible_run_tags'][0] == 'all')
    tags:
    - always

我测试过:

  • 0 个标签(在这种情况下,ansible_run_tags有 1 个元素all:)
  • 1 个标签
  • 超过 1 个标签

它按预期工作。希望能帮助到你

更新

样本 PB 和执行运行:

---
- hosts: localhost
  gather_facts: false
  vars:

  tasks:
  - name: Check how many tags were provided
    fail:
      msg: "0 or more than 1 tags were provided. Exiting.."
    failed_when: hostvars['localhost']['ansible_run_tags']|length > 1 or
                 (hostvars['localhost']['ansible_run_tags']|length == 1 and hostvars['localhost']['ansible_run_tags'][0] == 'all')
    tags:
    - always

  - name: print results
    debug:
      var: hostvars['localhost']['ansible_run_tags']
    tags:
    - always

3次运行:

[http_offline@greenhat-29 tests]$ ansible-playbook test.yml

PLAY [localhost] *******************************************************************************************************************************************************************************************************

TASK [Check how many tags were provided] *******************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed_when_result": true, "msg": "0 or more than 1 tags were provided. Exiting.."}

PLAY RECAP *************************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1   

[http_offline@greenhat-29 tests]$ ansible-playbook test.yml --tags="printA"

PLAY [localhost] *******************************************************************************************************************************************************************************************************

TASK [Check how many tags were provided] *******************************************************************************************************************************************************************************
ok: [localhost]

TASK [print results] ***************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "hostvars['localhost']['ansible_run_tags']": [
        "printA"
    ]
}

PLAY RECAP *************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

[http_offline@greenhat-29 tests]$ ansible-playbook test.yml --tags="printA, printB"

PLAY [localhost] *******************************************************************************************************************************************************************************************************

TASK [Check how many tags were provided] *******************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed_when_result": true, "msg": "0 or more than 1 tags were provided. Exiting.."}

PLAY RECAP *************************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1   

[http_offline@greenhat-29 tests]$ 

更新二:

此解决方案适用于 Ansible 2.7.X。像 2.4.X 这样的旧版本需要另一种方法 - 如果有的话


推荐阅读