使用过滤和插件转换数据
1、 使用过滤器处理变量
1.1 ansible filter
ansible应用变量到playbook并且使用jinja2表达式来使用变量。例如下面的J2表达式中的变量使用两个大括号括起来。
J2表达式也支持filter。Filter在playbook或者模板中被用来修改或者处理要替代的变量值。一些filter使用J2语言来使用,其他的一些filter被包含在ansible的插件中。它也可以创建自定义的filter,尽管这超出了本课程的范围。filter在playbook中或者template用于准备使用的数据是非常有用的。
# ansible 表达变量
{{ var }}
1.2 变量类型
ansible将运行时数据存储在变量中,YAML结构或值的内容定义了确切的数据类型,一些值的类型包括:
变量类型 | 说明 |
---|---|
String | 字符串 |
Number | 数字 |
Booleans | 布尔值(与或非) |
Dates | 日期 |
Null | 空 |
Lists 或 Arrays | 列表或变量矩阵 |
Dictionaries | 字典 |
1.2.1 String
- String是一串字符序列,是ansible的默认数据类型,String类型数据不需要使用单引号或者双引号扩起来。
my_string: Those are the contents of the string
- yaml语言支持使用|或 > 符号对字符串进行格式化输出。
格式化符号 | 说明 |
---|---|
| | 换行输出 |
> | 不换行输出 |
# 对字符串进行换行输出
string_with_breaks: |
this string
has serveral
line breaks
# 对字符串不换行输出
string_without_breaks: >
this string will not
contain any line breaks.
Separated lines are joined
by a space character.
1.2.2 Numbers
通过给变量赋值,ansible会自动识别出数字类型,并根据赋值情况确定数字类型。
# 整型Integer
answer: 10
# 浮点型Float
float_answer: 10.5
# 科学计数法整型/浮点型
scientific_answer: 0.4e+2
# 十六进制
hex_answer: 0x2A
# 非数字类型,使用双引号ansible会识别成字符串
string_not_number: "20"
1.2.3 Booleans
布尔值可以作为判断条件
布尔值 | 含义 |
---|---|
yes、y、on、true | 真 |
no、n、off、false | 假 |
1.2.4 Date
日期类型准讯ISO-8610标准,ansible变量可以接受日期类型的值
my_date_time: 2019-05-30T21:15:32.42+02:00
my_simple_date: 2019-05-30
1.2.5 Null
可以给变量赋值为空,使用null或者~进行赋值
my_undefined1: null
my_nudefined2: ~
1.2.6 List 或 Arrays
列表或者数组是数据收集和循环的基本结构
# 列表定义方式1,不推荐
my_list: ['xiaoming','xiaohong','xiaobai']
# 列表定义方式2,推荐
my_list:
- xiaoming
- xiaohong
- xiaobai
# 可以通过列表名 + 下标快速索引
- name: confirm that the second list element is "xiaoming"
assert:
that:
- my_list[0] == 'xiaoming'
1.2.7 Dictionaries
字典也称为maps或hashes列,是链接字符串的结构,通常有key:values组成。字典可以写成一行或者多行,也支持通过键访问值。
# 字典定义方式1,不推荐
my_dict: { Douglas: Human, Marvin: Robot, Arthur: Human}
# 字典定义方式2,推荐
my_dict:
Douglas: Human
Marvin: Robot
Arthur: Human
# 可以通过列表名 + 键名快速索引
- name: identiry Marvin
assert:
that:
- my_dict['Marvin'] == 'Robot'
1.3 filter处理数据
filter允许你处理变量中的值以提取信息,转换或使用它来产生一个新的值,要使用filter,需要在变量后加入一个管道符(|),管道符后写filter过滤器名称。你可以一次性使用多个filter对数据进行处理。
1.3.1 过滤器特性
- capitalize这个filter作用时确保首字母大写,通过Jinja2格式可以通过如下方式定义:
{{ myname | capitalize }}
- string可以将变量转成字符串,通过Jinja2格式可以通过如下方式定义:
{{ munumber | string }}
- unique可以去掉重复元素,sort可以对数据进行排序
- 可以使用连续管道符对变量进行多次处理
- name: test to see if the assertion is true, fail if not
assert:
that:
- "{{ [1,4,2,2] | unique | sort }} is eq( [1,2,4] )"
1.3.2 对过滤器特性进行测试
# 将3个特性写在一个playbook中进行测试
[workstation task-review (master *)]# cat test_fileter.yml
---
- name: test filter
hosts: servera.lab.example.com
vars:
var1: test1
var2: 123
tasks:
- name: test capitalize
debug:
msg: "{{ var1 | capitalize }}"
- name: test string filter
debug:
msg: "{{ var2 | string }}"
- name: test unique and sort filter
debug:
msg: "{{ [1,4,2,2] | unique | sort }}"
[workstation task-review (master *)]# ansible-playbook test_fileter.yml
PLAY [test filter] *************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [test capitalize] *********************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "Test1"
}
TASK [test string filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "123"
}
TASK [test unique and sort filter] *********************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": [
1,
2,
4
]
}
PLAY RECAP *********************************************************************************************************************************************
servera.lab.example.com : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.4 filter描述
ansible存在大量的filter过滤器,包括在Jinja2和RHEL提供的额外的过滤器。如果要查询这些过滤器,请参考:
- http://jinja.pocoo.org/docs/2.10/templates/#builtinfilters
- https://jinja.palletsprojects.com/en/3.0.x/templates/
1.4.1 检查变量是否定义
通过使用两个Ansible-specific filter过滤器,可以检查变量是否定义
- mandatory
判断变量是否被赋值,如果变量没被赋值,则失败或终止
# 定义格式
{{ my_value | mandatory }}
# 提示:在生产环境中,一定要使用mandatory指定特定的版本,不要使用缺省值!!!
# 如果变量未被定义,报错如下
fatal: [servera.lab.example.com]: FAILED! => {"msg": "Mandatory variable 'var2' not defined."}
- default
判断变量是否被赋值,如果变量没有赋值,则赋予一个缺省的值
# 定义格式
# 如果my_value未被赋值,则使用缺省值“my_default”
{{ my_value | default(my_default, True )}}
default filter也可以使用omit作为缺省值,如果使用了该缺省值,一旦变量未赋值,将会用“hello world”作为替代
# default filter参数使用omit作为赋值参数
"{{ var2 | default(omit) }}"
1.4.2 mandatory和default测试
[workstation task-tagging (master *)]# cat useful_filter1.yml
---
- name: check if the var exist
hosts: servera.lab.example.com
vars:
var1: test
tasks:
- name: use default filter
debug:
msg: "{{ var1 | mandatory }}"
- name: use defualt filter
debug:
msg: "{{ var2 | mandatory }}"
tags:
- mandatory
- name: use default filter
debug:
msg: "{{ var1 | default('var1 is not exist') }}"
- name: use default filter
debug:
msg: "{{ var1 | default('var1 is not exist', true)}}"
- name: use default filter
debug:
msg: "{{ var2 | default('var1 is not exist') }}"
- name: use default filter
debug:
msg: "{{ var2 | default('var1 is not exist', true)}}"
- name: use default filter
debug:
msg: "{{ var1 | default(omit) }}"
- name: use default filter
debug:
msg: "{{ var2 | default(omit) }}"
[workstation task-tagging (master *)]# ansible-playbook useful_filter1.yml
PLAY [check if the var exist] **************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "test"
}
TASK [use defualt filter] ******************************************************************************************************************************
fatal: [servera.lab.example.com]: FAILED! => {"msg": "Mandatory variable 'var2' not defined."}
PLAY RECAP *********************************************************************************************************************************************
servera.lab.example.com : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[workstation task-tagging (master *)]# ansible-playbook useful_filter1.yml --skip-tags mandatory
PLAY [check if the var exist] **************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************
ok: [servera.lab.example.com]
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "test"
}
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "test"
}
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "test"
}
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "var1 is not exist"
}
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "var1 is not exist"
}
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "test"
}
TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
"msg": "Hello world!"
}
PLAY RECAP *********************************************************************************************************************************************
servera.lab.example.com : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0