DO447使用过滤器和插件转换器--使用查找模板化外部数据

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: DO447使用过滤器和插件转换器--使用查找模板化外部数据

DO447使用过滤器和插件转换器–使用查找模板化外部数据

RHCSA专栏:戏说 RHCSA 认证

RHCE专栏:戏说 RHCE 认证

此文章(第四章 使用过滤器和插件转换器–使用查找模板化外部数据 )收录在RHCA专栏:RHCA 回忆录



📜官网:

📜2.1 查找插件(lookup plug-in)

查找插件是对Jinja2模板的扩展。这些插件使Ansible能够使用来自外部源的数据,比如文件和shell环境。


📜2.2 调用查找插件

您可以使用两个Jinja2模板函数之一(lookup或query)来调用查找插件。这两种方法的语法都非常类似于过滤器。指定函数的名称,并在括号中指定要调用的查找插件的名称和插件需要的任何参数。

例如,下面的变量定义使用文件查找插件将/etc/hosts文件的内容放入Ansible变量myhosts中:

vars:
  hosts: "{
    { lookup('file', '/etc/hosts') }}"

您可以在文件插件中包含多个文件名。当使用查找函数调用时。每个文件的内容在模板值中用逗号分隔。

vars:
  hosts: "{
    { lookup('file', '/etc/hosts', '/etc/issue') }}"

上面的Jinja2模板表达式会产生以下结构(换行):

image-20220414213453225

在Ansible 2.5及以后版本中,可以使用query函数代替lookup来调用查找插件。两者之间的区别是,query返回的不是用逗号分隔的值,而是一个列表,这样更容易解析和处理。

前面的例子可以这样调用:

vars:
  hosts: "{
    { query('file', '/etc/hosts', '/etc/issue') }}"

查询调用将返回这个数据结构(换行):

image-20220414213537444


📜2.3 选择查找插件

在默认的Ansible安装中有几十个插件可用。使用ansible-doc -t lookup -l命令获取可用查找插件的完整列表。关于特定插件的用途和使用方法,请执行ansible-doc -t lookup PLUGIN_NAME命令

下面介绍了一些最有用的插件:

📑读取文件的内容

file文件插件允许Ansible将本地文件的内容加载到一个变量中。如果您提供了一个相对路径,插件就会在剧本的文件目录中查找文件。

下面的示例读取用户公钥文件的内容,并使用authorized_key模块将授权密钥添加到托管主机。该示例使用循环和+操作符在模板中添加字符串,以便查找文件files/fred.key.pub和files/naoko.key.pub文件。

image-20220414213612990

使用file文件插件的一个有用的技巧是,如果文件是YAML或JSON格式的,可以使用from_yaml或from_json过滤器将其解析为适当结构的数据。

my_yaml: "{
    { lookup('file', '/path/to/my.yaml') | from_yaml }}"

**注意:**文件插件读取控制节点上的文件,而不是托管主机上的文件。


📑使用模板应用数据

与file文件插件一样,template模板插件返回文件的内容。不同之处在于template模板插件期望文件内容是Jinja2模板,并计算它的值在应用内容之前使用模板。如果您向模板文件传递一个相对路径,插件将在剧本的模板目录中查找它。

{
    {
     lookup('template', 'my.template.j2') }}

前面的示例将处理templates/my.template.js模板在你的剧本目录中。例如,假设模板的内容如下:

Hello {
    {
     name }}.

下面的任务将显示“Hello class.”。

image-20220414213734730

template模板插件允许一些额外的参数,比如定义开始和结束标记序列。如果输出字符串是YAML值,convert_data选项将解析该字符串以提供结构化数据


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

env插件从控制节点查询环境变量。当控制器主机是一个容器化的应用程序,并且配置映射和秘密被容器管理应用程序(如Kubernetes或Red Hat OpenShift)注入到主机中时,这是非常有用的。

{
    {
     lookup('env','MY_PASSWORD') }}

📑读取控制节点上的命令输出

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

假设您有以下jinj2表达式:

{
    {
     query('pipe', 'ls files') }}

这个表达式将以字符串形式返回ls命令的原始输出。如果使用lines插件,则表达式如下:

{
    {
     query('lines', 'ls files') }}

该命令生成一个列表,ls将每一行输出作为列表项返回。

这个功能的一个有趣的应用是获取一组命令的输出的第一行(或任何特定的行):

image-20220414213851736

注意:考虑到head命令的存在,此示例可能不是执行此特定任务的最有效方法。


📑从URL获取内容

file文件插件获取文件内容的方式类似,url插件从url获取内容。

{
    {
     lookup('url', 'https://my.site.com/my.file') }}

有许多选项可用于控制身份验证、选择web代理或将返回的内容分成行。

然而,使用URL插件的一个优点是,您可以将返回的数据作为变量中的值使用,可能首先使用过滤器处理它。


📑从Kubernetes API获取信息

k8s插件通过openshift Python模块提供了对Kubernetes API的完全访问。要获取Kubernetes对象,必须使用kind选项提供对象类型。提供额外的对象细节,比如namespace命名空间选项或label_selector选项,有助于过滤结果:

{
    {
     lookup('k8s', kind='Deployment', namespace='ns', resource_name='my_res') }}

注意:当Ansible Playbook管理时,使用openshift作为k8s插件的别名Red Hat OpenShift容器平台实例。

注意:k8s插件是一个查找插件。它的主要目的是从Kubernetes集群中提取信息,而不是更新它。使用k8s模块来管理Kubernetes集群。


📜2.4 处理查找错误

大多数Ansible插件被设计为在失败时中止Ansible Playbook。但是,查找函数将执行委托给其他插件,这些插件可能不需要在失败时中止Ansible Playbook。例如,如果没有找到该文件,该文件插件可能不需要中止Ansible Playbook,但可能需要通过创建丢失的文件来恢复。

为了适应不同的插件需求,查找插件接受错误参数。

{
    {
     lookup('file', 'my.file', errors='warn') | default("Default file content") }}

error错误选项的默认值是strict。这意味着如果底层脚本失败,lookup查找插件将引发致命错误。如果错误选项的值为warn,则当底层脚本失败并返回空字符串(或空列表)时,查找插件将记录一个警告。如果错误选项的值为ignore,则查找插件将静默地忽略该错误并返回一个空字符串或列表。


📜2.5 课本练习

[student@workstation ~]$ lab data-lookups start

📑第一部分

这个练习由两个部分组成,使用不同的目录。在第一节中,您将创建一个Ansible Playbook,将在纯文本文件中定义的所有用户填充到托管主机中。

📑按要求编写剧本

[student@workstation ~]$ cd ~/DO447/labs/data-lookups/users
# 读取文件内容的方法有很多种,但是在这里将使用行查找插件。
"{
    {
     query('lines','cat users.txt') }}"
# 这个插件读取cat用户的输出作为单行。查询函数将每行拆分为一个列表项。
# Ansible任务需要遍历这个简单列表中的用户。可以使用loop来做到这一点:
loop: "{
    { query('lines','cat users.txt') }}"

[student@workstation users]$ vim site.yml
- name: Populate users from file
  hosts: all
  gather_facts: no
  tasks:
    - name: Create remote user
      debug:
        msg: "To be done"
      loop: "{
    { query('lines','cat users.txt') }}"

# 在创建用户时,创建一个随机密码。password lookup密码查找插件生成随机密码,并可选地将密码存储在本地文件中。
# 前面的步骤在用户上添加了循环,因此可以使用相同的项为每个用户生成相关联的文件。
"{
    {
     lookup('password', 'credentials/' + item + ' length=9') }}"
# 将密码存储到一个任务变量中,以便于使用。该Yml文件应该如下所示。注意 ' length=9' 中第一个单引号后要包含空格

- name: Populate users from file
  hosts: all
  gather_facts: no
  tasks:
    - name: Create remote user
      vars:
        password: "{
    { lookup('password', 'credentials/' + item + ' length=9') }}"
      debug:
        msg: "To be done"
      loop: "{
    { query('lines','cat users.txt') }}"

# 注意,在使用刚才创建的密码之前,应该对其进行散列处理。update_password: on_create选项只在用户不存在时设置密码。如果用户已经存在,且密码不一致,则不修改密码。

- 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
      loop: "{
    { query('lines','cat users.txt') }}"

📑运行剧本并验证

[student@workstation users]$ ansible-playbook site.yml
[student@workstation users]$ ssh jonfoo@serverf "cat /etc/passwd"
devops:x:1001:1001::/home/devops:/bin/bash
jonfoo:x:1002:1002::/home/jonfoo:/bin/bash
janebar:x:1003:1003::/home/janebar:/bin/bash
philbaz:x:1004:1004::/home/philbaz:/bin/bash

📑清除实验

[student@workstation users]$ ansible-playbook clean.yml
[student@workstation users]$ ssh serverf "grep jonfoo /etc/passwd"; echo $?
1

📑第二部分

在这个指导练习的第二部分中,将使用查找插件来国际化前面章节中部署的静态web应用程序。每个服务器提供本地化数据应用程序的版本,基于它自己配置的语言环境。如果没有配置语言环境,服务器将使用控制器提供的语言环境。

静态应用程序包含用于部署的项目版本,也称为Infrastructure-as-Code版本(laC版本)。为了简单起见,使用项目的Git提交id作为Ansible项目的laC版本。

📑明确模板

[student@workstation ~]$ cd ~/DO447/labs/data-lookups/i18n/
[student@workstation i18n]$ cat roles/webapp/templates/webapp.en_US.UTF-8.j2
Greetings from {
    {
     inventory_hostname }}.
App Version: {
    {
     webapp_version}}
IaC Version: {
    {
     iac_version }}
[student@workstation i18n]$ cat roles/webapp/templates/webapp.es_ES.UTF-8.j2
Saludos desde {
    {
     inventory_hostname }}.
App Version: {
    {
     webapp_version}}
IaC Version: {
    {
     iac_version }}

📑按要求编写默认变量

要获取控制器主机的区域设置,可以使用env查找插件来检索LANG环境变量的值。在环境变量不可用的情况下,提供一个默认值也是一个好的实践:

controller_lang: "{
    { lookup('env','LANG') | default('en_US.UTF-8') }}"

使用git rev-parse --short HEAD命令获取当前的Ansible项目提交id。使用管道查找来指示Ansible执行该命令:

iac_version: "{
    { lookup('pipe', 'git rev-parse --short HEAD') | quote }}"

注意:quote引号过滤器用于清除字符串中不合适的字符。在这种情况下,git命令不会返回任何有害字符,但是在使用来自外部来源的输入时,使用quote过滤器是一个很好的安全实践。

[student@workstation i18n]$ vim roles/webapp/defaults/main.yml
controller_lang: "{
    { lookup('env','LANG') | default('en_US.UTF-8') }}"
iac_version: "{
    { lookup('pipe', 'git rev-parse --short HEAD')|quote }}"
webapp_version: v1.0

📑编写主任务中页面内容

[student@workstation i18n]$ vim roles/webapp/tasks/main.yml
---
- name: Ensure stub web content is deployed
  vars:
    locale: "{
    { ansible_facts.env.LANG | default(controller_lang) }}"
  copy:
    content: "{
    { lookup('template','webapp.' + locale + '.j2') }}"
    dest: /var/www/html/index.html

📑设置系统环境变量并执行剧本

[student@workstation i18n]$ LANG=en_US.UTF-8
[student@workstation i18n]$ ansible-playbook site.yml

📑验证执行情况

[student@workstation i18n]$ curl servera
Saludos desde serverb.lab.example.com.

App Version: v1.1a
IaC Version: f716bbe
[student@workstation i18n]$ curl servera
Greetings from serverc.lab.example.com.

App Version: v1.1b
IaC Version: f716bbe
[student@workstation i18n]$ ansible web_servers -m shell -a "printenv LANG" 
serverb.lab.example.com | CHANGED | rc=0 >>
es_ES.UTF-8

serverc.lab.example.com | FAILED | rc=1 >>
non-zero return code

📑清除实验

[student@workstation i18n]$ ansible-playbook clean.yml
[student@workstation ~]$ lab data-lookups finish

💡总结

RHCA认证需要经历5门的学习与考试,还是需要花不少时间去学习与备考的,好好加油,可以噶🤪。

以上就是【金鱼哥】对 第四章 使用过滤器和插件转换器–使用查找模板化外部数据 的简述和讲解。希望能对看到此文章的小伙伴有所帮助。

如果这篇【文章】有帮助到你,希望可以给【金鱼哥】点个赞👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【运维技术】感兴趣,也欢迎关注❤️❤️❤️ 【金鱼哥】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
7天前
|
SQL Java 数据库连接
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
|
3月前
|
开发框架 缓存 前端开发
基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换
基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换
|
4月前
uniapp实战 —— 轮播图【自定义指示点】(含组件封装,自动注册全局组件,添加全局组件类型声明)
uniapp实战 —— 轮播图【自定义指示点】(含组件封装,自动注册全局组件,添加全局组件类型声明)
256 1
|
6月前
|
JavaScript 前端开发 算法
< 封装公共导出模块:配合element实现提示 >
在 Vue + elementUi 开发中,我们偶尔会遇到需要导出的列表,或者指定位置的导出内容。在一个项目里面是十分常见的,但是由于导出代码有稍微有点长,不方便维护!基于项目开发需求,封装了一个公用的导出模块,模块入口提供了 四个参数,分别是:导出接口地址导出参数对象导出文件名称导出时选择的服务地址(需要配合config文件实现选择功能)。且基于信息安全问题,实现信息提示,当提示点击遵守规则才允许下载文件!
< 封装公共导出模块:配合element实现提示 >
|
数据安全/隐私保护
fastadmin中写接口是时Validate规则验证自定义如何用
fastadmin中写接口是时Validate规则验证自定义如何用
228 0
|
6月前
|
存储 Python
自定义模板过滤器
自定义模板过滤器
39 1
|
XML Java 应用服务中间件
Filter 过滤器--基本原理--Filter 过滤器生命周期--过滤器链--注意事项和细节--全部应用实例--综合代码示例
Filter 过滤器--基本原理--Filter 过滤器生命周期--过滤器链--注意事项和细节--全部应用实例--综合代码示例
168 0
xxlsso框架设置不需要过滤的路径
xxlsso框架设置不需要过滤的路径
40 0
过滤器简介--操作步骤--过滤器生命周期--过滤器匹配规则-- 过滤器链
过滤器简介--操作步骤--过滤器生命周期--过滤器匹配规则-- 过滤器链
65 0
|
开发者 Python
自定义模块的使用|学习笔记
快速学习自定义模块的使用