首页 > 其他分享 >Ansible如何使用lookup插件模板化外部数据

Ansible如何使用lookup插件模板化外部数据

时间:2022-12-12 15:35:10浏览次数:44  
标签:插件 38 name ansible 192.168 Ansible lookup root


写在前面


  • 今天和小伙伴分享使用lookup插件模板化外部数据
  • 博文内容比较简单
  • 主要介绍的常用lookup插件和对应的Demo
  • 外部数据如何代替cat等通过lookup插件读取
  • 理解不足小伙伴帮忙指正
  • 食用方式:了解Ansible基础语法

运维箴言:重启试试


lookup插件

lookup 插件是 Jinja2 模板化语言的 Ansible 扩展。这些插件使 Ansible 能够使用外部来源的数据,如​​文件和Shell 环境​​。

默认的Ansible安装中有几十个可用的插件。​​ansible-doc-t lookup -l​​,获取可用查找插件的完整列表。

[[email protected]]$ ansible-doc -t lookup -l
aws_account_attribute Look up AWS account attributes
aws_secret Look up secrets stored in AWS Secrets Manager
aws_service_ip_ranges Look up the IP ranges for services provided in AWS such as EC2 and S3
aws_ssm Get the value for a SSM parameter or all parameters under a path
cartesian returns the cartesian product of lists

可以运行 ​​ansible-doc -t lookup PLUGIN_NAME​​ 命令。我们随便看一个模块

┌──[[email protected]]-[~/ansible]
└─$ansible-doc -t lookup vars
> VARS (/usr/lib/python2.7/site-packages/ansible/plugins/lookup/vars.py)

Retrieves the value of an Ansible variable.

* This module is maintained by The Ansible Community
OPTIONS (= is mandatory):

= _terms
The variable names to look up.
......

嗯,获取一个Ansible变量的值,顺便研究下代码怎么写

┌──[[email protected]]-[~/ansible]
└─$cat /usr/lib/python2.7/site-packages/ansible/plugins/lookup/vars.py
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

## 一些模块的说明
DOCUMENTATION = """
lookup: vars
author: Ansible Core
version_added: "2.5"
short_description: Lookup templated value of variables
description:
- Retrieves the value of an Ansible variable.
options:
_terms:
description: The variable names to look up.
required: True
default:
description:
- What to return if a variable is undefined.
- If no default is set, it will result in an error if any of the variables is undefined.
"""
## 模块使用方法
。。。。

RETURN = """
_value:
description:
- value of the variables requested.
"""

from ansible.errors import AnsibleError, AnsibleUndefinedVariable
from ansible.module_utils.six import string_types
from ansible.plugins.lookup import LookupBase


class LookupModule(LookupBase):
##只有一个方法,接收所有参数
def run(self, terms, variables=None, **kwargs):
# variables不为none的话
if variables is not None:
self._templar.available_variables = variables
myvars = getattr(self._templar, '_available_variables', {})

self.set_options(direct=kwargs)
default = self.get_option('default')

ret = []
for term in terms:
if not isinstance(term, string_types):
raise AnsibleError('Invalid setting identifier, "%s" is not a string, its a %s' % (term, type(term)))

try:
try:
value = myvars[term]
except KeyError:
try:
value = myvars['hostvars'][myvars['inventory_hostname']][term]
except KeyError:
raise AnsibleUndefinedVariable('No variable found with this name: %s' % term)

ret.append(self._templar.template(value, fail_on_undefined=True))
except AnsibleUndefinedVariable:
if default is not None:
ret.append(default)
else:
raise

return ret

可以看到,和回调插件的编写方式类似,继承基类,重写方法。主要用于根据变量名获取当前剧本中的变量,变量名可以是经过运行的变量,我编写一个Demo来测试下

---
- name: vars Demo
hosts: master
tasks:
- name: Show value of 'variablename'
debug:
msg: "{{ lookup('vars', 'variabl' + myvar)}}"
vars:
variablename: hello
myvar: ename

- name: Show default empty since i dont have 'variablnotename'
debug:
msg: "{{ lookup('vars', 'variabl' + myvar, default='变量不存在')}}"
vars:
variablename: hello
myvar: notename

- name: Produce an error since i dont have 'variablnotename'
debug:
msg: "{{ lookup('vars', 'variabl' + myvar)}}"
ignore_errors: True
vars:
variablename: hello
myvar: notename

- name: find several related variables
debug:
msg: "{{ lookup('vars', 'ansible_play_hosts', 'ansible_play_batch', 'ansible_play_hosts_all') }}"

- name: alternate way to find some 'prefixed vars' in loop
debug:
msg: "{{ lookup('vars', 'ansible_play_' + item) }}"
loop:
- hosts
- batch
- hosts_all
┌──[[email protected]]-[~/ansible]
└─$ansible-playbook vars.yaml

PLAY [vars Demo] ****************************************************************

TASK [Gathering Facts] **********************************************************
ok: [192.168.26.81]

TASK [Show value of 'variablename'] *********************************************
ok: [192.168.26.81] => {
"msg": "hello"
}

TASK [Show default empty since i dont have 'variablnotename'] *******************
ok: [192.168.26.81] => {
"msg": "变量不存在"
}

TASK [Produce an error since i dont have 'variablnotename'] *********************
fatal: [192.168.26.81]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: No variable found with this name: variablnotename\n\nThe error appears to be in '/root/ansible/vars.yaml': line 19, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Produce an error since i dont have 'variablnotename'\n ^ here\n"}
...ignoring

TASK [find several related variables] *******************************************
ok: [192.168.26.81] => {
"msg": [
[
"192.168.26.81"
],
[
"192.168.26.81"
],
[
"192.168.26.81"
]
]
}

TASK [alternate way to find some 'prefixed vars' in loop] ***********************
ok: [192.168.26.81] => (item=hosts) => {
"msg": [
"192.168.26.81"
]
}
ok: [192.168.26.81] => (item=batch) => {
"msg": [
"192.168.26.81"
]
}
ok: [192.168.26.81] => (item=hosts_all) => {
"msg": [
"192.168.26.81"
]
}

PLAY RECAP **********************************************************************
192.168.26.81 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1

┌──[[email protected]]-[~/ansible]
└─$

可以使用lookup和query来调用查找插件。使用方法与过滤器相似;指定函数的名称,并在括号中添加要调用的查找插件的名称以及该插件所需的所有参数。

调用lookup插件

可以使用两个​​ Jinja2 模板函数​​​(​​lookup 或 query​​)中的一个来调用插件。

这两种方法都具有和过滤器非常相似的语法。指定函数的名称,并在圆括号中指定要调用的​​lookup​​插件的名称和插件需要的任何参数。

通过lookup的file插件获取指定文件的内容,编写剧本

- name: lookup Demo
hosts: master
vars:
hosts: "{{ lookup('file', '/etc/hosts')}}"
tasks:
- debug:
var: hosts

模拟执行剧本

┌──[[email protected]]-[~/ansible]
└─$ansible-playbook jinja2.yaml -C
PLAY [lookup Demo] **********************************************************************************
TASK [Gathering Facts] ******************************************************************************ok: [192.168.26.81]
TASK [debug] ****************************************************************************************ok: [192.168.26.81] => {
"hosts": "127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4\n::1 localhost localhost.localdomain localhost6 localhost6.localdomain6\n192.168.26.81 vms81.liruilongs.github.io vms81\n192.168.26.82 vms82.liruilongs.github.io vms82\n192.168.26.83 vms83.liruilongs.github.io vms83"
}

PLAY RECAP ******************************************************************************************192.168.26.81 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

使用逗号分隔,可以在 file 插件中包含多个文件名:

- name: lookup Demo
hosts: master
vars:
issue: "{{ lookup( 'file','/etc/hosts','/etc/issue')}}"
tasks:
- debug:
var: issue

在​​Ansible 2.5​​​和更高版本中,可以使用​​query​​​函数,而不是​​ lookup​​​来调用​​查找插件​​​。两者之间的区别在于,​​query ​​​始终会返回⼀个更容易解析和使用的​​列表​​​,而不是返回​​逗号分隔的值​​。

┌──[[email protected]]-[~/ansible]
└─$ansible-playbook query.yaml
PLAY [query] **********************************************************************************
TASK [Gathering Facts] ************************************************************************
ok: [192.168.26.81]
TASK [debug] **********************************************************************************
ok: [192.168.26.81] => {
"param": [
"\\S\nKernel \\r on an \\m\n\n192.168.26.81",
"127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4\n::1 localhost localhost.localdomain localhost6 localhost6.localdomain6\n192.168.26.81 vms81.liruilongs.github.io vms81\n192.168.26.82 vms82.liruilongs.github.io vms82\n192.168.26.83 vms83.liruilongs.github.io vms83"
]
}
PLAY RECAP ************************************************************************************
192.168.26.81 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

┌──[[email protected]]-[~/ansible]
└─$
- name: query
hosts: master
vars:
param: "{{ query('file','/etc/issue','/etc/hosts')}}"
tasks:
- debug:
var: param

那这里有一个问题,​​lookup获取文件的内容适控制节点,还是被控节点,实际上是控制节点​

读取文件的内容

​file 插件​​​允许​​ Ansible​​ 将本地文件的内容加载到变量。来看一个传递SSH密钥的Demo

┌──[[email protected]]-[~/ansible]
└─$ssh [email protected] useradd fred
┌──[[email protected]]-[~/ansible]
└─$ssh [email protected] useradd naoko
┌──[[email protected]]-[~/ansible]
└─$
┌──[[email protected]]-[~/ansible]
└─$ssh-keygen -N '' -f fred.key
Generating public/private rsa key pair.
Your identification has been saved in fred.key.
Your public key has been saved in fred.key.pub.
The key fingerprint is:
SHA256:AABygrfjKr2zllYikm0DCbxHaEvt/5fLwN6jY/OaXN8 [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|*.=.. |
|+B.o . |
|+o=. . |
|oooo . |
| =... S |
|+ * ... |
|.= = .o .. |
|o * o=*+. . |
|.oo+ .*B=o. E |
+----[SHA256]-----+
┌──[[email protected]]-[~/ansible]
└─$ssh-keygen -N '' -f naoko.key
Generating public/private rsa key pair.
Your identification has been saved in naoko.key.
Your public key has been saved in naoko.key.pub.
The key fingerprint is:
SHA256:UDtUESSooboZtIungph4VJoLa3mwVqekwp6wdoExwaI [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|. .+o=o |
|.o . .o o |
|o .. o. o |
|E+. o . . |
|..=+ S |
|++++ . |
|BOO.+ |
|&@=+ |
|X*o |
+----[SHA256]-----+
┌──[[email protected]]-[~/ansible]
└─$
┌──[[email protected]]-[~/ansible]
└─$ls | grep key
fred.key
fred.key.pub
naoko.key
naoko.key.pub
- name: Add authorized keys
hosts: 192.168.26.82
vars:
users:
- fred
- naoko
tasks:
- name: Add keys
authorized_key:
user: "{{ item }}"
key: "{{ lookup('file',item + '.key.pub')}}"
loop: "{{ users }}"
┌──[[email protected]]-[~/ansible]
└─$ansible-playbook file_vars.yaml

PLAY [Add authorized keys] **************************************************************************

TASK [Gathering Facts] ******************************************************************************
ok: [192.168.26.82]

TASK [Add keys] *************************************************************************************
changed: [192.168.26.82] => (item=fred)
changed: [192.168.26.82] => (item=naoko)

PLAY RECAP ******************************************************************************************
192.168.26.82 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
┌──[[email protected]]-[~/ansible]
└─$ssh -i fred.key [email protected] id
uid=1001(fred) gid=1001(fred) 组=1001(fred)
┌──[[email protected]]-[~/ansible]
└─$ssh -i naoko.key [email protected] id
uid=1002(naoko) gid=1002(naoko) 组=1002(naoko)
┌──[[email protected]]-[~/ansible]
└─$

对于公钥的获取,也可以直接通过变量拼接,不使用运算符。

key: "{{ lookup('file', '{{ item }}.key.pub')}}"

如果文件是​​JSON 或 YAML​​​格式,可以使用​​from_yaml 或 from_json​​过滤器将其解析为正确结构化的数据:

我们读取一个pod资源文件试试

---
- name: yaml to vars
hosts: 192.168.26.82
tasks:
- name: show yaml
debug:
var: " lookup('file', 'static-pod.yaml') | from_yaml"

---
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod-static
name: pod-static
namespeace: default
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod-demo
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
┌──[[email protected]]-[~/ansible]
└─$ansible-playbook file_yaml.yaml

PLAY [yaml to vars] *********************************************************************************

TASK [Gathering Facts] ******************************************************************************
ok: [192.168.26.82]

TASK [show yaml] ************************************************************************************
ok: [192.168.26.82] => {
" lookup('file', 'static-pod.yaml') | from_yaml": {
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": null,
"labels": {
"run": "pod-static"
},
"name": "pod-static",
"namespeace": "default"
},
"spec": {
"containers": [
{
"image": "nginx",
"imagePullPolicy": "IfNotPresent",
"name": "pod-demo",
"resources": {}
}
],
"dnsPolicy": "ClusterFirst",
"restartPolicy": "Always"
},
"status": {}
}
}

PLAY RECAP ******************************************************************************************
192.168.26.82 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

json也是一样的,我们来看一下,这是传递一个docker加速器设置

┌──[[email protected]]-[~/ansible]
└─$cat daemon.json
{
"registry-mirrors": ["https://2tefyfv7.mirror.aliyuncs.com"]
}
┌──[[email protected]]-[~/ansible]
└─$cat file_json.yaml
---
- name: json to vars
hosts: 192.168.26.82
tasks:
- debug:
var: lookup('file', 'daemon.json') | from_json
┌──[[email protected]]-[~/ansible]
└─$ansible-playbook file_json.yaml

PLAY [json to vars] *********************************************************************************

TASK [Gathering Facts] ******************************************************************************
ok: [192.168.26.82]

TASK [debug] ****************************************************************************************
ok: [192.168.26.82] => {
"lookup('file', 'daemon.json') | from_json": {
"registry-mirrors": [
"https://2tefyfv7.mirror.aliyuncs.com"
]
}
}

PLAY RECAP ******************************************************************************************
192.168.26.82 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

ini插件查询控制节点ini格式文件特定参数值。

---
- name: lookup or query Play
hosts: 192.168.26.82
gather_facts: false
tasks:
- debug:
msg: >
first name in file /etc/foo. ini section liruilong is {{ lookup('ini', 'first_name lest_name section=liruilong file=/etc/foo.ini') }}
┌──[[email protected]]-[~/ansible]
└─$ansible-playbook file_ini.yaml

PLAY [lookup or query Play] ********************************************************************************************

TASK [debug] ***********************************************************************************************************
ok: [192.168.26.82] => {
"msg": "first name in file /etc/foo. ini section liruilong is []\n"
}

PLAY RECAP *************************************************************************************************************
192.168.26.82 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

使用模板应用数据

与​​file​​​插件一样​​,template ​​​插件也会返回文件的内容,不同之处在于,​​template ​​​插件预期文件内容为 Jinja2 模
板,并在应用之前评估该模板。

┌──[[email protected]]-[~/ansible]
└─$echo "hello {{ name }}" > hello.j2
---
- name: template Demo
hosts: 192.168.26.82
vars:
name: liruilong
tasks:
- name: mes deml
debug:
var: lookup('template', 'hello.j2')
┌──[[email protected]]-[~/ansible]
└─$ansible-playbook template_demo.yaml
[WARNING]: Found variable using reserved name: name

PLAY [template Demo] ********************************************************************************

TASK [Gathering Facts] ******************************************************************************
ok: [192.168.26.82]

TASK [mes deml] *************************************************************************************
ok: [192.168.26.82] => {
"lookup('template', 'hello.j2')": "hello liruilong\n"
}

PLAY RECAP ******************************************************************************************
192.168.26.82 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

读取控制节点上的环境变量

env插件查询控制节点环境变量。当控制主机是容器化的应用程序,并且将环境变量注入configmap和secret到主机中时,此功能很有用。

---
- name: lookup or query play
hosts: 192.168.26.82
tasks:
- name: show env LANG
debug:
var: lookup('env', 'LANG')
- name: show env
debug:
var: ansible_env
PLAY [lookup or query play] ********************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [192.168.26.82]

TASK [show env LANG] ***************************************************************************************************
ok: [192.168.26.82] => {
"lookup('env', 'LANG')": "zh_CN.UTF-8"
}

TASK [show env] ********************************************************************************************************
ok: [192.168.26.82] => {
"ansible_env": {
"HOME": "/root",
"LANG": "zh_CN.UTF-8",
"LESSOPEN": "||/usr/bin/lesspipe.sh %s",
"LOGNAME": "root",
"LS_COLORS": "rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:",
"MAIL": "/var/mail/root",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
"PWD": "/root",
"SHELL": "/bin/bash",
"SHLVL": "2",
"SSH_CLIENT": "192.168.26.81 43056 22",
"SSH_CONNECTION": "192.168.26.81 43056 192.168.26.82 22",
"SSH_TTY": "/dev/pts/0",
"TERM": "xterm-256color",
"USER": "root",
"XDG_RUNTIME_DIR": "/run/user/0",
"XDG_SESSION_ID": "2",
"_": "/usr/bin/python"
}
}

PLAY RECAP *************************************************************************************************************
192.168.26.82 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

读取控制节点执行命令输出

​pipe ​​​和​​lines​​​插件都在​​Ansible​​​控制节点上​​运行命令,并返回输出​​​。​​pipe 插件​​​返回命令生成的原始输出,​​lines 插件​​将该命令的输出拆分为行。

---
- name: pipe & lines demo
hosts: 192.168.26.82
tasks:
- name: pipe demo
debug:
var: lookup('pipe' , 'pwd','uname -a','ls -l k8s-volume-create/')
- name: lines demo
debug:
var: lookup('lines', 'pwd','uname -a','ls -l k8s-volume-create/')
┌──[[email protected]]-[~/ansible]
└─$ansible-playbook pipe_demo.yaml

PLAY [pipe & lines demo] ****************************************************************************

TASK [Gathering Facts] ******************************************************************************
ok: [192.168.26.82]

TASK [pipe demo] ************************************************************************************
ok: [192.168.26.82] => {
"lookup('pipe' , 'pwd','uname -a','ls -l k8s-volume-create/')": "/root/ansible,Linux vms81.liruilongs.github.io 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux,总用量 40\ndrwxr-xr-x 2 root root 135 12月 1 19:54 nfsdy\n-rw-r--r-- 1 root root 442 12月 1 23:04 pod_storageclass.yaml\n-rw-r--r-- 1 root root 438 11月 27 17:14 PodVolumeHostPath.yaml\n-rw-r--r-- 1 root root 478 11月 28 11:10 podvolumenfs.yaml\n-rw-r--r-- 1 root root 695 11月 27 16:15 pod_volume_r.yaml\n-rw-r--r-- 1 root root 206 11月 28 17:17 pod_volumes-pvc.yaml\n-rw-r--r-- 1 root root 442 11 月 28 17:43 pod_volumespvc.yaml\n-rw-r--r-- 1 root root 615 11月 27 15:51 pod_volumes.yaml\n-rw-r--r-- 1 root root 646 11月 27 15:28 pod_volume.yaml\n-rw-r--r-- 1 root root 330 11月 28 17:18 pod_volunms-pv.yaml\n-rw-r--r-- 1 root root 199 12月 1 20:15 pvc_nfs.yaml"
}

TASK [lines demo] ***********************************************************************************
ok: [192.168.26.82] => {
"lookup('lines', 'pwd','uname -a','ls -l k8s-volume-create/')": "/root/ansible,Linux vms81.liruilongs.github.io 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux,总用量 40,drwxr-xr-x 2 root root 135 12月 1 19:54 nfsdy,-rw-r--r-- 1 root root 442 12月 1 23:04 pod_storageclass.yaml,-rw-r--r-- 1 root root 438 11月 27 17:14 PodVolumeHostPath.yaml,-rw-r--r-- 1 root root 478 11月 28 11:10 podvolumenfs.yaml,-rw-r--r-- 1 root root 695 11月 27 16:15 pod_volume_r.yaml,-rw-r--r-- 1 root root 206 11月 28 17:17 pod_volumes-pvc.yaml,-rw-r--r-- 1 root root 442 11月 28 17:43 pod_volumespvc.yaml,-rw-r--r-- 1 root root 615 11月 27 15:51 pod_volumes.yaml,-rw-r--r-- 1 root root 646 11月 27 15:28 pod_volume.yaml,-rw-r--r-- 1 root root 330 11月 28 17:18 pod_volunms-pv.yaml,-rw-r--r-- 1 root root 199 12月 1 20:15 pvc_nfs.yaml"
}

PLAY RECAP ******************************************************************************************
192.168.26.82 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

看一个简单的

┌──[[email protected]]-[~/ansible]
└─$ansible master -m debug -a "msg={{ query('lines', 'ls /etc/host*')}}"
192.168.26.81 | SUCCESS => {
"msg": [
"/etc/host.conf",
"/etc/hostname",
"/etc/hosts",
"/etc/hosts.allow",
"/etc/hosts.deny"
]
}

​lookup​​​使用​​fileglob​​插件,返回逗号分隔的文件名清单。

┌──[[email protected]]-[~/ansible]
└─$ansible master -m debug -a "msg={{ lookup('fileglob', '/etc/hosts*') }}"
192.168.26.81 | SUCCESS => {
"msg": "/etc/hosts,/etc/hosts.allow,/etc/hosts.deny"
}

​query​​​使用​​fileglob​​插件,强制返回文件列表值。

┌──[[email protected]]-[~/ansible]
└─$ansible master -m debug -a "msg={{ query('fileglob', '/etc/hosts*') }}"
192.168.26.81 | SUCCESS => {
"msg": [
"/etc/hosts",
"/etc/hosts.allow",
"/etc/hosts.deny"
]
}

从 URL 获取内容

url 插件从 URL 获取内容:

┌──[[email protected]]-[~/ansible]
└─$ansible master -m debug -a "msg={{ query('url', 'https://liruilongs.github.io/') }}"
192.168.26.81 | SUCCESS => {
"msg": [
"<!doctype html>",
"<html lang=\"zh\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\"><meta><title>山河已无恙</title><link rel=\"manifest\" href=\"/manifest.json\"><meta name=\"application-name\" content=\"山河已无恙\"><meta name=\"msapplication-TileImage\" content=\"https://cdn.jsdelivr.net/gh/removeif/removeif-demo@latest/img/favicon.png\"><meta name=\"apple-mobile-web-app-capable\" content=\"yes\"><meta name=\"apple-mobile-web-app-title\" content=\"山河已无恙\"><meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\"><meta property=\"og:type\" content=\"blog\"><meta property=\"og:title\" content=\"山河已无恙\"><meta property=\"og:url\" ....

同时具有许多选项用于控制身份验证、web代理或将结果拆分为行等。

从 Kubernetes API 获取信息

k8s 插件通过​​ openshift Python 模块​​提供对 Kubernetes API 的完全访问权限。必须使用 kind 选项来提供对象类型:

- name: k8s demo
hosts: 192.168.26.81
tasks:
- name: debug demo k8s
debug:
var: lookup('k8s',kind='pod',namespect='kube-system',resource_name='kube-proxy')

注意:k8s 插件是一个 lookup 插件,主要用途是从 Kubernetes 集群提取信息,而不是对其进行更新。使用 k8s模块来管理 Kubernetes 集群。

- name: Fetch all deployments 
set_fact:
deployments: "{{ lookup(k8s',kind='Deployment)}"
- name: Fetch all deployments in a namespace
set_fact:
deployments: "{{ lookup(k8s',kind='Deployment',namespace='testing)}}"
- name: Fetch a specific deployment by name
set_fact:
deployments: {{ lookup(k8s',kind='Deployment',namespace='testing, resource_name='elastic)}}
- name: Fetch with label selector
set_fact:
service: "{{ lookup('k8s',kind='Service',label_ selector='app=galaxy') }}"

这个Demo有问题,之后需要在看下

查询插件etcd,redis,mongodb还可以从数据库中获取信息。

┌──[[email protected]]-[~/ansible]
└─$ansible-doc -t lookup etcd
┌──[[email protected]]-[~/ansible]
└─$ansible master -m debug -a "msg={{ lookup('etcd', 'foo')}} "
192.168.26.81 | SUCCESS => {
"msg": ""
}
- name: a value from a locally running etcd
debug:
msg: "{{ lookup('etcd', 'foo/bar')}"
- name: "values from multiple folders on a locally running etcd"
debug:
msg: "{{ lookup('etcd', 'foo','bar','baz')}}"
- name: "since Ansible 2.5 you can set server options inline"
debug:
msg: "{{ lookup('etcd','foo', version='v2', url='http://192.168.0.27') }}"

password插件生成密码

password插件可用于创建用户密码,并保存在文件中。、

┌──[[email protected]]-[~/ansible]
└─$ansible 192.168.26.82 -m user -a "name=liruilong password={{ lookup('password','password-liruilong chars=digits lengt
h=6 encrypt=sha512_crypt') }}"
192.168.26.82 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1003,
"home": "/home/liruilong",
"name": "liruilong",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1003
}
┌──[[email protected]]-[~/ansible]
└─$cat password-liruilong
747437 salt=Uy3I0UCN
┌──[[email protected]]-[~/ansible]
└─$ssh [email protected]
[email protected]'s password:
[liruilong@vms82 ~]$

处理liikup错误

大多数 Ansible 插件可在失败时​​中止 Ansible Playbook​​​,但是,lookup 功能将执行委托给其它插件,这些插件可能​​不需要在失败时中止 Ansible Playbook。​

- name: error demo
hosts: 192.168.26.81
tasks:
- name: debug demo error
debug:
var: lookup('file', '/etc/passwd',error='warn') | default("Default file conten")

lookup 插件接受 ​​error​​ 参数:

  • error 选项的默认值为 ​​strict​​,如果基础脚本失败,lookup 插件会导致严重错误。
  • error 选项可以设置为 ​​warn​​,则 lookup 插件在基础脚本失败时记录警告并返回空字符串(或空列表)
  • error 选项可以设置为 ​​ignore​​,则 lookup 插件会以静默方式忽略错误,并返回空字符串(或空列表)

实战

本地生成密码远程批量创建用户

​读取文件创建用户​

$ cat users.txt
jonfoo
janebar
philbaz
$

编写剧本

$ cat site.yml
- name: Populate users from file
hosts: all
gather_facts: no
tasks:
- name: Create remote user
vars:
password: "{{ lookup('password', 'credentials/' + item + ' length=9') }}"
user:
name: "{{ item }}"
password: "{{ password | password_hash('sha512') }}"
update_password: on_create
state: present
loop: "{{ query('lines','cat users.txt') }}"
$
$ ansible-playbook  site.yml

PLAY [Populate users from file] ******************************************************************************

TASK [Create remote user] ************************************************************************************
changed: [serverf.lab.example.com] => (item=jonfoo)
changed: [serverf.lab.example.com] => (item=janebar)
changed: [serverf.lab.example.com] => (item=philbaz)

PLAY RECAP ***************************************************************************************************
serverf.lab.example.com : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ls credentials/* | xargs cat
4qj2fAR6_
FrQRx7XR4
DgJoh1e7:

博文参考


​《Red Hat Ansible Engine 2.8 DO447》​


标签:插件,38,name,ansible,192.168,Ansible,lookup,root
From: https://blog.51cto.com/u_13474506/5929828

相关文章

  • 如何编写清晰的Ansible剧本(复杂剧本如何构建)
    写在前面嗯,学习Ansible高级特性,整理这部分笔记博文内容涉及复杂Ansible剧本的编写规范一个具体的编写Demo食用方式:理论有些枯燥,不感兴趣小伙伴可以直接跳过去看Demo......
  • MBR20200FCT-ASEMI插件低压降肖特基二极管
    编辑:llMBR20200FCT-ASEMI插件低压降肖特基二极管型号:MBR20200FCT品牌:ASEMI封装:TO-220F正向电流:20A反向电压:200V引线数量:3芯片个数:2芯片尺寸:102MIL漏电流:10ua恢复时间:5ns浪涌......
  • Elasticsearch Head插件使用小结
    作者:崔雄华1ElasticsearchHead是什么ElasticSearchhead就是一款能连接ElasticSearch搜索引擎,并提供可视化的操作页面对ElasticSearch搜索引擎进行各种设置和数据检索功能......
  • fluentd中,当设置多个worker进程时,如何将插件与进程进行绑定?
    设置多worker进程 当通过如下的命令,设置多个worker进程时: <system>workers4</system> 示例配置 可以特定的插件与进程进行绑定,如:<system>worke......
  • MBR20200FCT-ASEMI插件低压降肖特基二极管
    编辑:llMBR20200FCT-ASEMI插件低压降肖特基二极管型号:MBR20200FCT品牌:ASEMI封装:TO-220F正向电流:20A反向电压:200V引线数量:3芯片个数:2芯片尺寸:102MIL漏电流:10ua恢......
  • 一起来写 VS Code 插件:为你的团队提供常用代码片段
    前言VSCode是前端开发者最佳的开发工具,你在开发中是否疲倦了从一个文件拷贝来新建一个文件呢?或者在你的团队内部是否有一些内部组件库,比如AntDesign、Reacthooks等组......
  • fluentd中,sample输入插件的作用是什么?
    in_sample输入插件的作用是什么? sample输入插件,用来产生样本事件。主要用于:测试,调试,和压力测试。这个插件,包含在fluentd的核心代码中sample是由dummy插件而......
  • 如何实现ignite的安全插件(security plugin)
    Ignite可以实现自定义的安全插件,以下实现在2.13.0测试可行。1.如何实现自定义的安全插件第一步:需要定义一个提供插件的类,它会被IgniteKernal在启动时调用,主要实现的是cre......
  • [笔记]Volatility 取证工具使用以及Hollow插件使用
    ​​Volatility内存取证使用​​文章目录​​前言​​​​环境​​​​使用Dumpit生成内存镜像​​​​使用VMware的内存镜像​​​​安装Volatility​​​​使用HollowFind......
  • vb6怎么调用大漠插件
    首先下载大漠插件,版本是3.1233  https://wwon.lanzout.com/iNl8Xhfx75c打开vb6引用dm.dll创建两个变量 dimdm,ver鼠标点击事件PrivateSubCommand1_Click()v......