到目前为止,模块是我们通过 Ansible 旅程中非常明显和关键的一部分。它们用于执行定义明确的任务,既可以用于一次性命令(使用临时命令),也可以作为更大剧本的一部分。插件对 Ansible 来说同样重要,到目前为止,我们在所有的测试中都使用了它们,甚至没有意识到这一点!虽然模块总是用来在 Ansible 中创建某种任务,但是插件的使用方式取决于它们的用例。有许多不同类型的插件;我们将在本章中向您介绍它们,并让您了解它们的用途。但是,作为一名体验者,你有没有意识到,当 Ansible 使用 SSH 连接到远程服务器时,功能是由连接插件提供的?这证明了插件的重要作用。
在本章中,我们将为您提供插件的深入介绍,并向您展示如何探索 Ansible 附带的各种插件。然后,我们将通过演示如何创建自己的插件并在 Ansible 项目中使用它们来对此进行扩展,这与我们在上一章中使用自定义模块的方式非常相似。这将有望帮助你理解像 Ansible 这样的开源软件所提供的无限可能性。
在本章中,我们将涵盖以下主题:
- 发现插件类型
- 查找包含的插件
- 创建自定义插件
本章假设您已经使用 Ansible 设置了控制主机,详见第 1 章、ansi ble 入门,并且您使用的是最新版本。本章中的示例用 Ansible 2.9 进行了测试。本章还假设您至少有一个要测试的附加主机;理想情况下,这应该是基于 Linux 的。
虽然我们将在本章中给出主机名的具体示例,但是您可以自由地用自己的主机名和/或 IP 地址来替换它们,并且如何做到这一点的详细信息将在适当的地方提供。本章涉及的插件开发工作假设您的计算机上存在 Python 2 或 Python 3 开发环境,并且您正在运行 Linux、FreeBSD 或 macOS。如果需要额外的 Python 模块,它们的安装将被记录下来。构建模块文档的任务在 Python 3.5 或更高版本中有一些非常具体的要求,因此假设您希望尝试这样做,可以安装一个合适的 Python 环境。
本章的代码包可在https://github . com/packt publishing/Ansible-2-cook book/tree/master/Chapter % 206上获得。
正如我们在前面章节中所讨论的,插件在 Ansible 中并不像它们的模块对应物那样明显,但是我们已经在幕后使用了它们,在我们到目前为止发布的每一个 Ansible 命令中!让我们在前一节的工作的基础上继续努力,在这一节中,我们通过查看哪里可以找到插件的源代码来查看插件文档。这反过来将成为我们构建自己的简单插件的先驱。
如果您使用软件包管理器(即通过 RPM 或 DEB 软件包)在 Linux 系统上安装了 Ansible,那么插件的位置将取决于您的操作系统。例如,在我测试的 CentOS 7 系统上,我从官方 RPM 包中安装了 Ansible,我可以在这里看到安装的插件:
$ ls /usr/lib/python2.7/site-packages/ansible/plugins/
action cliconf httpapi inventory lookup terminal
become connection __init__.py loader.py netconf test
cache doc_fragments __init__.pyc loader.pyc shell vars
callback filter __init__.pyo loader.pyo strategy
注意插件是如何被分成子目录的,所有的子目录都是以它们的类别命名的。如果我们想查找我们在前面章节中查看过的paramiko_ssh
插件,我们可以在connection/
子目录中查找:
$ ls -l /usr/lib/python2.7/site-packages/ansible/plugins/connection/paramiko_ssh.py
-rw-r--r-- 1 root root 23544 Mar 5 05:39 /usr/lib/python2.7/site-packages/ansible/plugins/connection/paramiko_ssh.py
但是,一般来说,我不建议您编辑或更改从软件包安装的文件,因为升级软件包时,您可能很容易覆盖它们。由于本章的目标之一是编写我们自己的简单定制插件,让我们看看如何在官方的 Ansible 源代码中找到插件:
- 从 GitHub 中克隆官方 Ansible 存储库,就像我们之前所做的那样,并将目录更改为您的克隆位置:
$ git clone https://github.com/ansible/ansible.git
$ cd ansible
- 在官方的源代码目录结构中,你会发现插件都包含在
lib/ansible/plugins/
下(同样,在分类子目录中):
$ cd lib/ansible/plugins
- 我们可以通过查看
connection
目录来探索基于连接的插件:
$ ls -al connection/
该目录的确切内容将取决于您所克隆的 Ansible 源代码的版本。在撰写本文时,它看起来如下,每个插件有一个 Python 文件(类似于我们在第 5 章、消费和创建模块中看到的每个模块有一个 Python 文件):
$ ls -al connection/
total 176
drwxr-xr-x 2 root root 109 Apr 15 17:24 .
drwxr-xr-x 19 root root 297 Apr 15 17:24 ..
-rw-r--r-- 1 root root 16411 Apr 15 17:24 __init__.py
-rw-r--r-- 1 root root 6855 Apr 15 17:24 local.py
-rw-r--r-- 1 root root 23525 Apr 15 17:24 paramiko_ssh.py
-rw-r--r-- 1 root root 32839 Apr 15 17:24 psrp.py
-rw-r--r-- 1 root root 55367 Apr 15 17:24 ssh.py
-rw-r--r-- 1 root root 31277 Apr 15 17:24 winrm.py
- 您可以查看每个插件的内容,了解它们的工作原理,这也是开源软件的魅力所在:
$ less connection/paramiko_ssh.py
下面的代码块显示了该文件开头的一个示例,让您了解如果该命令正确运行,您应该看到什么样的输出:
# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
# (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 = """
author: Ansible Core Team
connection: paramiko
short_description: Run tasks via python ssh (paramiko)
description:
- Use the python ssh implementation (Paramiko) to connect to targets
- The paramiko transport is provided because many distributions, in particular EL6 and before do not support ControlPersist
in their SSH implementations.
....
请注意DOCUMENTATION
块,它与我们在处理模块源代码时看到的非常相似。如果你探究每个插件的源代码,你会发现其结构与模块代码结构有些相似。然而,在下一节中,让我们开始构建我们自己的定制插件,通过一个实际的例子来学习它们是如何组合在一起的,而不是简单地从表面上理解这个陈述。
在这一部分,我们将带你通过一个关于创建你自己的插件的实用指南。这个例子必然很简单。然而,希望它能很好地指导你插件开发的原则和最佳实践,并为你构建更复杂的插件打下坚实的基础。我们甚至将向您展示如何将这些与您自己的行动手册集成,当您准备好之后,将它们提交给官方的 Ansible 项目进行包含。
正如我们在构建自己的模块时注意到的,Ansible 是用 Python 编写的,它的插件也不例外。因此,您将需要用 Python 编写您的插件;因此,要开始开发自己的插件,您需要确保安装了 Python 和一些基本工具。如果您的开发机器上已经运行了 Ansible,那么您可能已经安装了所需的软件包。但是,如果您从零开始,您将需要安装 Python、Python 包管理器(pip
)以及其他一些开发包。操作系统之间的具体过程会有很大的不同,但下面是一些让您开始的示例:
- 在 Fedora 上,您可以运行以下命令来安装所需的软件包:
$ sudo dnf install python python-devel
- 同样,在 CentOS 上,您可以运行以下命令来安装所需的软件包:
$ sudo yum install python python-devel
- 在 Ubuntu 上,您可以运行以下命令来安装您需要的包:
$ sudo apt-get update
$ sudo apt-get install python-pip python-dev build-essential
- 如果您正在使用 macOS 和自制包装系统,以下命令将安装您需要的软件包:
$ sudo brew install python
一旦您安装了所需的包,您将需要将 Ansible Git 存储库克隆到您的本地机器上,因为其中有一些有价值的脚本,我们将在模块开发过程中稍后需要它们。使用以下命令将 Ansible 存储库克隆到开发计算机上的当前目录:
$ git clone https://github.com/ansible/ansible.git
$ cd ansible
有了所有这些先决条件,让我们开始创建自己的插件。虽然编码模块和插件之间有许多相似之处,但也有根本的区别。事实上,Ansible 可以使用的每种不同类型的插件实际上编码略有不同,并且有不同的建议。遗憾的是,我们没有足够的篇幅来一一介绍这本书,但是您可以从官方 Ansible 文档中找到更多关于每种插件类型的要求,网址为https://docs . ansi ble . com/ansi ble/latest/dev _ guide/developing _ plugins . html。
对于我们的简单示例,我们将创建一个过滤器插件,用另一个字符串替换给定的字符串。如果您参考前面的文档链接,过滤器插件可能是最容易编码的插件,因为对文档的要求不像对模块那样严格。然而,如果我们要创建一个lookup
插件,我们应该创建与我们在第 5 章、消费和创建模块中创建的相同的DOCUMENTATION
、EXAMPLES
和RETURN
文档部分。我们还需要以同样的方式测试和构建我们的网络文档。
我们已经介绍了这一点,因此在本章中不再重复整个过程。相反,我们将首先专注于创建一个过滤器插件。与其他 Ansible 插件和模块相比,您实际上可以在一个 Python 插件文件中定义几个过滤器。过滤器本质上是非常紧凑的代码。它们也很多,所以每个过滤器只有一个文件不能很好地扩展。然而,如果你想编码其他类型的插件(比如lookup
插件),你将需要为每个插件创建一个 Python 文件。
让我们开始创建我们的简单过滤器插件。由于我们只创建了一个,它将存在于自己的单独 Python 文件中。如果您想将代码提交回 Ansible 项目,您可以建议对 Ansible 核心过滤器 Python 文件之一进行修改;但是现在,我们将把它作为一个项目留给你自己来完成。我们的过滤文件将被称为custom_filter.py
,它将位于名为filter_plugins
的目录中,该目录必须与您的行动手册位于同一目录中。
执行以下步骤来创建和测试您的插件代码:
- 用一个标题开始你的插件文件,这样人们就会知道是谁写的插件,以及它是在什么许可下发布的。当然,您应该用适合您的插件的值来更新版权和许可证字段,但是下面给出的文本是一个让您开始使用的示例:
# (c) 2020, James Freeman <james.freeman@example.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- 接下来,我们将添加一个非常简单的 Python 函数——您的函数可以像您希望的那样复杂,但是对于我们的函数,我们将简单地使用 Python
.replace
函数在string
变量中用另一个字符串替换一个字符串。以下示例查找Puppet
的实例,并用Ansible
替换它们:
def improve_automation(a):
return a.replace("Puppet", "Ansible")
- 接下来,我们需要创建一个
FilterModule
类的对象,这就是 Ansible 将如何知道这个 Python 文件包含一个过滤器。在这个对象中,我们可以创建一个filters
定义,并将我们之前定义的过滤函数的值返回给 Ansible:
class FilterModule(object):
'''improve_automation filters'''
def filters(self):
return {'improve_automation': improve_automation}
- 如您所见,这段代码非常简单,我们可以使用内置的 Python 函数,如
replace
,来操作字符串。Ansible 中没有插件的特定测试工具,所以我们将通过编写一个简单的剧本来测试我们的插件代码。下面的剧本代码定义了一个简单的字符串,其中包含单词Puppet
,并使用debug
模块将其打印到控制台,将我们新定义的过滤器应用到字符串中:
---
- name: Play to demonstrate our custom filter
hosts: frontends
gather_facts: false
vars:
statement: "Puppet is an excellent automation tool!"
tasks:
- name: make a statement
debug:
msg: "{{ statement | improve_automation }}"
现在,在我们尝试运行这个之前,让我们回顾一下目录结构应该是什么样子。正如我们能够利用我们在第 5 章、消费和创建模块中创建的定制模块一样,通过创建一个library/
子目录来存放我们的模块,我们也可以为我们的插件创建一个filter_plugins/
子目录。当您完成前面代码块中各种文件细节的编码后,您的目录树结构应该如下所示:
.
├── filter_plugins
│ ├── custom_filter.py
├── hosts
├── myplugin.yml
现在,让我们运行我们的小测试剧本,看看我们得到了什么输出。如果一切顺利,应该如下所示:
$ ansible-playbook -i hosts myplugin.yml
PLAY [Play to demonstrate our custom filter] ***********************************
TASK [make a statement] ********************************************************
ok: [frt01.example.com] => {
"msg": "Ansible is an excellent automation tool!"
}
PLAY RECAP *********************************************************************
frt01.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
如您所见,我们的新过滤器插件替换了变量内容中的Puppet
字符串,并将其替换为Ansible
字符串。当然,这只是一个愚蠢的测试,你不可能对 Ansible 项目做出贡献。然而,它展示了如何在仅仅六行代码和一点 Python 知识的情况下,创建我们自己的过滤器插件来操作字符串。我相信你能想出更复杂更有用的东西!
其他插件类型需要更多的努力;虽然我们不会在这里介绍创建过滤器插件的过程,但是您会发现编写过滤器插件更类似于编写模块,因为您需要执行以下操作:
- 将
DOCUMENTATION
、EXAMPLES
和RETURN
部分包含在适当的文档中。 - 确保你已经在插件中加入了适当和足够的错误处理。
- 彻底测试它,包括失败和成功的案例。
作为一个例子,让我们重复前面的过程,而是创建一个lookup
插件。这个插件将主要基于文件lookup
插件的简化版本。然而,我们希望修改我们的版本,只返回文件的第一个字符。您可以修改这个例子来读取文件的头,或者您可以给插件添加参数来允许您使用字符索引提取子串。我们将把这个增强活动作为一个练习留给你自己去完成。我们开始吧!我们新的查找插件将被称为firstchar
,由于lookup
插件与其 Python 文件有一对一的映射,插件文件将被称为firstchar.py
。(事实上,Ansible 将使用这个文件名作为插件的名称——你在代码中的任何地方都找不到对它的引用!).如果您打算从剧本中进行测试,如前所述,您应该在名为lookup_plugins/
的目录中创建:
- 像以前一样,从给插件文件添加一个头开始,这样维护者和版权细节就清楚了。我们借用了大量原始的
file.py
lookup
插件代码作为示例,因此我们必须包含相关的信用:
# (c) 2020, James Freeman <james.freeman@example.com>
# (c) 2012, Daniel Hokka Zakrisson <daniel@hozac.com>
# (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
- 接下来,添加 Python 3 头——如果你打算通过拉请求 ( PR )向 Ansible 项目提交你的插件,这些是绝对的要求:
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
- 接下来,给你的插件添加一个
DOCUMENTATION
块,这样其他用户就可以理解如何与之交互了:
DOCUMENTATION = """
lookup: firstchar
author: James Freeman <james.freeman@example.com>
version_added: "2.9"
short_description: read the first character of file contents
description:
- This lookup returns the first character of the contents from a file on the Ansible controller's file system.
options:
_terms:
description: path(s) of files to read
required: True
notes:
- if read in variable context, the file can be interpreted as YAML if the content is valid to the parser.
- this lookup does not understand 'globing', use the fileglob lookup instead.
"""
- 添加相关的
EXAMPLES
块来展示如何使用你的插件,就像我们对模块所做的那样:
EXAMPLES = """
- debug: msg="the first character in foo.txt is {{lookup('firstchar', '/etc/foo.txt') }}"
"""
- 此外,确保您记录了插件中的
RETURN
值:
RETURN = """
_raw:
description:
- first character of content of file(s)
"""
- 文档完成后,我们现在可以开始处理 Python 代码了。我们将从导入我们需要的所有 Python 模块开始,以使我们的模块工作。我们还将设置
display
对象,用于详细输出和调试。如果需要显示debug
输出,这应该用来代替插件代码中的print
语句:
from ansible.errors import AnsibleError, AnsibleParserError
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
display = Display()
- 我们现在将创建一个
LookupModule
类的对象。在其中定义一个名为run
的默认函数(这是 Ansiblelookup
插件框架所期望的),并为我们的返回数据初始化一个空数组:
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
ret = []
- 有了这个,我们将开始一个循环来迭代每个术语(在我们的简单插件中,是传递给插件的文件名)。虽然我们将只在简单的用例上测试这一点,但是查找插件的使用方式意味着它们需要支持
terms
的列表来操作。在这个循环中,我们显示了有价值的调试信息,最重要的是,定义了一个对象,该对象包含我们将要打开的每个文件的详细信息,称为lookupfile
:
for term in terms:
display.debug("File lookup term: %s" % term)
lookupfile = self.find_file_in_search_path(variables, 'files', term)
display.vvvv(u"File lookup using %s as file" % lookupfile)
- 现在,我们将读入文件内容。这可能就像使用一行 Python 代码一样简单,但是我们从我们在第 5 章、消费和创建模块中对模块的工作中知道,我们不应该想当然地认为我们将被传递一个我们实际上可以读取的文件。因此,我们将把读取文件内容的语句放入一个
try
块中,并实现异常处理,以确保插件的行为是明智的,即使在错误情况下,并且易于理解的错误消息被传递回用户,而不是 Python 回溯:
try:
if lookupfile:
contents, show_data = self._loader._get_file_contents(lookupfile)
ret.append(contents.rstrip()[0])
else:
raise AnsibleParserError()
except AnsibleParserError:
raise AnsibleError("could not locate file in lookup: %s" % term)
请注意,在这里,我们将文件内容的第一个字符(由[0]
索引表示)附加到我们的空数组中。我们还使用rstrip
移除任何训练空间。
- 最后,我们用
return
语句将从文件中收集的字符返回给 Ansible:
return ret
- 我们可以再次创建一个简单的测试剧本来测试我们新创建的插件:
---
- name: Play to demonstrate our custom lookup plugin
hosts: frontends
gather_facts: false
tasks:
- name: make a statement
debug:
msg: "{{ lookup('firstchar', 'testdoc.txt')}}"
同样,我们使用调试模块将输出打印到控制台,并引用我们的lookup
插件来获取输出。
- 创建上一个代码块中引用的文本文件,称为
testdoc.txt
。这可以包含您喜欢的任何内容—我的包含以下简单文本:
Hello
为了清楚起见,您的最终目录结构应该如下所示:
.
├── hosts
├── lookup_plugins
│ └── firstchar.py
├── myplugin2.yml
└── testdoc.txt
- 现在,当我们运行我们的新剧本时,我们应该会看到类似于以下内容的输出:
$ ansible-playbook -i hosts myplugin2.yml
PLAY [Play to demonstrate our custom lookup plugin] ****************************
TASK [make a statement] ********************************************************
ok: [frt01.example.com] => {
"msg": "H"
}
PLAY RECAP *********************************************************************
frt01.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
如果一切顺利,您的剧本应该返回您创建的文本文件的第一个字符。当然,我们可以做很多事情来增强这段代码,但是这是一个很好的简单的例子来帮助您开始。
有了这个基础,你现在应该对如何开始为 Ansible 编写自己的插件有了一个合理的想法。对我们来说,下一个合乎逻辑的步骤是更深入地研究如何测试我们新编写的插件,这将在下一节中进行。
到目前为止,我们只以独立的方式测试了我们的插件。这一切都很好,但是如果您真的想将它添加到您自己的 Ansible 源代码分支中,或者更好的是,将它提交回 Ansible 项目以包含在 PR 中,会怎么样呢?幸运的是,这个过程与我们在第 5 章、消费和创建模块中介绍的过程非常相似,只是文件夹结构略有不同。
和以前一样,您的第一个任务是获取官方 Ansible 项目源代码的副本,例如,通过将 GitHub 存储库克隆到您的本地机器上:
$ git clone https://github.com/ansible/ansible.git
$ cd ansible
接下来,您需要将您的插件代码复制到适当的插件目录中。
- 例如,我们的示例过滤器将被复制到您刚刚克隆的源代码中的以下目录:
$ cp ~/custom_filter.py ./lib/ansible/plugins/filter/
- 类似地,我们的自定义
lookup
插件将进入lookup
插件的目录,使用如下命令:
$ cp ~/firstchar.py ./lib/ansible/plugins/lookup/
代码复制到位后,您需要像以前一样测试文档(也就是说,您的插件是否包含它)。您可以用与我们在第 5 章、消费和创建模块中完全相同的方式构建webdocs
文档,因此我们在此不再赘述。但是,作为复习,我们可以使用ansible-doc
命令快速检查文档是否正确呈现,如下所示:
$ . hacking/env-setup
running egg_info
creating lib/ansible.egg-info
writing requirements to lib/ansible.egg-info/requires.txt
writing lib/ansible.egg-info/PKG-INFO
writing top-level names to lib/ansible.egg-info/top_level.txt
writing dependency_links to lib/ansible.egg-info/dependency_links.txt
writing manifest file 'lib/ansible.egg-info/SOURCES.txt'
reading manifest file 'lib/ansible.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching 'SYMLINK_CACHE.json'
writing manifest file 'lib/ansible.egg-info/SOURCES.txt'
Setting up Ansible to run out of checkout...
PATH=/home/james/ansible/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PYTHONPATH=/home/james/ansible/lib
MANPATH=/home/james/ansible/docs/man:/usr/local/share/man:/usr/share/man
Remember, you may wish to specify your host file with -i
Done!
$ ansible-doc -t lookup firstchar
> FIRSTCHAR (/home/james/ansible/lib/ansible/plugins/lookup/firstchar.py)
This lookup returns the first character of the contents from a
file on the Ansible controller's file system.
* This module is maintained by The Ansible Community
OPTIONS (= is mandatory):
= _terms
path(s) of files to read
正如您到目前为止所看到的,在 Ansible 中,插件开发和模块开发之间有很多重叠。特别重要的是要注意异常情况下的错误处理,以产生高质量、易于理解的错误消息,并遵守和维护 Ansible 的高文档标准。插件输出是我们这里没有涉及到的另一个项目。所有插件都必须返回 Unicode 字符串;这确保了它们可以正确地通过jinja2
过滤器。进一步的指导可以在官方的 Ansible 文档中找到,网址为。
有了这些知识,您现在应该可以开始自己的插件开发工作了,如果您愿意,甚至可以将代码提交回社区。我们将在下一节对此进行简要回顾。
您可能希望向 Ansible 项目提交您的新插件,就像我们在第 5 章、消费和创建模块中考虑我们的定制模块一样。用插件做这件事的过程几乎和你对模块做的一样,这一部分将会重新回顾。
Using the following process will submit a real request to the Ansible project on GitHub to merge the code you submit with their code. Do not follow this process unless you genuinely have a new module that is ready for submission to the Ansible codebase.
为了提交你的插件作为 Ansible 库的 PR,你首先需要分叉官方 Ansible 库的devel
分支。为此,请在网络浏览器上登录您的 GitHub 帐户(或者创建一个帐户,如果您还没有的话),然后导航到https://github.com/ansible/ansible.git。点击页面右上角的分叉:
一旦您将存储库转移到您自己的帐户,我们将引导您完成需要运行的命令,将您的模块代码添加到其中,然后创建所需的 PRs,以便将新模块与上游 Ansible 项目合并:
- 克隆刚刚分叉到本地机器的
devel
分支。使用类似下面的命令,但是一定要用与您自己的 GitHub 帐户相匹配的 URL 来替换该 URL:
$ git clone https://github.com/<your GitHub account>/ansible.git
- 将您的模块代码复制到适当的
plugins/
目录中。在下面的代码块中使用的copy
命令只是一个例子,让你知道该怎么做——实际上,你应该为你的插件选择合适的类别子目录,因为它不一定适合lookup
类别。一旦添加了 Python 文件,执行git add
命令让 Git 知道新文件,然后用有意义的commit
消息提交它。这里显示了一些示例命令:
$ cd ansible
$ cp ~/ansible-development/plugindev/firstchar.py ./lib/ansible/plugins/lookup
$ git add lib/ansible/plugins/lookup/firstchar.py
$ git commit -m 'Added tested version of firstchar.py for pull request creation'
- 现在,请确保使用以下命令将代码推送到分叉的存储库中:
$ git push
- 在您的网络浏览器中返回 GitHub,导航到拉取请求页面,如下图所示。单击“新建请求”按钮:
遵循 GitHub 网站指导的公关创建流程。一旦你成功地提交了你的 PR,你应该能够在官方的 Ansible 源代码库中找到你的 PR 列表。以下截图显示了一个公关列表示例,供您参考:
如前所述,如果你的公共关系需要很长时间来审查,不要惊慌——这只是因为有多少公共关系需要审查和处理。你总是可以通过将你的插件代码添加到一个本地*_plugins/
目录来本地使用它,就像我们之前演示的那样,这样你的 PR 的处理速度就不会妨碍你使用 Ansible 的工作。关于在本地工作时将插件代码放在哪里的更多细节,可以在https://docs . ansi ble . com/ansi ble/latest/dev _ guide/developing _ local . html上找到。
这就完成了插件的创建,包括两个工作示例。希望您已经发现这段旅程内容丰富且有价值,它增强了您使用 Ansible 的能力,并在需要时扩展了其功能。
Ansible 插件是 Ansible 功能的核心部分,我们在这一章中发现,我们在整本书中都在使用它们,甚至没有意识到这一点!Ansible 的模块化设计使得扩展和添加功能变得很容易,无论您使用的是模块还是当前支持的各种类型的插件。无论是为字符串处理添加一个新的过滤器,还是一种新的查找数据的方式(甚至可能是一种新技术的新连接机制),Ansible 插件都提供了一个完整的框架,可以将 Ansible 扩展到远远超出其已经广泛的功能。
在本章中,我们了解了 Ansible 支持的各种类型的插件,然后对它们进行了更详细的探索,并研究了如何获取现有插件的文档和信息。然后,我们完成了两个实际的例子,为 Ansible 创建了两种不同类型的插件,同时查看了插件开发的最佳实践以及这如何与模块开发重叠。我们最后总结了如何将我们的新插件代码作为 PR 提交回 Ansible 项目。
在下一章中,我们将探讨您在编写 Ansible 行动手册时应该遵循的最佳实践,以确保您能够生成可管理的高质量自动化代码。
- 下列哪个
ansible-doc
命令可以用来列出所有缓存插件的名称?
A) ansible-doc -a cache -l
B) ansible-doc cache -l
C) ansible-doc -a cache
D) ansible-doc -t cache -l
E) ansible-doc cache
- 您需要将哪个类添加到您的
lookup
插件代码中,以包含大部分插件代码,包括run()
、items
循环、try
和except
?
A) LookupModule
B) RunModule
C) StartModule
D) InitModule
E) LoadModule
- 对或错-为了使用 Python 创建自定义插件,您需要在操作系统上安装 Python 和相关的依赖项:
真的吗
假的
通过直接访问https://github . com/Ansible/ansi ble/tree/develop/lib/ansi ble/plugins,可以找到 ansi ble 上的所有插件。