按照设计,Ansible 表达了机器的期望状态,以确保 Ansible playbook 或角色的内容被部署到目标机器。但是,如果您需要确保所有基础设施更改都在 Ansible 中呢?或者随时验证服务器的状态?
Testinfra 是一个基础设施测试框架,可以轻松编写单元测试来验证服务器的状态。它是一个 Python 库,并使用强大的 pytest 测试引擎。
Testinfra 入门
可以使用 Python 包管理器 (pip) 和 Python 虚拟环境轻松安装 Testinfra。
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install testinfra
Testinfra 也可在 Fedora 和 CentOS 的软件包存储库中使用 EPEL 存储库获得。例如,在 CentOS 7 上,您可以使用以下命令安装它
$ yum install -y epel-release
$ yum install -y python-testinfra
一个简单的测试脚本
在 Testinfra 中编写测试很容易。使用您选择的代码编辑器,将以下内容添加到名为 test_simple.py 的文件中
import testinfra
def test_os_release(host):
assert host.file("/etc/os-release").contains("Fedora")
def test_sshd_inactive(host):
assert host.service("sshd").is_running is False
默认情况下,Testinfra 为测试用例提供一个主机对象;此对象提供对不同辅助模块的访问。例如,第一个测试使用 file 模块来验证主机上文件的内容,第二个测试用例使用 service 模块来检查 systemd 服务的状态。
要在本地机器上运行这些测试,请执行以下命令
(venv)$ pytest test_simple.py
================================ test session starts ================================
platform linux -- Python 3.7.3, pytest-4.4.1, py-1.8.0, pluggy-0.9.0
rootdir: /home/cverna/Documents/Python/testinfra
plugins: testinfra-3.0.0
collected 2 items
test_simple.py ..
================================ 2 passed in 0.05 seconds ================================
更多关于 Ansible
有关 Testinfra API 的完整列表,您可以查阅文档。
Testinfra 和 Ansible
Testinfra 支持的后端之一是 Ansible,这意味着 Testinfra 可以直接使用 Ansible 的清单文件和清单中定义的一组机器来针对它们运行测试。
让我们使用以下清单文件作为示例
[web]
app-frontend01
app-frontend02
[database]
db-backend01
我们想确保我们的 Apache Web 服务器服务在 app-frontend01 和 app-frontend02 上运行。让我们在一个名为 test_web.py 的文件中编写测试
def check_httpd_service(host):
"""Check that the httpd service is running on the host"""
assert host.service("httpd").is_running
要使用 Testinfra 和 Ansible 运行此测试,请使用以下命令
(venv) $ pip install ansible
(venv) $ py.test --hosts=web --ansible-inventory=inventory --connection=ansible test_web.py
在调用测试时,我们使用 Ansible 清单 [web] 组作为目标机器,并指定我们要使用 Ansible 作为连接后端。
使用 Ansible 模块
Testinfra 还提供了一个不错的 Ansible API,可以在测试中使用。Ansible 模块允许访问在测试内部运行 Ansible playbook,并可以轻松检查 playbook 的结果。
def check_ansible_play(host):
"""
Verify that a package is installed using Ansible
package module
"""
assert not host.ansible("package", "name=httpd state=present")["changed"]
默认情况下,Ansible 的 Check Mode 已启用,这意味着 Ansible 将报告如果在远程主机上执行 playbook 会发生什么变化。
Testinfra 和 Nagios
现在我们可以轻松运行测试来验证机器的状态,我们可以使用这些测试来触发监控系统上的警报。这是捕捉意外更改的好方法。
Testinfra 提供了与流行的监控解决方案 Nagios 的集成。默认情况下,Nagios 使用 NRPE 插件在远程主机上执行检查,但使用 Testinfra 允许您直接从 Nagios 主服务器运行测试。
要获得与 Nagios 兼容的 Testinfra 输出,我们必须在触发测试时使用 --nagios 标志。我们还使用 -qq pytest 标志来启用 pytest 的静默模式,这样就不会显示所有测试详细信息。
(venv) $ py.test --hosts=web --ansible-inventory=inventory --connection=ansible --nagios -qq line test.py
TESTINFRA OK - 1 passed, 0 failed, 0 skipped in 2.55 seconds
Testinfra 是一个强大的库,用于编写测试以验证基础设施的状态。与 Ansible 和 Nagios 结合使用,它提供了一个简单的解决方案来强制执行基础设施即代码。它也是在使用 Molecule 开发 Ansible 角色期间添加测试的关键组件。
5 条评论