结果注册变量中特定行的 Ansible 解析
Ansible parse for a specific line in resulted registered var
在我的 ansible 剧本下,我有一个执行脚本的任务:
- name: Execute Update on selected databases
shell: "./script_update.sh server007 {{item}} {{bdd_config[item].updateFile }}"
with_items: "{{selected_DBS}}"
register: updateResult
这个脚本的结果可能是这样的:
INFO - ================================================================================
INFO - BEGIN 'script_update' ON ini99db1 AT 2019/05/22 12:22:06
INFO - ================================================================================
INFO - THE MySQL SERVER server007 EXISTS
INFO - THE MySQL SERVER server007 IS ON
INFO - THE DATABASE myDB EXISTS
INFO - FILE /opt/myscode_In_progress.sql EXISTS.
ERROR - ERROR 1064 (42000) at line 4 in file: '/opt/myscode_In_progress.sql': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'azdazdazdazdazd' at line 1
INFO - SCRIPT OUTPUT : SEE LOG FILE 1
INFO - THE DB HAS BEEN CORRECTLY UPDATED
INFO - --------------------------------------------------------------------------------
INFO - THE PROCESS TERMINATED SUCCESSFULLY
INFO - SEE THE LOG FILE /opt/mysql/log/app_20190522_12H22.log
当显示我的寄存器变量 (updateResult) 的输出时,它给出如下内容:
"msg": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "nomadisdb",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "./rcd_db_update.ksh myserver01 nomadisdb nomadisdb_In_progress.sql",
"delta": "0:00:12.786607",
"end": "2019-05-22 12:36:52.817077",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "./rcd_db_update.ksh myserver01 nomadisdb nomadisdb_In_progress.sql",
"_uses_shell": true,
"argv": null,
"chdir": "/opt/application/i99/current/sh",
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "nomadisdb",
"rc": 0,
"start": "2019-05-22 12:36:40.030470",
"stdout_lines": [
"\tINFO - ================================================================================",
"\tINFO - BEGIN 'rcd_db_update' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================",
"\tINFO - THE MySQL SERVER myserver01 EXISTS",
"\tINFO - THE MySQL SERVER myserver01 IS ON",
"\tINFO - THE DATABASE nomadisdb EXISTS",
"\tINFO - FILE /opt/application/i99/current/sql/nomadisdb_In_progress.sql EXISTS.",
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
"\tINFO - SCRIPT OUTPUT : SEE LOG FILE 1",
"\tINFO - THE DB HAS BEEN CORRECTLY UPDATED",
"\tINFO - --------------------------------------------------------------------------------",
"\tINFO - THE PROCESS TERMINATED SUCCESSFULLY",
"\tINFO - SEE THE LOG FILE /opt/mysql/log/rcd_db_update_myserver01_nomadisdb_20190522_12H36.log",
"\tINFO - ================================================================================",
"\tINFO - END 'rcd_db_update.ksh' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================"
]
}
]
}
}
我的目的是搜索此输出消息并搜索任何 ERROR 行,如下所示:
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
我可能会用 regExp 搜索它,查找以“ERROR”开头并包含“”的行在行”和“在文件”
最后我应该得到整行结果
我试过像这样使用正则表达式:
- name: set regex
set_fact:
regExpOfSqlError: ' '
become_user: mysql
- set_fact:
errorLine: "{{ updateResult.results | regex_search(regExpOfSqlError, ' ') }}"
become_user: mysql
但我仍然想知道我应该输入什么 RegExp 来搜索这些行并输出它们
建议 ?
一个简单的解决方案是使用 json_query
过滤器。
备注:
json_query
依赖于 jmespath
。在示例 运行 之前,您需要 pip(3) install jmespath
。
- 需要
to_json | from_json
破解 work arround a known bug when using jmespath contains
function in ansible. This needs a modification on jmespath side 仍在等待 approval/development
- 您应该阅读
jmespath
documentation 以了解更多详细信息,但这里是对我示例中查询字符串的快速解释:创建所有输入元素的列表投影 (updateResults.result
),然后 select stdout_lines
条目中包含文本 ERROR
的所有元素,最后将结果投影为平面列表。
---
- name: SO Test
hosts: localhost
vars:
# This result var mimics your current captured result
# I only kept the relevant part for the example.
updateResult:
results:
- stdout_lines: [
"\tINFO - ================================================================================",
"\tINFO - BEGIN 'rcd_db_update' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================",
"\tINFO - THE MySQL SERVER myserver01 EXISTS",
"\tINFO - THE MySQL SERVER myserver01 IS ON",
"\tINFO - THE DATABASE nomadisdb EXISTS",
"\tINFO - FILE /opt/application/i99/current/sql/nomadisdb_In_progress.sql EXISTS.",
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
"\tINFO - SCRIPT OUTPUT : SEE LOG FILE 1",
"\tINFO - THE DB HAS BEEN CORRECTLY UPDATED",
"\tINFO - --------------------------------------------------------------------------------",
"\tINFO - THE PROCESS TERMINATED SUCCESSFULLY",
"\tINFO - SEE THE LOG FILE /opt/mysql/log/rcd_db_update_myserver01_nomadisdb_20190522_12H36.log",
"\tINFO - ================================================================================",
"\tINFO - END 'rcd_db_update.ksh' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================"
]
tasks:
- name: Capture a list of all lines containing an error in all results
set_fact:
error_lines: "{{ updateResult.results | to_json | from_json | json_query(\"[].stdout_lines[?contains(@, 'ERROR')][]\") }}"
- name: Show lines with errors
debug:
var: error_lines
给出:
PLAY [SO Test] *****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Capture a list of all lines containing an error in all results] **********
ok: [localhost]
TASK [Show lines with errors] **************************************************
ok: [localhost] => {
"error_lines": [
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'"
]
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
在我的 ansible 剧本下,我有一个执行脚本的任务:
- name: Execute Update on selected databases
shell: "./script_update.sh server007 {{item}} {{bdd_config[item].updateFile }}"
with_items: "{{selected_DBS}}"
register: updateResult
这个脚本的结果可能是这样的:
INFO - ================================================================================
INFO - BEGIN 'script_update' ON ini99db1 AT 2019/05/22 12:22:06
INFO - ================================================================================
INFO - THE MySQL SERVER server007 EXISTS
INFO - THE MySQL SERVER server007 IS ON
INFO - THE DATABASE myDB EXISTS
INFO - FILE /opt/myscode_In_progress.sql EXISTS.
ERROR - ERROR 1064 (42000) at line 4 in file: '/opt/myscode_In_progress.sql': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'azdazdazdazdazd' at line 1
INFO - SCRIPT OUTPUT : SEE LOG FILE 1
INFO - THE DB HAS BEEN CORRECTLY UPDATED
INFO - --------------------------------------------------------------------------------
INFO - THE PROCESS TERMINATED SUCCESSFULLY
INFO - SEE THE LOG FILE /opt/mysql/log/app_20190522_12H22.log
当显示我的寄存器变量 (updateResult) 的输出时,它给出如下内容:
"msg": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "nomadisdb",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "./rcd_db_update.ksh myserver01 nomadisdb nomadisdb_In_progress.sql",
"delta": "0:00:12.786607",
"end": "2019-05-22 12:36:52.817077",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "./rcd_db_update.ksh myserver01 nomadisdb nomadisdb_In_progress.sql",
"_uses_shell": true,
"argv": null,
"chdir": "/opt/application/i99/current/sh",
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "nomadisdb",
"rc": 0,
"start": "2019-05-22 12:36:40.030470",
"stdout_lines": [
"\tINFO - ================================================================================",
"\tINFO - BEGIN 'rcd_db_update' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================",
"\tINFO - THE MySQL SERVER myserver01 EXISTS",
"\tINFO - THE MySQL SERVER myserver01 IS ON",
"\tINFO - THE DATABASE nomadisdb EXISTS",
"\tINFO - FILE /opt/application/i99/current/sql/nomadisdb_In_progress.sql EXISTS.",
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
"\tINFO - SCRIPT OUTPUT : SEE LOG FILE 1",
"\tINFO - THE DB HAS BEEN CORRECTLY UPDATED",
"\tINFO - --------------------------------------------------------------------------------",
"\tINFO - THE PROCESS TERMINATED SUCCESSFULLY",
"\tINFO - SEE THE LOG FILE /opt/mysql/log/rcd_db_update_myserver01_nomadisdb_20190522_12H36.log",
"\tINFO - ================================================================================",
"\tINFO - END 'rcd_db_update.ksh' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================"
]
}
]
}
}
我的目的是搜索此输出消息并搜索任何 ERROR 行,如下所示:
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
我可能会用 regExp 搜索它,查找以“ERROR”开头并包含“”的行在行”和“在文件”
最后我应该得到整行结果
我试过像这样使用正则表达式:
- name: set regex
set_fact:
regExpOfSqlError: ' '
become_user: mysql
- set_fact:
errorLine: "{{ updateResult.results | regex_search(regExpOfSqlError, ' ') }}"
become_user: mysql
但我仍然想知道我应该输入什么 RegExp 来搜索这些行并输出它们
建议 ?
一个简单的解决方案是使用 json_query
过滤器。
备注:
json_query
依赖于jmespath
。在示例 运行 之前,您需要pip(3) install jmespath
。- 需要
to_json | from_json
破解 work arround a known bug when using jmespathcontains
function in ansible. This needs a modification on jmespath side 仍在等待 approval/development - 您应该阅读
jmespath
documentation 以了解更多详细信息,但这里是对我示例中查询字符串的快速解释:创建所有输入元素的列表投影 (updateResults.result
),然后 selectstdout_lines
条目中包含文本ERROR
的所有元素,最后将结果投影为平面列表。
---
- name: SO Test
hosts: localhost
vars:
# This result var mimics your current captured result
# I only kept the relevant part for the example.
updateResult:
results:
- stdout_lines: [
"\tINFO - ================================================================================",
"\tINFO - BEGIN 'rcd_db_update' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================",
"\tINFO - THE MySQL SERVER myserver01 EXISTS",
"\tINFO - THE MySQL SERVER myserver01 IS ON",
"\tINFO - THE DATABASE nomadisdb EXISTS",
"\tINFO - FILE /opt/application/i99/current/sql/nomadisdb_In_progress.sql EXISTS.",
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'",
"\tINFO - SCRIPT OUTPUT : SEE LOG FILE 1",
"\tINFO - THE DB HAS BEEN CORRECTLY UPDATED",
"\tINFO - --------------------------------------------------------------------------------",
"\tINFO - THE PROCESS TERMINATED SUCCESSFULLY",
"\tINFO - SEE THE LOG FILE /opt/mysql/log/rcd_db_update_myserver01_nomadisdb_20190522_12H36.log",
"\tINFO - ================================================================================",
"\tINFO - END 'rcd_db_update.ksh' ON ini99db1 AT 2019/05/22 12:36:50",
"\tINFO - ================================================================================"
]
tasks:
- name: Capture a list of all lines containing an error in all results
set_fact:
error_lines: "{{ updateResult.results | to_json | from_json | json_query(\"[].stdout_lines[?contains(@, 'ERROR')][]\") }}"
- name: Show lines with errors
debug:
var: error_lines
给出:
PLAY [SO Test] *****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Capture a list of all lines containing an error in all results] **********
ok: [localhost]
TASK [Show lines with errors] **************************************************
ok: [localhost] => {
"error_lines": [
"\tERROR - ERROR 1060 (42S21) at line 4 in file: '/opt/myDB_In_progress.sql': Duplicate column name 'con_habilitation_version'"
]
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0