Ansible——lookup,过滤器

文章目录

  • Ansible——lookup,过滤器
    • lookup读取文件
    • lookup生成随机密码
    • lookup读取环境变量
    • lookup读取Linux命令的执行结果
    • lookup读取template变量替换后的文件
    • lookup读取配置文件
    • lookup读取DNS解析的值
  • 过滤器
    • 过滤器使用的位置
    • 过滤器对普通变量的操作
    • 过滤器对文件路径的操作
    • 过滤器对字符串变量的操作
    • 过滤器对JSON的操作
    • 过滤器对数据结构的操作
    • 过滤器的链式/连续使用
  • 常见插件类型

Ansible——lookup,过滤器

Ansible Playbook允许用户使用自定义变量,不过当变量过大,或者太复杂时,无论是在Playbook中通过vars定义,还是在单独的变量文件中定义,可读性都比较差

lookup能够读取Ansible管理节点上文件系统的文件内容到Ansible变量中,也可以读取配置的数据库中的内容

lookup读取文件

下面是lookup基本使用方法,将Ansible管理节点上的文件data/plain.txt的内容读取出来,并赋值给变量"contents"。"file"告诉lookup读取对象的类型是File,直接读取文件内容,无须做特别的处理

[root@csq ~]# mkdir data
[root@csq ~]# echo "csqcsqcsq" > data/plain.txt
[root@csq ~]# vim test.yml 
- hosts: allremote_user: rootgather_facts: falsevars:contents: "{{ lookup('file','/root/data/plain.txt') }}"tasks:- debug: msg="the value of /root/data/plain.txt is {{ contents }}"# 执行结果
TASK [debug] **********************************************************************************
ok: [192.168.200.20] => {"msg": "the value of /root/data/plain.txt is csqcsqcsq"
}
ok: [192.168.200.30] => {"msg": "the value of /root/data/plain.txt is csqcsqcsq"
}

lookup生成随机密码

如果密码文件/tmp/password/kitty不存在,lookup会生成长度为5的随机密码,存储在文件中。如果密码文件存在,那么直接读取该文件中的内容作为密码

[root@csq ~]# vim a.yml 
- hosts: allremote_user: rootvars:password: "{{ lookup('password','/tmp/password/kitty length=5') }}"tasks:- debug: var=password# 执行结果
TASK [debug] **********************************************************************************
ok: [192.168.200.20] => {"password": "TWLDK"
}
ok: [192.168.200.30] => {"password": "TWLDK"
}

lookup读取环境变量

env类型的lookup可以读取Linux上的环境变量

[root@csq ~]# vim c.yml              tasks:
- hosts: testremote_user: roottasks:- name: envdebug: msg=" {{lookup('env','HOME') }} 是一个环境变量"# 执行结果
[root@csq ~]# ansible-playbook c.yml PLAY [test] *************************************************************************************************************************TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.20]TASK [env] **************************************************************************************************************************
ok: [192.168.200.20] => {"msg": " /root 是一个环境变量"
}PLAY RECAP **************************************************************************************************************************
192.168.200.20             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

lookup读取Linux命令的执行结果

pipe类型的lookup可以将Linux上命令的执行结果读取到Ansible中

[root@csq ~]# vim d.yml         
- hosts: allremote_user: roottasks:- name: 读取管理节点的Linux命令执行结果debug: msg="{{ lookup('pipe','date') }} 这是该命令执行的结果"# 执行结果
[root@csq ~]# ansible-playbook d.yml PLAY [all] **************************************************************************************************************************TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.30]
ok: [192.168.200.20]TASK [读取管理节点的Linux命令执行结果] **********************************************************************************************
ok: [192.168.200.20] => {"msg": "2024年 05月 02日 星期四 11:42:35 CST 这是该命令执行的结果"
}
ok: [192.168.200.30] => {"msg": "2024年 05月 02日 星期四 11:42:35 CST 这是该命令执行的结果"
}PLAY RECAP **************************************************************************************************************************
192.168.200.20             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.30             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

lookup读取template变量替换后的文件

template类型的lookup可以将一个template文件经过变量替换后的内容读取到Ansible中。如果在template文件中有未定义的变量,则会报错

# template文件
[root@csq ~]# vim template1.j2            
hostname: {{ansible_hostname}}# playbook文件
[root@csq ~]# vim e.yml              
- hosts: allremote_user: roottasks:- name: 读取templatedebug: msg="{{ lookup('template','/root/template1.j2') }} 这是template.j2的变量"# 执行结果
[root@csq ~]# ansible-playbook e.yml PLAY [all] **************************************************************************************************************************TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.30]
ok: [192.168.200.20]TASK [读取template] *****************************************************************************************************************
ok: [192.168.200.20] => {"msg": "hostname: podman\n 这是template.j2的变量"
}
ok: [192.168.200.30] => {"msg": "hostname: localhost\n 这是template.j2的变量"
}PLAY RECAP **************************************************************************************************************************
192.168.200.20             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.200.30             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

lookup读取配置文件

lookup支持读取两种类型的配置文件;ini和java的properties

ini类型的lookup默认读取配置文件类型是ini

# ini文件
[root@csq ~]# vim data/users.ini 
[test1]
user=csq
password=111
[test2]
user=zhw
password=000# playbook文件
[root@csq ~]# vim f.yml- name:
- hosts: testremote_user: roottasks:- debug:msg: "test1 user = {{ lookup('ini','user section=test1 file=/root/data/users.ini') }}"- debug:msg: "test2 user = {{ lookup('ini','user section=test2 file=/root/data/users.ini') }}"
# 执行结果
[root@csq ~]# ansible-playbook  f.yml PLAY [test] *************************************************************************************************************************TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.20]TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "test1 user = csq"
}TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "test2 user = zhw"
}PLAY RECAP **************************************************************************************************************************
192.168.200.20             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

读取properties类型文件时,需要加一个额外的参数来告诉lookup,这是properties类型的文件

# user.properties文件
[root@csq ~]# vim data/user.properties
user.name=csq
user.pass=111# playbook文件
[root@csq ~]# vim g.yml- name: dd
- hosts: testremote_user: roottasks:- debug:msg: "user.name is {{ lookup('ini','user.name type=properties file=/root/data/user.properties') }}"# 执行结果
[root@csq ~]# ansible-playbook g.yml PLAY [test] *************************************************************************************************************************TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.20]TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "user.name is csq"
}PLAY RECAP **************************************************************************************************************************
192.168.200.20             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

ini类型参数格式:

lookup('ini','key [type=<properties|ini>] [section=section] [file=file.ini] [re=true] [default=<defaultvalue>]')
# 每个参数都是可选的,没有传入的参数会使用默认值
参数名默认值参数含义
typeini文件的类型
fileansible.ini加载文件的名字
sectionglobal默认的在哪个section里面查找key
reFalsekey的正则表达式
defaultempty stringkey不存在时的返回值

lookup读取DNS解析的值

dig类型的lookup可以向DNS服务器查询指定域名的DNS记录。它可以查询任何DNS记录,包括正向反向查询

使用dig类型的lookup查询DNS,使用正向反向查询DNS解析,还可以指定查询的DNS服务器

# 首先安装dnspython因为需要用到这个Python库
[root@localhost ansible]# pip3.11 install dnspython
# 剧本文件
[root@localhost ansible]# vim test7.yml              
- hosts: testremote_user: rootgather_facts: falsetasks:- debug: msg="这是baidu.com的ipv4地址:{{lookup('dig','baidu.com')}}"- debug: msg="这是baidu.com的TXT记录:{{lookup('dig','baidu.com','qtype=TXT')}}"- debug: msg="这是baidu.com的TXT记录:{{lookup('dig','baidu.com./TXT')}}"- debug: msg="163.com的mx记录之一是:{{item}}"with_items: "{{lookup('dig','163.com./MX','wantlist=True')}}"
# 执行剧本
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "这是baidu.com的ipv4地址:110.242.68.66,39.156.66.10"
}TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "这是baidu.com的TXT记录:9279nznttl321bxp1j464rd9vpps246v,v=spf1 include:spf1.baidu.com include:spf2.baidu.com include:spf3.baidu.com include:spf4.baidu.com mx ptr -all,google-site-verification=GHb98-6msqyx_qqjGl5eRatD3QTHyVB6-xQ3gJB5UwM,_globalsign-domain-verification=qjb28W2jJSrWj04NHpB0CvgK9tle5JkOq-EcyWBgnE"
}TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "这是baidu.com的TXT记录:9279nznttl321bxp1j464rd9vpps246v,v=spf1 include:spf1.baidu.com include:spf2.baidu.com include:spf3.baidu.com include:spf4.baidu.com mx ptr -all,google-site-verification=GHb98-6msqyx_qqjGl5eRatD3QTHyVB6-xQ3gJB5UwM,_globalsign-domain-verification=qjb28W2jJSrWj04NHpB0CvgK9tle5JkOq-EcyWBgnE"
}TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => (item=10 163mx02.mxmail.netease.com.,10 163mx03.mxmail.netease.com.,50 163mx00.mxmail.netease.com.,10 163mx01.mxmail.netease.com.) => {"msg": "163.com的mx记录之一是:10 163mx02.mxmail.netease.com.,10 163mx03.mxmail.netease.com.,50 163mx00.mxmail.netease.com.,10 163mx01.mxmail.netease.com."
}

反向查询DNS

# 剧本文件
[root@localhost ansible]# vim test8.yml              
- hosts: testremote_user: rootgather_facts: falsetasks:- debug: msg="114.114.114.114反向查询DNS是:{{lookup('dig','114.114.114.114/PTR')}}"    
# 执行结果
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "114.114.114.114反向查询DNS是:public1.114dns.com."
}

指定查询的DNS服务器

    - debug: msg="使用8.8.8.8查询baidu.com的ipv4地址:{{lookup('dig','baidu.com','@8.8.8.8')}}"
# 执行结果
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "使用8.8.8.8查询baidu.com的ipv4地址:39.156.66.10,110.242.68.66"
}

过滤器

在 Ansible 中,过滤器(Filters)是一种功能强大的工具,用于在模板中处理变量的值。过滤器可以对变量进行转换、格式化、筛选和操作

过滤器使用的位置

quote过滤器的功能是给字符串加引号

[root@csq ~]# vim b.yml
- hosts: test2remote_user: rootgather_facts: falsevars:my_test_string: "This is the test string"tasks:- name: "quote {{ my_test_string }}"debug: msg="echo {{ my_test_string | quote }}"# 执行结果
TASK [quote This is the test string] **********************************************************
ok: [192.168.200.30] => {"msg": "echo 'This is the test string'"
}

过滤器对普通变量的操作

default:为没有定义的变量提供默认值

因为变量some_undefined_varible表示没有定义,所以下面的任务会输出NONE

[root@csq ~]# vim c.yml   
- hosts: testremote_user: rootgather_facts: falsetasks:- name: output1debug: msg="{{ some_undefined_varible | default('NONE') }}"
# 执行结果
TASK [output1] ********************************************************************************
ok: [192.168.200.20] => {"msg": "NONE"
}

如果是远程主机fact里面的变量,当远程主机的fact变量为空一般都是显示的[]或者"",那么我不想让他显示这个空的

true:这是 default 过滤器的第二个参数,用于指示 Ansible 在判断变量是否为空时将空字符串、空列表、空字典等视为真实的空值。如果设置为 true,则 Ansible 会将这些空值视为真实的空值,否则会将其视为非空值。

[root@csq ~]# vim c.yml              
- hosts: testremote_user: roottasks:- name: output1debug: msg="{{ ansible_fibre_channel_wwn | default('NONE',true) }}"# 执行结果TASK [output1] ********************************************************************************
ok: [192.168.200.20] => {"msg": "NONE"
}

omit:忽略变量的占位符

与default一起使用时,如果某个变量没有定义,那么使用omit占位符,Ansible就会把这个对应的参数按照没用传这个参数的值来处理

[root@csq ~]# vim r.yml
- hosts: testremote_user: roottasks:- name: touch filefile: dest={{item.path}} state=touch mode={{item.mode|default(omit)}}with_items:- path: /tmp/csq1- path: /tmp/csq2mode: "0444"
[root@csq ~]# ansible test -m shell -a "ls /tmp/csq* -la"     
192.168.200.20 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0  52 13:58 /tmp/csq1
-r--r--r--. 1 root root 0  52 13:58 /tmp/csq2
# 文件/tmp/csq1没用定义参数mode,所以default(omit)会在没有定义mode时忽略mode变量
# ansible的file模块会按照没有传入mode这个参数来创建文件/tmp/csq1,/tmp/csq2定义了mode为0444
# 所以文件的权限为0444

mandatory:强制变量必须定义,否则报错

在ansible默认的配置中,如果变量没有定义,那么直接使用未定义的变量{{aaa-bbb-ccc}}会报错

如果ansible配置文件中使用了下面的配置,那么遇到未定义的变量时,ansible就不会报错

error_on_undefined_vars=False

如果你想要某一个变量必须定义,就可使用mandatory

[root@csq ~]# vim l.yml                    
- hosts: testremote_user: rootvars:aaabbbccc: abcgather_facts: falsetasks:- name: 定义了变量debug:msg: "{{aaabbbccc}}"- name: 未定义变量报错debug:msg: "{{aaa-bbb-ccc | mandatory}}"# 执行结果
[root@csq ~]# ansible-playbook l.yml       PLAY [test] *************************************************************************************************************************TASK [定义了变量] *******************************************************************************************************************
ok: [192.168.200.20] => {"msg": "abc"
}TASK [未定义变量报错] ***************************************************************************************************************
fatal: [192.168.200.20]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'aaa' is undefined. 'aaa' is undefined\n\nThe error appears to be in '/root/l.yml': line 10, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n        msg: \"{{aaabbbccc}}\"\n    - name: 未定义变量报错\n      ^ here\n"}PLAY RECAP **************************************************************************************************************************
192.168.200.20             : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

bool:判断变量是否为布尔类型

bool的过滤器是playbook中判断条件bool类型的过滤器,其中bool类型的过滤器用来判断变量是否为布尔类型

[root@csq ~]# vim i.yml              
- hosts: testremote_user: rootgather_facts: falsevars:var1: "Test"var2: Truevar3: "True"tasks:- debug: msg=testwhen: var1 | bool- debug: msg=testwhen: var2 | bool- debug: msg=testwhen: var3 | bool
#  执行结果
TASK [debug] **************************************************************************************************************************
skipping: [192.168.200.20]TASK [debug] **************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "test"
}TASK [debug] **************************************************************************************************************************
ok: [192.168.200.20] => {"msg": "test"
}

ternary:Playbook的条件表达式

ternary类似于编程语言中的类型表达式,(“A?B:C”)当条件为真时,返回一个值;当条件为假时,返回另一个值

[root@csq ~]# vim j.yml              
- hosts: testremote_user: rootgather_facts: falsevars:hostname: "csq"tasks:- name: if hostname = csq Yes if hostname = other Nodebug: msg="{{ (hostname == "csq") | ternary('Yes','No') }}"
# 执行结果
TASK [if hostname = csq Yes if hostname = other No] ***********************************************************************************
ok: [192.168.200.20] => {"msg": "Yes"
}

过滤器对文件路径的操作

Ansible为了方便文件及其路径进行操作,提供了一系列关于文件目录的操作,包括获取文件名,路径名,等等。

Linux文件路径的操作的过滤器如下:

  • basename:获取路径中的文件名
  • dirname:获取文件的目录
  • expanduser:扩展~为实际的目录
  • realpath:获取链接文件所指文件的真实路径
  • relpath:获得相对某一根目录的相对路径
  • splitext:把文件名用点号(.)分割成多个部分
[root@csq ~]# vim test1.yml              
- hosts: testremote_user: rootgather_facts: falsevars:linux_path: "/etc/csq/a.txt"linux_user_path: "~/data/my_test/file.txt"link_to_ansible_cfg: "/bin"tasks:- name: "获取Linux路径的文件名 {{linux_path}}"debug: msg="{{linux_path | basename}}"- name: "获取Linux路径的目录名 {{linux_path}}"debug: msg="{{linux_path | dirname}}"- name: "获取展开文件路径中的用户目录 {{linux_user_path}}"debug: msg="{{linux_user_path | expanduser}}"- name: "获取文件路径的真实路径 {{link_to_ansible_cfg}}"debug: msg="{{link_to_ansible_cfg | realpath}}"- name: "获取相对某一根目录的相对路径 {{linux_path}}"debug: msg="{{linux_path | relpath('/etc')}}"- name: "把文件名用点号(.)分隔成多个部分{{linux_path}}"debug: msg="{{linux_path | splitext}}"
# 执行结果
TASK [获取Linux路径的文件名 /etc/csq/a.txt] *******************************************************************************************
ok: [192.168.200.20] => {"msg": "a.txt"
}TASK [获取Linux路径的目录名 /etc/csq/a.txt] *******************************************************************************************
ok: [192.168.200.20] => {"msg": "/etc/csq"
}TASK [获取展开文件路径中的用户目录 ~/data/my_test/file.txt] ***************************************************************************
ok: [192.168.200.20] => {"msg": "/root/data/my_test/file.txt"
}TASK [获取文件路径的真实路径 /bin] ****************************************************************************************************
ok: [192.168.200.20] => {"msg": "/usr/bin"
}TASK [获取相对某一根目录的相对路径 /etc/csq/a.txt] ************************************************************************************
ok: [192.168.200.20] => {"msg": "csq/a.txt"
}TASK [把文件名用点号(.)分隔成多个部分/etc/csq/a.txt] **********************************************************************************
ok: [192.168.200.20] => {"msg": "('/etc/csq/a', '.txt')"
}

过滤器对字符串变量的操作

quote:给字符串加引号

[root@csq ~]# vim b.yml
- hosts: test2remote_user: rootgather_facts: falsevars:my_test_string: "This is the test string"tasks:- name: "quote {{ my_test_string }}"debug: msg="echo {{ my_test_string | quote }}"# 执行结果
TASK [quote This is the test string] **********************************************************
ok: [192.168.200.30] => {"msg": "echo 'This is the test string'"
}

base64:得到字符串Base64编码

[root@csq ~]# vim test2.yml              
- hosts: testremote_user: rootgather_facts: falsevars:my_comment: "hello world"my_comment_base64: "aGVsbG8gd29ybGQ="tasks:- name: "获取base64编码{{my_comment}}"debug: msg="{{my_comment | b64encode}}"- name: "解码base64 {{my_comment_base64}}"debug: msg="{{my_comment_base64 | b64decode}}"- name: "获取uuid {{my_comment}}"debug: msg="{{my_comment | to_uuid}}"
# 执行结果
TASK [获取base64编码hello world] ******************************************************************************************************
ok: [192.168.200.20] => {"msg": "aGVsbG8gd29ybGQ="
}TASK [解码base64 aGVsbG8gd29ybGQ=] ****************************************************************************************************
ok: [192.168.200.20] => {"msg": "hello world"
}TASK [获取uuid hello world] ***********************************************************************************************************
ok: [192.168.200.20] => {"msg": "9a129f19-657c-5ca0-80f4-31b29d10569c"
}

hash:获取字符串的哈希值

计算哈希值的算法有很多,如果sha1、md5、checksum等

[root@csq ~]# vim test3.yml              
- hosts: testremote_user: rootgather_facts: falsevars:my_password: "mypassword"tasks:- name: "获取字符串{{my_password}}的sha1 hash"debug: msg="{{my_password | hash('sha1')}}"- name: "获取字符串{{my_password}}的MD5 hash"debug: msg="{{my_password | hash('md5')}}"- name: "获取字符串{{my_password}}的checksum"debug: msg="{{my_password | checksum}}"- name: "获取字符串{{my_password}}的sha512 hash"debug: msg="{{my_password | password_hash('sha512')}}"- name: "获取字符串{{my_password}}的sha256 hash带有特定字符串"debug: msg="{{my_password | password_hash('sha256','mysecretsalt')}}"
# 执行结果
TASK [获取字符串mypassword的sha1 hash] ************************************************************************************************
ok: [192.168.200.20] => {"msg": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2"
}TASK [获取字符串mypassword的MD5 hash] *************************************************************************************************
ok: [192.168.200.20] => {"msg": "34819d7beeabb9260a5c854bc85b3e44"
}TASK [获取字符串mypassword的checksum] *************************************************************************************************
ok: [192.168.200.20] => {"msg": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2"
}TASK [获取字符串mypassword的sha512 hash] **********************************************************************************************ok: [192.168.200.20] => {"msg": "$6$kM35/CEoWTM1xoIX$0HjNRHNwS01H2uH4Rik7h06E3DzDZpI9uHvg0NN0QE2kQOMKYwkN28kPKOuB9.0aShHv6CsFJAbAPnOCv1PZO0"
}TASK [获取字符串mypassword的sha256 hash带有特定字符串] ********************************************************************************ok: [192.168.200.20] => {"msg": "$5$mysecretsalt$HhobCuvPwbLCsdua9UNYk8C.EPib1CkzWvN23KBHYV2"
}

comment:把字符串变成代码注释的一部分

comment展示了将字符串转化为不同风格和格式注释的使用方法,最后一个是用户自定义的注释风格

[root@csq ~]# vim test4.yml              - name: "erlang 
- hosts: testremote_user: rootgather_facts: falsevars:my_comment: "hello world"tasks:- name: "Simple comment"debug: msg="{{my_comment | comment}}"- name: "C  comment"debug: msg="{{my_comment | comment('c')}}"- name: "cblock  comment"debug: msg="{{my_comment | comment('cblock')}}"- name: "erlang  comment"debug: msg="{{my_comment | comment('erlang')}}"- name: "xml  comment"debug: msg="{{my_comment | comment('xml')}}"- name: "customize comment"debug: msg="{{my_comment | comment('plain',prefix='######\n#',postfix='#\n######\n###\n#')}}"
# 执行结果
TASK [Simple comment] *****************************************************************************************************************
ok: [192.168.200.20] => {"msg": "#\n# hello world\n#"
}TASK [C  comment] *********************************************************************************************************************
ok: [192.168.200.20] => {"msg": "//\n// hello world\n//"
}TASK [cblock  comment] ****************************************************************************************************************
ok: [192.168.200.20] => {"msg": "/*\n *\n * hello world\n *\n */"
}TASK [erlang  comment] ****************************************************************************************************************
ok: [192.168.200.20] => {"msg": "%\n% hello world\n%"
}TASK [xml  comment] *******************************************************************************************************************
ok: [192.168.200.20] => {"msg": "<!--\n -\n - hello world\n -\n-->"
}TASK [customize comment] **************************************************************************************************************
ok: [192.168.200.20] => {"msg": "######\n#\n# hello world\n#\n######\n###\n#"
}

regex:利用正则表达式对字符串进行替换

[root@csq ~]# vim test5.yml              
- hosts: testremote_user: rootvars:my_comment: "hello world"gather_facts: falsetasks:- name: "转换 ansible 为 able"debug: msg="{{'ansible' | regex_replace('^a.*i(.*)$','a\\1')}}"- name: "转换 foobar 为 bar"debug: msg="{{'foobar' | regex_replace('^f.*o(.*)$','\\1')}}"- name: "转换 localhost:80 为 localhost,80"debug: msg="{{'localhost:80' | regex_replace('^(?P<host>.+):(?P<port>\\d+)$','\\g<host>,\\g<port>') }}"
# 执行结果
TASK [转换 ansible 为 able] ***********************************************************************************************************
ok: [192.168.200.20] => {"msg": "able"
}TASK [转换 foobar 为 bar] *************************************************************************************************************
ok: [192.168.200.20] => {"msg": "bar"
}TASK [转换 localhost:80 为 localhost,80] **********************************************************************************************
ok: [192.168.200.20] => {"msg": "localhost,80"
}

ip:判断字符串是否是合法的IP地址

[root@localhost ansible]# vim test6.yml              
- hosts: testremote_user: rootgather_facts: falsevars:ip_address1: "192.168.2455.1"ip_address2: "192.168.200.20"ip_addr_ipv6: "fe80::20c:29ff:fe4e:d6a9"tasks:- name: "判断{{ip_address1}}是否为合法ip"debug: msg="{{ ip_address1 | ipaddr}}"- name: "判断{{ip_address2}}是否为合法ip"debug: msg="{{ ip_address2 | ipaddr}}"- name: "判断{{ip_address2}}是否为ipv4地址"debug: msg="{{ ip_address2 | ipv4}}"- name: "判断{{ip_addr_ipv6}}是否为ipv6地址"debug: msg="{{ ip_addr_ipv6 | ipv6}}"- name: "判断{{'192.0.2.1/24' | ipaddr('address')}}是否为合法IP"debug: msg="{{'192.0.2.1/24' | ipaddr('address')}}"
# 执行结果
[root@localhost ansible]# ansible-playbook test6.yml TASK [判断192.168.2455.1是否为合法ip] ***********************************************************************************************ok: [192.168.200.20] => {"msg": false
}TASK [判断192.168.200.20是否为合法ip] ***********************************************************************************************ok: [192.168.200.20] => {"msg": "192.168.200.20"
}TASK [判断192.168.200.20是否为ipv4地址] *********************************************************************************************ok: [192.168.200.20] => {"msg": "192.168.200.20"
}TASK [判断fe80::20c:29ff:fe4e:d6a9是否为ipv6地址] ***********************************************************************************ok: [192.168.200.20] => {"msg": "fe80::20c:29ff:fe4e:d6a9"
}TASK [判断192.0.2.1是否为合法IP] ****************************************************************************************************
ok: [192.168.200.20] => {"msg": "192.0.2.1"
}

过滤器对JSON的操作

format:将变量的值按照JSON/YAML格式输出

# 剧本文件
[root@localhost ansible]# vim test1.yml   
- hosts: testgather_facts: falsevars:my_variable:key1: value1key2: value2tasks:- name: Print variable as JSONdebug:msg: "{{ my_variable | to_json }}"- name: Print variable as YAMLdebug:msg: "{{ my_variable | to_yaml }}"- name: Print variable as Nice JSONdebug:msg: "{{ my_variable | to_nice_json }}"- name: Print variable as Nice YAMLdebug:msg: "{{ my_variable | to_nice_yaml }}"
# 执行结果TASK [Print variable as JSON] *******************************************************************************************************
ok: [192.168.200.20] => {"msg": "{\"key1\": \"value1\", \"key2\": \"value2\"}"
}TASK [Print variable as YAML] *******************************************************************************************************
ok: [192.168.200.20] => {"msg": "{key1: value1, key2: value2}\n"
}TASK [Print variable as Nice JSON] **************************************************************************************************
ok: [192.168.200.20] => {"msg": "{\n    \"key1\": \"value1\",\n    \"key2\": \"value2\"\n}"
}TASK [Print variable as Nice YAML] **************************************************************************************************
ok: [192.168.200.20] => {"msg": "key1: value1\nkey2: value2\n"
}

query:在一个JSON对象里,搜索符合条件的属性,返回符合条件的属性数组

[root@localhost ansible]# vim test2.yml              
- name: Search for properties matching a condition in a JSON objecthosts: localhostgather_facts: falsevars:my_json:users:- name: Johnage: 30- name: Aliceage: 25- name: Bobage: 35tasks:- name: Query JSON objectdebug:msg: "{{ my_json.users | json_query('[].name') }}"
# 执行结果
ok: [localhost] => {"msg": ["John","Alice","Bob"]
}

过滤器对数据结构的操作

Ansible中的过滤器支持以下几种数据结构的操作

random:取随机数

[root@localhost ansible]# vim test3.yml              
- hosts: testremote_user: rootgather_facts: falsetasks:- name: 列表随机debug: msg="{{ ['a','b','c'] | random}}"- name: 随机数debug: msg="{{ 59 | random}} * * * * echo hello world"- name: random with stepdebug: msg="{{ 100 | random(step=10)}}"- name: random with start and stepdebug: msg="{{ 100 | random(2,10)}}"- name: random with start and stepdebug: msg="{{ 100|random(start=2,step=10)}}"
# 执行结果TASK [列表随机] *********************************************************************************************************************
ok: [192.168.200.20] => {"msg": "b"
}TASK [随机数] ***********************************************************************************************************************
ok: [192.168.200.20] => {"msg": "33 * * * * echo hello world"
}TASK [random with step] *************************************************************************************************************
ok: [192.168.200.20] => {"msg": "10"
}TASK [random with start and step] ***************************************************************************************************
ok: [192.168.200.20] => {"msg": "32"
}TASK [random with start and step] ***************************************************************************************************
ok: [192.168.200.20] => {"msg": "72"
}

过滤器的链式/连续使用

ansible的过滤器是支持链式使用的,就是在一个{{}}中使用多个过滤器

[root@localhost ansible]# vim test4.yml              
- hosts: testremote_user: rootvars:aaabbbccc: abcgather_facts: falsetasks:- name: 判断变量是否存在,存在就使用base64加密该变量debug:msg: "{{aaabbbccc | mandatory | b64encode}}"
# 执行结果TASK [判断变量是否存在,存在就使用base64加密该变量] *********************************************************************************
ok: [192.168.200.20] => {"msg": "YWJj"
}

常见插件类型

modules插件

模块插件是Ansible的核心成分,用于执行具体的任务。它们可以通过在任务中调用来提供丰富的功能,例如文件操作、软件包管理、配置管理等。

Inventory插件

主机清单插件用于动态生成Ansible的主机清单。它们可以从各种源(如INI文件、YAML文件、云服务提供商)读取主机信息,并动态生成可供Ansible使用的清单。

Action插件

和模块使用方法类似,只不过执行目标不是远程主机,而是在Ansible的控制节点(管理节点)本机上

Cache插件

为Facts(主机变量)提供缓存,以避免多次执行Playbook时搜集Facts

Callback插件

Ansible执行Playbook后,提供额外的行为,例如,将执行结果发送到E-mail中,或者将执行结果写入log中等等

connection插件

用于在Ansible连接远程主机时进行身份验证。认证插件允许使用不同的认证机制,如用户名/密码、私钥等

filters插件

过滤器插件用于对变量进行转换、过滤和操作。

lookup插件

文件查找插件用于在Ansible中查找文件和数据。它们可以从文件系统、远程主机或其它的数据源中查找所需的文件或数据

test插件

ansible Jinja2 test提供更多功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/6790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QSqlDatabase的数据库路径或名称问题

在Qt的数据库编程中&#xff0c;先是设置数据库的类型&#xff0c;然后是设置数据库文件的路径&#xff0c;或者数据库名称。若有数据库的用户名、密码&#xff0c;则分别调用setUserName(“”)、setPassword(“”)来设置用户名和密码&#xff1b;若没有&#xff0c;则省略用户…

Maven 在项目的 pom.xml 文件中 指定 阿里云的景象仓库

配置 在 项目的 pom.xml 文件中添加如下配置即可 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&…

【Unity】位图字体制作工具:蒲公英

一般来讲&#xff0c;如果需要制作位图字体&#xff0c;一般是使用 BMFont 这种第三方工具&#xff1a;BMFont - AngelCode.comhttp://www.angelcode.com/products/bmfont/ 然而这个工具对于非程序员来说&#xff0c;操作起来较为繁琐困难。每次美术修改了字体之后&…

解决git合并冲突

解决Git请求合并冲突通常涉及以下步骤&#xff1a; 了解冲突&#xff1a; 当Git在合并过程中无法自动解决文件差异时&#xff0c;它会产生冲突。 你可以通过查看Git的输出或检查冲突文件的特殊标记来识别冲突。 查看冲突文件&#xff1a; 打开Git告诉你存在冲突的文件。 你…

【区块链】比特币架构

比特币架构 2009年1月&#xff0c;在比特币系统论文发表两个月之后&#xff0c;比特币系统正式运行并开放了源码&#xff0c;标志着比特币网络的正式诞生。通过其构建的一个公开透明、去中心化、防篡改的账本系统&#xff0c;比特币开展了一场规模空前的加密数字货币体验。在区…

C++手写协程项目(协程实现线程结构体、线程调度器定义,线程挂起、切换、恢复函数,模块测试)

协程结构体定义 之前我们使用linux下协程函数实现了线程切换&#xff0c;使用的是ucontext_t结构体&#xff0c;和基于这个结构体的四个函数。现在我们要用这些工具来实现我们自己的一个线程结构体&#xff0c;并实现线程调度和线程切换、挂起。 首先我们来实现以下线程结构体…

Linux常用软件安装(JDK、MySQL、Tomcat、Redis)

目录 一、上传与下载工具Filezilla1. filezilla官网 二、JDK安装1. 在opt中创建JDK目录2.上传JDK压缩文件到新建目录中3.卸载系统自代jdk4.安装JDK5.JDK环境变量配置6. 验证是否安装成功 三、安装MySQL1.创建mysql文件夹2.下载mysql安装压缩包3.上传到文件夹里面4. 卸载系统自带…

ThreeJS:光线投射与3D场景交互

光线投射Raycaster 光线投射详细介绍可参考&#xff1a;https://en.wikipedia.org/wiki/Ray_casting&#xff0c; ThreeJS中&#xff0c;提供了Raycaster类&#xff0c;用于进行鼠标拾取&#xff0c;即&#xff1a;当三维场景中鼠标移动时&#xff0c;利用光线投射&#xff0c;…

linux手动安装es

docker下载 docker pull elasticsearch:7.9.3 docker pull kibana:7.9.3检查安装目录下存在文件夹/data/elasticsearch/data &#xff0c;如果缺少&#xff0c;请创建目录并设置权限&#xff0c;否则会因为无权限访问而启动失败。 # 创建目录 mkdir /data/elasticsearch/data…

SpringCloudAlibaba:4.1云原生网关higress的搭建

概述 简介 Higress是基于阿里内部的Envoy Gateway实践沉淀、以开源Istio Envoy为核心构建的下一代云原生网关&#xff0c; 实现了流量网关 微服务网关 安全网关三合一的高集成能力&#xff0c;深度集成Dubbo、Nacos、Sentinel等微服务技术栈 定位 在虚拟化时期的微服务架构…

【DevOps】Jenkins 集成Docker

目录 1. 安装 Docker 和 Jenkins 2. 在 Jenkins 中安装 Docker 插件 3. 配置 Docker 连接 4. 创建 Jenkins Pipeline 5. 示例 Pipeline 脚本 6. 运行 Jenkins Job 7. 扩展功能 8、docker配置测试连接的时候报错处理 将 Docker 与 Jenkins 集成可以实现持续集成和持续交…

目标检测正负样本区分和平衡

1、正负样本定义 rpn和rcnn的正负样本定义都是基于MaxIoUAssigner&#xff0c;只不过定义阈值不一样而已。 MaxIoUAssigner的操作包括4个步骤&#xff1a; 首先初始化时候假设每个anchor的mask都是-1&#xff0c;表示都是忽略anchor 将每个anchor和所有gt的iou的最大Iou小于…

如何为 Nestjs 编写单元测试和 E2E 测试

前言 最近在给一个 nestjs 项目写单元测试&#xff08;Unit Testing&#xff09;和 e2e 测试&#xff08;End-to-End Testing&#xff0c;端到端测试&#xff0c;简称 e2e 测试&#xff09;&#xff0c;这是我第一次给后端项目写测试&#xff0c;发现和之前给前端项目写测试还…

小白入门 CSS 语法规则

文章导读&#xff1a;AI 辅助学习前端&#xff0c;包含入门、进阶、高级部分前端系列内容&#xff0c;当前是 CSS 的部分&#xff0c;瑶琴会持续更新&#xff0c;适合零基础的朋友&#xff0c;已有前端工作经验的可以不看&#xff0c;也可以当作基础知识回顾。 这篇文章给大家…

Rust里的Fn/FnMut/FnOnce和闭包匿名函数关系

闭包&#xff08;英语&#xff1a;Closure&#xff09;&#xff0c;又称词法闭包&#xff08;Lexical Closure&#xff09;或函数闭包&#xff08;function closures&#xff09;&#xff0c;是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在&#xff0c;即使…

Linux线程安全,互斥量和条件变量

文章目录 一、 Linux线程互斥1. 进程线程间的互斥相关背景概念&#xff08;1&#xff09; 临界资源和临界区&#xff08;2&#xff09; 互斥和原子性 2. 互斥量mutex3. 互斥量的接口4. 互斥量实现原理探究 二、 可重入VS线程安全1. 概念2. 常见的线程不安全的情况3. 常见的线程…

【superset】基于MySQL的BI数据分析可视化实战案例(已更新)

1.熟悉、梳理、总结下superset可视化分析实战案例知识体系,一直想探索有效可用的可视化分析方案,大多收费或不好用,这里,借此机会总结、更新下。 2.复杂度高,遇到并解决的问题较多,尝试了很多次。 3.欢迎批评指正,跪谢一键三连! 基于MySQL的BI数据分析可视化实战案例文…

leetcode46-Permutations

题目 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 分析 求全排列&#xff0c;我们可以用…

Crossplane 实战:构建统一的云原生控制平面

1 什么是 Crossplane Crossplane 是一个开源的 Kubernetes 扩展&#xff0c;其核心目标是将 Kubernetes 转化为一个通用的控制平面&#xff0c;使其能够管理和编排分布于 Kubernetes 集群内外的各种资源。通过扩展 Kubernetes 的功能&#xff0c;Crossplane 对 Kubernetes 集群…

rv1126的rknn1.7.5自有模型训练部署

几乎一年前, 弄过一次rv1126的平台的推理部署, 一年时间过去了, rknn从1.7.1, 进化到了1.7.5,原有的代码不太好用了, 因为最近有个客户要做1126平台的推理, 今天下午就花了几个小时, 从头再捋了一遍. 模型训练 这部分, 跟3588平台差不多, clone下yolov5的仓库, 并check out到…