一.简述:
熟练使用ansible的api功能,会给我们的工作带来很大便利。 不过不得不说,ansible的api 这种通过继承原生类的方式,是一件比较复杂的事情。需要对配合ansible的源码做些分析了解,才能正确的使用api。
二. options功能详解:
还是通过官方提供的案例说起:
import json
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
from ansible.inventory import Inventory
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase
.........
Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'remote_user', 'check'])
variable_manager = VariableManager()
loader = DataLoader()
options = Options(connection='smart', module_path=None, forks=10, become=None, become_method=None, become_user=None, remote_user=None check=False)
.........
tqm = TaskQueueManager(inventory=inventory,variable_manager=variable_manager,loader=loader,options=options,passwords=None,stdout_callback=results_callback,
)
..........
我们可以看到, 上文中采用了collections模块(一个python内建的集合模块 )
关于Options的定义:
options -->主要用来替换命令行方式通过args传递进去的参数变量,上文中,首先我们初始化一个集合:
Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'remote_user', 'check']) #集合元素
PlayContext用于合并连接/认证主机的信息,有些是继承与基础配置(connection,port,remote_user,environment,no_log 等)。
class PlayContext(Base):'''This class is used to consolidate the connection information forhosts in a play and child tasks, where the task may override someconnection/authentication information.'''# connection fields, some are inherited from Base:# (connection, port, remote_user, environment, no_log)_docker_extra_args = FieldAttribute(isa='string')_remote_addr = FieldAttribute(isa='string')
...................def __init__(self, play=None, options=None, passwords=None, connection_lockfd=None)............if options:self.set_options(options)
通过set_options处理options:
可以看出, 整个options必须包含三个变量值(become,become_method,become_user)
如, 本文中的环境(sudo需求)为: ansible在中心机上以root身份运行playbook,走被操作机的ansible用户然后通过sudo方式执行命令(如 ls /root/)
.....................
Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user','remote_user', 'check', 'sudo_user', 'sudo'])options = Options(connection='smart', module_path=None, forks=10, become=True, become_method='sudo', become_user='root',remote_user='ansible', check=False,sudo_user=None,sudo='yes')
.....................
if self.become_method == 'sudo':# If we have a password, we run sudo with a randomly-generated# prompt set using -p. Otherwise we run it with default -n, which makes# it fail if it would have prompted for a password.# Cannot rely on -n as it can be removed from defaults, which should be# done for older versions of sudo that do not support the option.## Passing a quoted compound command to sudo (or sudo -s)# directly doesn't work, so we shellquote it with shlex_quote()# and pass the quoted string to the user's shell.# force quick error if password is required but not supplied, should prevent sudo hangs.if self.become_pass:prompt = '[sudo via ansible, key=%s] password: ' % randbitsbecomecmd = '%s %s -p "%s" -u %s %s' % (exe, flags.replace('-n',''), prompt, self.become_user, command)else:becomecmd = '%s %s -u %s %s' % (exe, flags, self.become_user, command)
回到主题: options -->主要用来替换命令行方式通过args传递进去的参数变量, 可支持的参数:
class Options(object):'''用于替换ansible的命令行参数'''def __init__(self, verbosity=None, inventory=None, listhosts=None, subset=None, module_paths=None, extra_vars=None,forks=None, ask_vault_pass=None, vault_password_files=None, new_vault_password_file=None,output_file=None, tags=None, skip_tags=None, one_line=None, tree=None, ask_sudo_pass=None, ask_su_pass=None,sudo=None, sudo_user=None, become=False, become_method='sudo', become_user='root', become_ask_pass=None,ask_pass=None, private_key_file=None, remote_user=None, connection=None, timeout=None, ssh_common_args=None,sftp_extra_args=None, scp_extra_args=None, ssh_extra_args=None, poll_interval=None, seconds=None, check=None,syntax=None, diff=None, force_handlers=None, flush_cache=None, listtasks=None, listtags=None, module_path=None):self.verbosity = verbosityself.inventory = inventoryself.listhosts = listhostsself.subset = subsetself.module_paths = module_pathsself.extra_vars = extra_varsself.forks = forksself.ask_vault_pass = ask_vault_passself.vault_password_files = vault_password_filesself.new_vault_password_file = new_vault_password_fileself.output_file = output_fileself.tags = tagsself.skip_tags = skip_tagsself.one_line = one_lineself.tree = treeself.ask_sudo_pass = ask_sudo_passself.ask_su_pass = ask_su_passself.sudo = sudoself.sudo_user = sudo_userself.become = becomeself.become_method = become_methodself.become_user = become_userself.become_ask_pass = become_ask_passself.ask_pass = ask_passself.private_key_file = private_key_fileself.remote_user = remote_userself.connection = connectionself.timeout = timeoutself.ssh_common_args = ssh_common_argsself.sftp_extra_args = sftp_extra_argsself.scp_extra_args = scp_extra_argsself.ssh_extra_args = ssh_extra_argsself.poll_interval = poll_intervalself.seconds = secondsself.check = checkself.syntax = syntaxself.diff = diffself.force_handlers = force_handlersself.flush_cache = flush_cacheself.listtasks = listtasksself.listtags = listtagsself.module_path = module_path
有相关需求的同学,可以作为参考。。。
----------------------------------------------------------------------------------------------
深耕运维行业多年,擅长linux、容器云原生、运维自动化等方面。
承接各类运维环境部署、方案设计/实施、服务代运维工作,欢迎沟通交流 !