一. 前言:
ansible 是一款自动化的运维工具,基于python语言,模块化工作;
作为一款运维工具,最重要的便是具备批量操作的能力,ansible能够进行批量的系统配置,程序部署,命令执行等;
ansible是基于ssh来和远程机器进行通信的,无需在远程机器上安装client或者agent;
ansible最强大的功能就是基于yaml语法的playbook(剧本),通过使用ansible的各个模块来定制化运维操作,是基于ansible开发运维操作系统的关键.
二. 使用 python api 调用 playbook
废话不多说,直接上代码,建议使用root账号密码来操作
ansible 版本: 2.8.5
python版本: 3.7.4
-
定义执行方法,用于执行剧本,参数含义就是字面意思
# 定义方法用于执行剧本 def cluster_node_start(target_host_list, name, callback_vars, tags, extra_vars=None): play = get_mine_playbook_executor(extra_vars, name, target_host_list, tags) # set callback results_callback = mine_playbook_callback(callback_vars) play._tqm._stdout_callback = results_callback play.run() -
定义剧本的执行器 PlaybookExecutor (核心,不同的版本之间有差异,遇坑的举爪)
# 定义剧本的执行器 PlaybookExecutor def get_mine_playbook_executor(extra_vars, name, target_host_list, tags=[]): # 非常神奇的一句话 current_process()._config = {'semprefix': '/mp'} loader = DataLoader() passwords = dict() inventory = InventoryManager(loader=loader, sources=settings.WHOLE_HOSTS_PATH) variable_manager = VariableManager(loader=loader, inventory=inventory) inventory.add_group("now_group") for data in target_host_list: host_ip = data.get("host_ip") inventory.add_host(host_ip, 'now_group') hostname = host_ip hostip = data.get('host_ip') username = data.get("host_user") password = data.get("host_password") my_host = Host(name=hostname) variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_host", value=hostip) variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_user", value=username) variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_pass", value=password) if extra_vars is not None: variable_manager._extra_vars = extra_vars # 如果你希望能够动态的更改tags,请使用这种方式获取options, # 使用context._init_global_context() tags只会赋一次初值!!! context.CLIARGS = get_mine_default_options(tags) play = PlaybookExecutor( playbooks=[settings.PLAYBOOK_BASE_DIR + name], inventory=inventory, loader=loader, # options=get_default_options(tags),#ansible 2.8 没办法直接在这里添加options了 passwords=passwords, variable_manager=variable_manager, ) return play -
options的获取,定义方法
get_mine_default_options(tags)# 获取options def get_mine_default_options(tags): from ansible.module_utils.common.collections import ImmutableDict return ImmutableDict(verbosity=0, ask_pass=False, private_key_file='/root/.ssh/id_rsa', remote_user=None, connection='smart', timeout=60, ssh_common_args='', sftp_extra_args='', scp_extra_args='', ssh_extra_args='', force_handlers=False, flush_cache=None, become=False, become_method='sudo', become_user=None, become_ask_pass=False, tags=tags if len(tags) > 0 else [], skip_tags=[], check=False, syntax=None, diff=False, # inventory= '/Users/caishichao/Code/AnsibleCentrolManagement/inventory/hosts.uat', listhosts=None, subset=None, extra_vars=[], ask_vault_pass=False, vault_password_files=[], vault_ids=[], forks=5, module_path=None, listtasks=None, listtags=None, step=None, start_at_task=None, args=['fake']) -
剧本回调(callback)--如果有运维平台的需求,会需要使用回调来获取task的执行情况
# 定义剧本执行完成后的回调策略,用来对任务的执行结果进行记录 class mine_playbook_callback(CallbackBase): def __init__(self, vars): super().__init__() self.vars = vars def v2_runner_on_ok(self, result): if (result._task._role != None): # 传入的playbook参数 extra_vars = result._task._variable_manager._extra_vars # 执行playbook的节点ip host_ip = result._host.addressc # 执行的playbook中的任务名称 task_name = result.task_name # 执行shell时的输出 stdout_lines = result._result.get('stdout_lines') def v2_runner_on_failed(self, result, ignore_errors=False): # 执行失败时的回调用 pass def v2_runner_on_unreachable(self, result): # host 不可达时的回调 pass以上就是ansible2.8 执行一个playbook的核心代码了!
三. 后记
ansible是个蛮不错的运维工具,结合playbook可以完成很多自动化的工作,比如新机器的环境check,应用安装等操作,都可以在定义好剧本后批量操作,比较方便.
当然我觉得目前的ansible文档较少,官网上说的不清不楚,对于python api 调用 playbook 基本没有什么说明,导致升级使用起来较为困难,在写上述的剧本代码调用也是被无情践踏了多词,疯狂的去各个社区搜索相关资料来逐渐完善自己的调用代码,非常感谢哪些愿意分享的优秀博主.
@author xigua