使用 Testinfra 和 Ansible 验证服务器状态

Testinfra 是一个强大的库,用于编写测试以验证基础设施的状态。与 Ansible 和 Nagios 结合使用,它提供了一个简单的解决方案来强制执行基础设施即代码。
202 位读者喜欢这篇文章。

按照设计,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-frontend01app-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 角色期间添加测试的关键组件。

接下来阅读什么

DevOps 扩大您的开源资历

您真的可以在不共享脚本或代码的情况下进行 DevOps 吗?DevOps 宣言的支持者重视跨职能团队、共生关系和持续反馈循环……

标签
User profile image.
开源爱好者,我是 Red Hat 社区平台工程团队的成员,这意味着我大部分时间都在 Fedora 和 CentOS 基础设施上进行黑客攻击。我喜欢撰写关于 Agile 和 DevOps 以及如何组建优秀团队的文章。

5 条评论

不错的文章

非常有用!

不错

这很好,它几乎将 3 个任务分解为一个来测试软件包是否已安装。

非常感谢。很高兴知道有方法可以验证我们的基础设施,而不是将基础设施视为一种一劳永逸的事情。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.