Ansible 2.0 API解析
来源:互联网 发布:我知这世界 编辑:程序博客网 时间:2024/05/17 03:50
看了ansible的文档,发现文档的API接口定义的特别简单,找了一个测试用例在安装了ansible的机器上跑了一下,能跑通,就开始调试源码看看为什么要这样写。在/usr/bin目录下找到ansible命令的源码,发现关键点在AdHocCLI这个类。然后找到这个类所在的位置/cli/adhoc.py。一番调试后,发现官网上的API接口就是从AdHocCLI这个类中抽取的。
ansible命令执行结果处理类:
class ResultsCollector(CallbackBase): def __init__(self, *args, **kwargs): super(ResultsCollector, self).__init__(*args, **kwargs) self.host_ok = {} self.host_unreachable = {} self.host_failed = {} def v2_runner_on_unreachable(self, result): self.host_unreachable[result._host.get_name()] = result def v2_runner_on_ok(self, result, *args, **kwargs): self.host_ok[result._host.get_name()] = result def v2_runner_on_failed(self, result, *args, **kwargs): self.host_failed[result._host.get_name()] = result
动态生成Inventory:
class MyInventory(Inventory): """ this is my ansible inventory object. """ def __init__(self, resource, loader, variable_manager): """ resource的数据格式是一个列表字典,比如 { "group1": { "hosts": [{"hostname": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...], "vars": {"var1": value1, "var2": value2, ...} } } 如果你只传入1个列表,这默认该列表内的所有主机属于my_group组,比如 [{"hostname": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...] """ self.resource = resource self.inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[]) self.gen_inventory() def my_add_group(self, hosts, groupname, groupvars=None): """ add hosts to a group """ my_group = Group(name=groupname) # if group variables exists, add them to group if groupvars: for key, value in groupvars.iteritems(): my_group.set_variable(key, value) # add hosts to group for host in hosts: # set connection variables hostname = host.get("hostname") hostip = host.get('ip', hostname) hostport = host.get("port") username = host.get("username") password = host.get("password") ssh_key = host.get("ssh_key") my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostip) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_private_key_file', ssh_key) # set other variables for key, value in host.iteritems(): if key not in ["hostname", "port", "username", "password"]: my_host.set_variable(key, value) # add to group my_group.add_host(my_host) self.inventory.add_group(my_group) def gen_inventory(self): """ add hosts to inventory. """ if isinstance(self.resource, list): self.my_add_group(self.resource, 'default_group') elif isinstance(self.resource, dict): for groupname, hosts_and_vars in self.resource.iteritems(): self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
ansible API:
class MyRunner(object): """ This is a General object for parallel execute modules. """ def __init__(self, resource, *args, **kwargs): self.resource = resource self.inventory = None self.variable_manager = None self.loader = None self.options = None self.passwords = None self.callback = None self.__initializeData() self.results_raw = {} def __initializeData(self): """ 初始化ansible """ Options = namedtuple('Options', ['connection','module_path', 'forks', 'timeout', 'remote_user', 'ask_pass', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'ask_value_pass', 'verbosity', 'check', 'listhosts', 'listtasks', 'listtags', 'syntax']) # initialize needed objects self.variable_manager = VariableManager() self.loader = DataLoader() self.options = Options(connection='smart', module_path='/usr/share/ansible', forks=100, timeout=10, remote_user='root', ask_pass=False, private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None, become_user='root', ask_value_pass=False, verbosity=None, check=False, listhosts=False, listtasks=False, listtags=False, syntax=False) self.passwords = dict(sshpass=None, becomepass=None) self.inventory = MyInventory(self.resource, self.loader, self.variable_manager).inventory self.variable_manager.set_inventory(self.inventory) def run(self, host_list, module_name, module_args,): """ run module from andible ad-hoc. module_name: ansible module_name module_args: ansible module args """ # create play with tasks play_source = dict( name="Ansible Play", hosts=host_list, gather_facts='no', tasks=[dict(action=dict(module=module_name, args=module_args))] ) play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader) # actually run it tqm = None self.callback = ResultsCollector() try: tqm = TaskQueueManager( inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, ) tqm._stdout_callback = self.callback result = tqm.run(play) finally: if tqm is not None: tqm.cleanup() def run_playbook(self, host_list, role_name, role_uuid, temp_param): """ run ansible palybook """ try: self.callback = ResultsCollector() filenames = [BASE_DIR + '/handlers/ansible/v1_0/sudoers.yml'] #playbook的路径 logger.info('ymal file path:%s'% filenames) template_file = TEMPLATE_DIR #模板文件的路径 if not os.path.exists(template_file): logger.error('%s 路径不存在 '%template_file) sys.exit() extra_vars = {} #额外的参数 sudoers.yml以及模板中的参数,它对应ansible-playbook test.yml --extra-vars "host='aa' name='cc' " host_list_str = ','.join([item for item in host_list]) extra_vars['host_list'] = host_list_str extra_vars['username'] = role_name extra_vars['template_dir'] = template_file extra_vars['command_list'] = temp_param.get('cmdList') extra_vars['role_uuid'] = 'role-%s'%role_uuid self.variable_manager.extra_vars = extra_vars logger.info('playbook 额外参数:%s'%self.variable_manager.extra_vars) # actually run it executor = PlaybookExecutor( playbooks=filenames, inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords=self.passwords, ) executor._tqm._stdout_callback = self.callback executor.run() except Exception as e: logger.error("run_playbook:%s"%e) def get_result(self): self.results_raw = {'success':{}, 'failed':{}, 'unreachable':{}} for host, result in self.callback.host_ok.items(): self.results_raw['success'][host] = result._result for host, result in self.callback.host_failed.items(): self.results_raw['failed'][host] = result._result['msg'] for host, result in self.callback.host_unreachable.items(): self.results_raw['unreachable'][host]= result._result['msg'] logger.debug("Ansible执行结果集:%s"%self.results_raw) return self.results_raw
2 0
- Ansible 2.0 API解析
- python之ansible 2.0 API
- Python调用Ansible 2.0 API执行playbook
- ansible api python joke
- ansible API 示例
- ansible小结(十)ansible api
- Ansible常用模块API调用
- Ansible 2.0发布
- ansible
- ansible
- Ansible
- Ansible
- ansible
- Ansible
- ansible
- Ansible
- ansible
- ansible
- String StringBuffer与StringBuilder的区别
- 25个经典的Spring面试问答
- JAVA基础部分(一)
- 回归技术
- React 试用
- Ansible 2.0 API解析
- Android 开源项目浅读-------SwipeMenuListView-重写-第二章,菜单显示
- (OK) NS-3—LXC-(Docker)—MANET——HOWTO Use Linux Containers to set up virtual networks
- Android 学习资料
- 实现文本的复制和粘贴、文本的撤销和恢复(Swing JTextArea)
- Best Time to Buy and Sell Stock
- 【Qt】自定义标题栏并实现最小化/最大化/关闭窗口功能
- C++中类和结构体的介绍
- Android Studio SVN 使用方法