7.13 基于 ansible-api 二次开发

长久以来,IT 运维在企业内部一直是个耗人耗力的事情。随着虚拟化的大量应用、私有云、容器的不断普及,数据中心内部的压力愈发增加。传统的自动化工具,往往是面向于数据中心特定的一类对象,例如操作系统、虚拟化、网络设备的自动化运维工具往往是不同的。那么,有没有一种数据中心级别的统一的自动化运维工具呢?

答案就是Ansible。和传统的自动化工具 (如 Puppet)相比,Ansible 尤其明显的优势:

  • 简单,是一种高级的脚本类语言,而非标准语言。

  • 不需要安装 agent, 分为管理节点和远程被管节点通过 SSH 认证。

  • 纳管范围广泛,不仅仅是操作系统,还包括各种虚拟化、公有云,甚至网络设备。

用过 ansible 的人都知道,ansible 一般都是通过命令行执行的:ansible、ansible-playbook、ansible-doc、ansible-galaxy、ansible-console 等。用执行命令的方式,整个过程的所有信息都会实时的打印在终端屏幕。这样的好处是,反馈实时,可以观察整个部署过程。缺点就是信息过多,难以获取有效的信息。

这时候,我们自然想到可以直接调用 ansible 提供的接口进行开发。

通过搜索引擎查询有关 ansible 二次开发的相关资料,发现这方面的文章非常少,而且由于 ansible 一直在进行代码的重构优化,有很多网友提供的 demo 已不适用我当前使用的版本,一直跑不通。

本想从官方文档中查得一些资料,结果发现官网中对于这块也没有很详细的介绍。

后来想想,ansible、ansible-playbook、ansible-doc 这些命令不也是基于 ansible api 开发出来的吗?

我不是可以模仿他们,来调用 ansible api 接口。

以下通过阅读 ansible cli 的源码,总结出来的。

定义回调类

class ResultCallback(CallbackBase):
    def v2_runner_on_ok(self, result, **kwargs):
        pass

    def v2_runner_on_failed(self, result, **kwargs):
        host = result._host.get_name()
        self.runner_on_failed(host, result._result, False)
        task_result[host]['status'] = 'fail'
        task_result[host]['reason'] = result._result.get('msg', '').encode('utf-8')

    def v2_runner_on_unreachable(self, result):
        host = result._host.get_name()
        self.runner_on_unreachable(host, result._result)
        task_result[host]['status'] = 'fail'
        task_result[host]['reason'] = result._result.get('msg' , 'unreachable')

    def v2_runner_on_skipped(self, result):
        if C.DISPLAY_SKIPPED_HOSTS:
            host = result._host.get_name()
            self.runner_on_skipped(host, self._get_item(getattr(result._result, 'results', {})))

    def v2_playbook_on_stats(self, stats):
        global PLAYBOOK_ERROR
        PLAYBOOK_ERROR = len(stats.dark)+len(stats.failures)

并实现其中几个关键的方法

  • v2_runner_on_ok:单个部署任务成功时,会调用

  • v2_runner_on_failed:节点的部署任务失败时,会调用

  • v2_runner_on_unreachable:节点不可达时,会调用

  • v2_runner_on_skipped:部署任务跳过时,会调用

  • v2_playbook_on_stats:所有的部署任务完成时,调用