Ansible api 常见问题总结

󰃭 2018-03-11

Ansible API

ansible api 2.0 的版本之后, 其调用的接口参数和旧的已经不一样, 且官方文档仅有一个实例, 其他什么都没有, 以下是在实践中总结的一点点文档

api 调用实例

loader = DataLoader()
inventory = InventoryManager(loader=loader)
variable_manager = VariableManager(loader=loader, inventory=inventory)


"tasks": [{"action": {"module": "shell", "args": cmd}}]}

Options = namedtuple('Options',
  ['connection',
  'module_path',
  'forks',
  'become',
  'become_method',
  'become_user',
  'become_ask_pass',
  'check',
  'timeout',
  'diff',
  'remote_user',
  ])

options = self.Options(connection='smart',
  module_path='/path/to/mymodules',
  forks=forks,
  become=False,
  become_method=None,
  become_user=None,
  become_ask_pass=False,
  check=False,
  diff=False,
  timeout=1,
  remote_user='root',  # webid用户必须制定远程用户
)


variable_manager.extra_vars = {}
executor = PlaybookExecutor(playbooks, inventory, variable_manager, loader, options,
passwords)

result = executor.run()

动态IP 传递

一般的ansible 执行都是命令行执行, 要执行的host文件都是写在文件中, 命令行参数指定该文件即可,

但在 API 执行的时候, 我们当然希望能把IP列表传递进去, 查了半天如下即可

inventory = InventoryManager(loader=loader, sources=[','.join(hosts)+','])

hosts 就是要传递进去的hosts列表, 通过这种方式即可对动态的机器列表执行任务

执行回调

ansible 以多进程的方式并行处理, 执行结果存储在各个子进程中, 比如想记录执行结果, 该怎么做呢

上面代码最后几行做如下更改

class MyResultCallback(ResultCallback):
    def __init__(self, shell_result):
        super(ResultCallback, self).__init__()
        self.shell_result = shell_result

    def v2_runner_on_ok(self, result, **kwargs):
        """Print a json representation of the result
        This method could store the result in an instance attribute for retrieval later
        """
        self.shell_result[str(result._host)] = result._result['stdout']



variable_manager.extra_vars = {}
executor = PlaybookExecutor(playbooks, inventory, variable_manager, loader, options,
passwords)
executor._tqm._stdout_callback=MyResultCallback

result = executor.run()

MyResultCallback 就是做回调处理的类, v2_runner_on_ok 就是在执行成功时的回调

其他对应的回调函数有

v2_playbook_on_start(self, playbook): 是 playbook 执行前调用的

v2_playbook_on_task_start(self, task, is_conditional): 是 playbook 中的各个 task 执行前调用的

v2_playbook_on_stats(self, stats) 是所有的host执行结束时调用的

v2_runner_on_failed(self, result, **kwargs) 是任务执行失败时调用的

v2_runner_on_unreachable(self, result) 是执行主机连接不上的时候触发调用的

v2_runner_on_skipped(self, result, **kwargs) 是任务跳过不执行时触发调用的

带参数的执行回调

如果需要在执行回调里带动态的参数呢, 正常的执行回调带的参数都是固定的, 要么是playbook, 要么是执行结果, 那么如果想动态的参数呢

我们基于python的动态特性, 可以实现这个

如下

def dp_callback(m_task, step_task, deploy_log):
    """某分步任务执行结束后的回调"""
    class DeployResultCallback(CallbackBase):
        """A sample callback plugin used for performing an action as results come in

        If you want to collect all results into a single object for processing at
        the end of the execution, look into utilizing the ``json`` callback plugin
        or writing your own custom callback plugin
        """
        def __init__(self):
            pass
 

        def v2_playbook_on_start(self, playbook):
            """playbook任务开始前会调用"""
            
        ......
        
        return DeployResultCallback

dp_callback(m_task, step_task, deploy_log) 括号里可以传任意参数

disable host_key_checking

在我们第一次执行远程操作时, 会有一个交互, 要求填写一个yes/no, 确认是将连接的host 写入 known_hosts

那我们如何取消这个交互呢

如下即可

from ansible import constants as C
C.HOST_KEY_CHECKING = False

设置ssh private key

我们连接远程服务器, 推荐使用ssh key 连接, 连接时, 我们需要设置和远程公钥配对的本地私钥

在option中, 添加一个private_key_file 参数, 指向我们的私钥即可

options = self.Options(
...
private_key_file='/path/to/private_key_file'
...
)