Ansible—— 33. playbook 条件判断

1. 单条件when
tasks:
  - name: "shut down Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Debian"
(当操作系统为debian时就执行关机操作)
---
- hosts: webserver
  user: admin
  become: yes
  vars:
    - username: user01
  tasks:
    - name: create {{ username }} user
      user: name={{ username }}
      when: ansible_fqdn == "node2.51yuki.cn"
2. 多条件when
---
- hosts: webserver
  user: admin
  become: yes
  tasks:
    - name: host 192.168.20.138 run this task
      debug: msg="{{ansible_default_ipv4.address}}"
      when: ansible_default_ipv4.address == "192.168.20.138"
    - name: all host run this task
      shell: hostname
      register: info
    - name: hostname is node2 run this task
      debug: msg="{{ansible_fqdn}}"
      when:  info['stdout']=="node2.51yuki.cn"
tasks:
  - name: "shut down CentOS 6 systems"
    command: /sbin/shutdown -t now
    when:
      - ansible_distribution == "CentOS"
      - ansible_distribution_major_version == "6"
3. when使用变量进行判断
vars:
  epic: true
tasks:
    - shell: echo "This certainly is epic!"
      when: epic
4. 与循环一起使用when
tasks:
    - command: echo {{ item }}
      with_items: [ 0, 2, 4, 6, 8, 10 ]
      when: item > 5
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{ item }}"
    with_items:
    - 1
    - 2
    - 3
    when: item > 1
5. 角色包含使用when
- include: tasks/sometasks.yml
  when: "'reticulating splines' in output"
- hosts: webservers
  roles:
     - { role: debian_stock_config, when: ansible_os_family == 'Debian' }
6. 关系、逻辑运算符
6.1 关系运算符
==  :比较两个对象是否相等,相等为真
!=  :比较两个对象是否不等,不等为真
>   :比较两个值的大小,如果左边的值大于右边的值,则为真
<  :比较两个值的大小,如果左边的值小于右边的值,则为真
>=  :比较两个值的大小,如果左边的值大于右边的值或左右相等,则为真
<=  :比较两个值的大小,如果左边的值小于右边的值或左右相等,则为真
我们总结的这些运算符其实都是jinja2的运算符,ansible使用jinja2模板引擎,在ansible中也可以直接使用jinja2的这些运算符。 
6.2 逻辑运算符
and  :逻辑与,当左边与右边同时为真,则返回真
or  :逻辑或,当左边与右边有任意一个为真,则返回真
not  :取反,对一个操作体取反
( )  :组合,将一组操作体包装在一起,形成一个较大的操作体
6.3 运算符操作示例
---
- hosts: test70
  remote_user: root
  tasks:
  - debug:
      msg: "System release is centos7"
    when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
---
- hosts: test70
  remote_user: root
  tasks:
  - debug:
      msg: "System release is centos7"
    when:
    - ansible_distribution == "CentOS"
    - ansible_distribution_major_version == "7"
---
- hosts: test70
  remote_user: root
  tasks:
  - debug:
      msg: "System release is centos6 or centos7"
    when: ansible_distribution == "CentOS" and
          (ansible_distribution_major_version == "6" or ansible_distribution_major_version == "7")
---
- hosts: test70
  remote_user: root
  tasks:
  - debug:
      msg: "System release is not centos"
    when: not ansible_distribution == "CentOS"

shell模块在远程主机test70中执行命令 “ls /testabc”,将shell模块的返回值注册到了变量returnmsg,然后通过returnmsg获取到了命令执行的返回码,如果返回码为 0,则证明命令完全正常执行,如果返回码不为0,则证明命令执行时出错了 。

---
- hosts: test70
  remote_user: root
  tasks:
  - name: task1
    shell: "ls /testabc"
    register: returnmsg
  - name: task2
    debug:
      msg: "Command execution successful"
    when: returnmsg.rc == 0
  - name: task3
    debug:
      msg: "Command execution failed"
    when: returnmsg.rc != 0

ignore_errors表示即使当前task执行报错,ansible也会忽略这个错误,继续执行playbook。

---
- hosts: test70
  remote_user: root
  tasks:
  - name: task1
    shell: "ls /testabc"
    register: returnmsg
    ignore_errors: true
  - name: task2
    debug:
      msg: "Command execution successful"
    when: returnmsg.rc == 0
  - name: task3
    debug:
      msg: "Command execution failed"
    when: returnmsg.rc != 0
7. is 运算符
---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testpath: /testdir
  tasks:
  - debug:
      msg: "file exist"
    when: testpath is exists
  vars:
    testpath: /testdir1
  tasks:
  - debug:
      msg: "file not exist"
    when: testpath is not exists
  vars:
    testpath: /testdir1
  tasks:
  - debug:
      msg: "file not exist"
    when: not testpath is exists

defined :判断变量是否已经定义,已经定义则返回真
undefind :判断变量是否已经定义,未定义则返回真
none :判断变量值是否为空,如果变量已经定义,但是变量值为空,则返回真

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testvar: "test"
    testvar1:
  tasks:
  - debug:
      msg: "Variable is defined"
    when: testvar is defined
  - debug:
      msg: "Variable is undefined"
    when: testvar2 is undefined
  - debug:
      msg: "The variable is defined, but there is no value"
    when: testvar1 is none

success 或 succeeded:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真
failure 或 failed:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真
change 或 changed:通过任务的返回信息判断任务的执行状态,任务执行状态为changed则返回真
skip 或 skipped:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    doshell: "yes"
  tasks:
  - shell: "cat /testdir/abc"
    when: doshell == "yes"
    register: returnmsg
    ignore_errors: true
  - debug:
      msg: "success"
    when: returnmsg is success
  - debug:
      msg: "failed"
    when: returnmsg is failure
  - debug:
      msg: "changed"
    when: returnmsg is change
  - debug:
      msg: "skip"
    when: returnmsg is skip

file : 判断路径是否是一个文件,如果路径是一个文件则返回真
directory :判断路径是否是一个目录,如果路径是一个目录则返回真
link :判断路径是否是一个软链接,如果路径是一个软链接则返回真
mount:判断路径是否是一个挂载点,如果路径是一个挂载点则返回真
exists:判断路径是否存在,如果路径存在则返回真
上述test名均为2.6版本中的名称,在2.5版本之前某些test需要加上"is_"前缀

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testpath1: "/testdir/test"
    testpath2: "/testdir/"
    testpath3: "/testdir/testsoftlink"
    testpath4: "/testdir/testhardlink"
    testpath5: "/boot"
  tasks:
  - debug:
      msg: "file"
    when: testpath1 is file
  - debug:
      msg: "directory"
    when: testpath2 is directory
  - debug:
      msg: "link"
    when: testpath3 is link
  - debug:
      msg: "link"
    when: testpath4 is link
  - debug:
      msg: "mount"
    when: testpath5 is mount
  - debug:
      msg: "exists"
    when: testpath1 is exists

lower:判断包含字母的字符串中的字母是否是纯小写,字符串中的字母全部为小写则返回真。
upper:判断包含字母的字符串中的字母是否是纯大写,字符串中的字母全部为大写则返回真。

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    str1: "abc"
    str2: "ABC"
  tasks:
  - debug:
      msg: "This string is all lowercase"
    when: str1 is lower
  - debug:
      msg: "This string is all uppercase"
    when: str2 is upper

even :判断数值是否是偶数,是偶数则返回真
odd :判断数值是否是奇数,是奇数则返回真
divisibleby(num) :判断是否可以整除指定的数值,如果除以指定的值以后余数为0,则返回真

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    num1: 4
    num2: 7
    num3: 64
  tasks:
  - debug:
      msg: "An even number"
    when: num1 is even
  - debug:
      msg: "An odd number"
    when: num2 is odd
  - debug:
      msg: "Can be divided exactly by"
    when: num3 is divisibleby(8)

version:可以用于对比两个版本号的大小,或者与指定的版本号进行对比,使用语法为 version(‘版本号’, ‘比较操作符’)。2.5版本中此tests从version_compare更名为version。

---
- hosts: test70
  remote_user: root
  vars:
    ver: 7.4.1708
    ver1: 7.4.1707
  tasks:
  - debug:
      msg: "This message can be displayed when the ver is greater than ver1"
    when: ver is version(ver1,">")
  - debug:
      msg: "system version {{ansible_distribution_version}} greater than 7.3"
    when: ansible_distribution_version is version("7.3","gt")

第一个task中,当ver的版本号大于ver1时,返回真,条件成立,debug模块输出"This message can be displayed when the ver is greater than ver1"
第二个task中,当facts中的ansible_distribution_version的值大于7.3时,返回真,条件成立,debug模块输出对应信息
">“与"gt"都表示"大于”,当使用version时,支持多种风格的比较操作符,version支持的比较操作符如下
大于:>, gt
大于等于:>=, ge
小于:<, lt
小于等于:<=, le
等于: ==, =, eq
不等于:!=, <>, ne
subset:判断一个list是不是另一个list的子集,是另一个list的子集时返回真。
superset : 判断一个list是不是另一个list的父集,是另一个list的父集时返回真。
2.5版本中上述两个tests从issubset和issuperset更名为subset和superset。

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    a:
    - 2
    - 5
    b: [1,2,3,4,5]
  tasks:
  - debug:
      msg: "A is a subset of B"
    when: a is subset(b)
  - debug:
      msg: "B is the parent set of A"
    when: b is superset(a)

string:判断对象是否是一个字符串,是字符串则返回真。

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testvar1: 1
    testvar2: "1"
    testvar3: a
  tasks:
  - debug:
      msg: "This variable is a string"
    when: testvar1 is string
  - debug:
      msg: "This variable is a string"
    when: testvar2 is string
  - debug:
      msg: "This variable is a string"
    when: testvar3 is string

number:判断对象是否是一个数字,是数字则返回真。

---
- hosts: test70
  remote_user: root
  gather_facts: no
  vars:
    testvar1: 1
    testvar2: "1"
    testvar3: 00.20
  tasks:
  - debug:
      msg: "This variable is number"
    when: testvar1 is number
  - debug:
      msg: "This variable is a number"
    when: testvar2 is number
  - debug:
      msg: "This variable is a number"
    when: testvar3 is number
8. block

使用"block"关键字将多个任务整合成一个"块",这个"块"将被当做一个整体,我们可以对这个"块"添加判断条件,当条件成立时,则执行这个块中的所有任务。

---
- hosts: test70
  remote_user: root
  tasks:
  - debug:
      msg: "task1 not in block"
  - block:
      - debug:
          msg: "task2 in block1"
      - debug:
          msg: "task3 in block1"
    when: 2 > 1

"错误处理"功能就是当某任务出错时,执行指定的其他任务,打个比方,想要在A任务执行失败时执行B任务,如果A任务执行成功,则无需执行B任 务,实现这个功能,就能够使用block,当然,还有一些别的方法,也可以实现类似的功能,比如前文中提到的jinja2的tests,有个一名为 failed的test,借助failed也可以实现类似的功能。

---
- hosts: test70
  remote_user: root
  tasks:
  - shell: 'ls /ooo'
    register: return_value
    ignore_errors: true
  - debug:
      msg: "I cought an error"
    when: return_value is failed

除了block关键字,还有另外一个关键字rescue,rescue关键字与block关键字对齐,rescue的字面意思为"救 援",表示当block中的任务执行失败时,会执行rescue中的任务进行补救,当block中的任务顺利执行时,则不会执行rescue中的任务。

---
- hosts: test70
  remote_user: root
  tasks:
  - block:
      - shell: 'ls /ooo'
    rescue:
      - debug:
          msg: 'I caught an error'

block中有三个任务,这三个任务中的任何一个任务出错,都会执行rescue中的任务,所以通常,我们会使用block和 rescue结合,完成"错误捕捉,报出异常"的功能,其实,不仅block中可以有多个任务,rescue中也可以定义多个任务,当block中的任何 一个任务出错时,会按照顺序执行rescue中的任务。

---
- hosts: test70
  remote_user: root
  tasks:
  - block:
      - shell: 'ls /opt'
      - shell: 'ls /testdir'
      - shell: 'ls /c'
    rescue:
      - debug:
          msg: 'I caught an error'

加入always关键字以后,无论block中的任务执行成功还是失败,always中的任务都会被执行。

---
- hosts: test70
  remote_user: root
  tasks:
  - block:
      - debug:
          msg: 'I execute normally'
      - command: /bin/false
      - debug:
          msg: 'I never execute, due to the above task failing'
    rescue:
      - debug:
          msg: 'I caught an error'
      - command: /bin/false
      - debug:
          msg: 'I also never execute'
    always:
      - debug:
          msg: "This always executes"

block中有多个任务,rescue中也有多个任务,上例中故意执行"/bin/false"命令,模拟任务出错的情况,当 block中的’/bin/false’执行后,其后的debug任务将不会被执行,因为’/bin/false’模拟出错,出错后直接执行rescue 中的任务,在执行rescue中的任务时,会先输出 ‘I caught an error’,然后又在rescue中使用’/bin/false’模拟出错的情况,出错后之后的debug任务不会被执行,直接执行always中的任 务,always中的任务一定会被执行,无论block中的任务是否出错。

————Blueicex 2020/3/28 11:13 blueice1980@126.com

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值