RHCE(ansible语句)

  • RHCE(ansible语句)已关闭评论
  • 104 次浏览
  • A+
所属分类:linux技术
摘要

 说到底,还是有多个表达式来组成一个判断语句,很多种的判断语句有的时候play的结果需要依赖于变量,fact或者是前一个任务的执行结果,或者基于上一个task执行返回的结果而决定如何执行后续的task,这个时候就需要条件的判断了,一个很简单的案例,就是挂载磁盘,不需要到被控节点上面去看是否挂成功了,直接使用一个判断,看那个task任务的执行的结果,为0则代表着成功,就进行下一步的任务的执行


一:when语句

1:基础了解

 说到底,还是有多个表达式来组成一个判断语句,很多种的判断语句

1、 为什么需要判断语句:

有的时候play的结果需要依赖于变量,fact或者是前一个任务的执行结果,或者基于上一个task执行返回的结果而决定如何执行后续的task,这个时候就需要条件的判断了,一个很简单的案例,就是挂载磁盘,不需要到被控节点上面去看是否挂成功了,直接使用一个判断,看那个task任务的执行的结果,为0则代表着成功,就进行下一步的任务的执行

 2、使用场景

  1)目标主机上定义了一个硬限制,比如目标主机的最小内存必须达到多少,才能执行task任务

  2)捕获一个命令的输出,根据输出的结果不同来触发不同的task

  3)根据不同的目标主机的facts,来执行不同的tasks,如果是node1就是执行A任务,如果是node2就执行B任务

  等等等

3、when理解

当判断的结果是一致的话,那么执行task任务,否则的话,就跳过这个任务 

ansible中判断语句是when判断,默认when判断,就识别变量,所以的话,不需要使用"{{}}"来引用变量,when  inventory_hostname == 'node1'

还有一个点就是如果不使用变量的话,就只使用这个值的话,那么的话就要带上这个双引号,并且里面还要有单引号即可

when与模块的层级是一样的

 

2:判断的表达式

1:比较运算符

==  比较2边是否相等的,比较字符串和数字

!=  2边是否一致,不一致则为真

>=  比较大小,左边大于右边为真

<=  右边大于左边为真

>  左边大于右边为真

<  右边大于左边为真

案例:

判断运行的task任务的主机是不是node1,如果是的node1则执行任务,

判断主机的freemem大小是否大于1000,如果是的话,则执行任务

//通过facts变量来获取这个内存,然后通过魔法变量来获取这个node1 - name: memfree   hosts: node1   tasks:     - name: use when       debug:         msg: dayu1000       when: ansible_memtotal_mb > 1000     - name: node1       debug:         msg: hostname is node1       when: inventory_hostname == 'node1'

2:逻辑运算符

 

and 逻辑与,2边都为真,则返回真
or 逻辑或,有一个为真,则返回为真
not 逻辑否,对表达式取反,真为假,假为真,在表达式的前面写上
() 当一组的表达式组合在一起后,形成一个更大的表达式,组合内的所有表达式都是逻辑与的关系

案例:

#判断主机名为node1,ip地址为10,则打印hello rhce [root@controller mnt]# cat f4.yml  - name: use debug   hosts: node1   tasks:     - debug:         msg: hello rhce       when: inventory_hostname == 'node1' and ansible_ens160.ipv4.address == '172.25.250.11'  #判断主机名是否为node1或者ip地址是30的,则打印rhce [root@controller mnt]# cat f5.yaml  - name:   hosts: all   tasks:     - debug:        msg: rhce       when: inventory_hostname == 'node1' or ansible_ens160.ipv4.address == '172.25.250.30'  #使用not来进行判断,判断不是node1的主机即执行任务 应该放在最前面 - name: user kkk   hosts: all   tasks:     - name:       debug:         msg: hello       when: not ansible_hostname == 'node1'   #()的使用,主机名是node1并且ip地址是11或者系统是redhat,并且版本是9的则执行任务 ()里面是逻辑与的关系,多个表达式一起表达 [root@controller mnt]# cat f7.yml  - name: use debug   hosts: all   tasks:     - debug:         msg: hello rhce       when: (ansible_hostname == 'node1' and ansible_ens160.ipv4.address == '172.25.250.11') or (ansible_distribution_major_version == '9' and ansible_os_family == 'RedHat') 

3:根据rc的返回值来进行判断task任务是否执行成功

根据注册变量,这个能保存上一个tasks任务的执行信息,就是根据rc的值为0则表示执行成功,执行任务,不成功,执行另外的一个任务

[root@controller mnt]# cat f8.yml  - hosts: node1   tasks:     - shell: ls /etc/passsssss       register: get_status       ignore_errors: yes     - debug:        msg: rc is 0       when: get_status.rc == 0     - debug:        msg: rc is error       when: get_status.rc != 0 

4:通过条件判断路径是否存在

shell脚本也有这个使用test -f 路径,判断是否是一个文件,-d判断是否是一个目录,-e 路径,判断路径是否存在

ansible中,判断的格式如下

file:判断指定路径是否为一个文件,是则为真

directory:判断指定路径是否是一个目录,是则为真

link:判断指定路径是否为一个软连接,是则为真

mount:判断路径是否为挂载点,是则为真

exists:判断指定路径是否存在,存在则为真

使用when来进行判断 when "'/etc/passwd' is exists "

使用的关键字就是is

使用变量的值进行判断

#/etc/passwd存在的话,就执行任务 #when直接使用值的话需要使用双引号里面的值在加上单引号即可 [root@controller mnt]# cat f9.yaml  - hosts: all   tasks:     - debug:        msg: exist       when: "'/etc/passwd is exists'" 

5:通过判断tasks任务的执行结果(是对整个task任务进行判断)

ok:目标状态和期望值一致,没有发生变更

change或changed:目标发生变更,与期望值一样

sucess或succeeded:目标状态与期望值一样,或者任务执行成功了

failure或failed:任务失败

skip或skipped:任务跳过,注意,如果一个错误的任务使用ignore_errors忽略了这个错误,会跳过,但是实际上这个任务的执行是失败的,并没有跳过注意) 

案例:

#使用一个错误的任务,错误的结果就执行任务 - hosts: all   tasks:     - shell: ls /etc/passssss       register: get_status       ignore_errors: yes     - debug:        msg: is filed       when: get_status is failed     - debug:        msg: is skipped       when: get_status is skip  

6:通过对变量进行判断

defined:判断变量是否已定义了,定义了则返回真

undefined:判断变量是否未定义,未定义则返回真

none:判断变量的值是否为空,如果变量的已定义但是值为空的话,则返回真,定义了这个变量名,但是没有值

案例:

#定义一个变量,然后不给他的值,则执行任务 - hosts: node1   vars:     rhel:   tasks:     - debug:        msg: is none       when: rhel is none     - debug:        msg: is undefined       when: rhel is undefined  

7:通过字符串进行判断大小写字母

lower:判断字符串是否是小写字母

upper:判断字符串是否是大写字母

[root@controller mnt]# cat f12.yml  - hosts: node1   vars:     rhel: qqqq   tasks:     - debug:        msg: lower       when: rhel is lower   

8:通过数字来进行判断

even:判断数值是否为偶数,是则为真

odd:判断数值是否为奇数,,是则为真

divisibleby(num):判断是否可以整除指定的数值,是则为真

#判断能被2整除吗。是的话就执行任务 [root@controller mnt]# cat f12.yml  - hosts: node1   vars:     rhel: 10   tasks:     - debug:        msg: oushu       when: rhel is divisibleby(2) 

9:通过判断是否是子集或者是父集,in的判断

数字和字符都行

subset():判断一个list是不是另外一个list的子集,when:  a is subnet(b)

就是判断a是不是b的子集,就是a是不是被包含在b里面,小的

superset():判断一个list是不是另外一个list的父集;when: b is superset(a)

判断a是不是b的父集,就是a是不是包含b,大的

写法的话就是使用列表的形式来编写,不能使用字典的形式,会出现错误

案例:

[root@controller mnt]# cat f13.yml  - hosts: node1   vars:     f:       - qqq       - www     w:       - qqq   tasks:     - debug:        msg: fuji       when: f is superset(w)   

 判断字符串是否位于一个列表中的(非常重要的,经常使用的)

判断ens160网卡是不是在ansible_intreafces里面

[root@controller mnt]# cat f3.yml  - hosts: node1   tasks:     - debug:        msg: ens160 exists       when: "'ens160' in ansible_interfaces"

10:判断对象是否是字符串或者数字

string:判断是否是字符串

numbber:判断是否是数字

[root@controller mnt]# cat f14.yml  - hosts: node1   vars:     rhel: 9   tasks:     - debug:        msg: 9 is number       when: rhel is number

3:when判断和其他的关键字

1、block关键字

使用when判断的时候,每一个when判断只会判断一个task任务,如果有多个的话,就需要编写多次的,这样的话,代码就非常的多且不必要了

解决的方法就是: 

ansible通过block包裹多个tasks的任务,直接对block进行when判断,如果判断成功,则执行block中的所有tasks任务

通俗来讲就是block是一个块,把多个tasks任务作为一个整体,对block进行判断,如果成立则block中的tasks任务执行

案例:
创建一个文件,创建一个目录,然后对其进行判断,直接对这个block进行判断,判断主机名是node1执行

#上面所述就有2个tasks任务,如果使用when的话,要使用2次,使用block的话,直接对这个block这个整体进行判断,即能执行 block的层级是包裹这些任务的,然后when对这个block进行判断,成功,则执行这个任务 - name: use block   hosts: all   tasks:     - block:       - file:            path: /mnt/1.txt           state: touch       - file:           path: /mnt/1.dir           state: directory       when: inventory_hostname == 'node1' 

2、resuce关键字

层级与block一样的,错误拯救,对于block块的话,如果block中的任务执行失败,则会执行resuce下面的任务,如果没有失败的话,则不会触发resuce关键字下的task任务

- name: rescue   hosts: all   tasks:     - block:        - shell: ls /etc/p11111        - file:           path: /etc/passwd           state: file       rescue:         - debug:            msg: rescue       when: inventory_hostname == 'node1' 

3、always关键字

无论block任务执行成功还是失败,都要执行always关键字的中task任务

- name: rescue   hosts: all   tasks:     - block:        - shell: ls /etc/p11111        - file:           path: /etc/passwd           state: file       rescue:         - debug:            msg: rescue       always:          - debug:             msg: always       when: inventory_hostname == 'node1' 

4、fail和failed_when  

如果一个task任务执行失败的话,后面的task任务也没有必要执行,需要执行退出

就是挂载都没有挂上去,就不需要写yum仓库等等

案例:

- name: faile   hosts: node1   tasks:     - shell: ls /etc/lllll       ignore_errors: yes       register: get_status     - fail:           msg: juben exit       when: get_status.rc != 0     - debug:        msg: a  思路: 忽略了错误,继续像下面执行任务,本来要打印这个a的,使用了fail关键字,符合条件就退出这个剧本

failed_when:关键字

案例:

- name: faile   hosts: node1   tasks:     - shell: ls /etc/lllll       ignore_errors: yes       register: get_status     - debug:         msg: juben exit       failed_when: get_status.rc != 0     - debug:        msg: a

二:ansible循环语句

循环语句进行批量化的操作,创建用户,创建文件等

1:基于列表的循环(with_items)

不能使用对象(字典)的方式进行循环,会报错的,item固定的格式

2种写法 第一种,利用变量的形式 - name: item   hosts: node1   vars:     users:       - zhangsan       - lisi       - wangwu   tasks:     - debug:        msg: "{{item}}"       with_items: "{{users}}"  #with_items遍历users里面的元素  第二种写法: 直接在with_items后面写 - name: item   hosts: node1   tasks:     - debug:        msg: "{{item}}"       with_items:           - zhangsan          - lisi          - wangwu 但是这种方式不常用

2:基于字典的循环(with_dict)

就是键值对的方式来进行循环

- name: dict   hosts: node1   vars:     users:       q1:        uid: 2022        name: zhangsan       q2:        uid: 2023        name: lisi   tasks:     - debug:        msg: "{{item.value.name}}"       with_dict: "{{users}}"  ###输出的结果 ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhangsan'}}) => {     "msg": "zhangsan" } ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'lisi'}}) => {     "msg": "lisi" }   //思路 key是q1,value是uid,name,然后想要输出什么就以.连接

3:loop循环

天生是用来遍历列表的,但是也可以遍历字典,需要过滤器等

- name: loop   hosts: node1   vars:     users:       - zhangsan       - lisi       - wangwu   tasks:     - debug:        msg: "{{item}}"       loop: "{{users}}" 

 

过滤器等

 

三:总结

when判断有很多的方式来进行判断,facts变量,注册变量,in判断等等

还有几个关键字,block,rescue,always,fail,failed_when

循环语句,最常用的就是loop循环