Solución:
Aviso de obsolescencia: esta publicación no funciona a partir de ansible 2. Se cambió la API.
Esto se cubre en la documentación de Ansible en “API de Python”.
Por ejemplo, ansible -i hosts dbservers -m setup
se implementa a través de:
import ansible.runner
runner = ansible.runner.Runner(
module_name="setup",
module_args="",
pattern='dbservers',
)
dbservers_get_facts = runner.run()
Hay un montón de parámetros no documentados en el __init__
método de corredor (de ansible.runner
). Hay demasiados para enumerarlos en línea, pero he incluido algunos de los parámetros en esta publicación como una suposición de lo que está buscando específicamente.
class Runner(object):
''' core API interface to ansible '''
# see bin/ansible for how this is used...
def __init__(self,
host_list=C.DEFAULT_HOST_LIST, # ex: /etc/ansible/hosts, legacy usage
module_path=None, # ex: /usr/share/ansible
module_name=C.DEFAULT_MODULE_NAME, # ex: copy
module_args=C.DEFAULT_MODULE_ARGS, # ex: "src=/tmp/a dest=/tmp/b"
...
pattern=C.DEFAULT_PATTERN, # which hosts? ex: 'all', 'acme.example.org'
remote_user=C.DEFAULT_REMOTE_USER, # ex: 'username'
remote_pass=C.DEFAULT_REMOTE_PASS, # ex: 'password123' or None if using key
remote_port=None, # if SSH on different ports
private_key_file=C.DEFAULT_PRIVATE_KEY_FILE, # if not using keys/passwords
sudo_pass=C.DEFAULT_SUDO_PASS, # ex: 'password123' or None
...
sudo=False, # whether to run sudo or not
sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root'
module_vars=None, # a playbooks internals thing
play_vars=None, #
play_file_vars=None, #
role_vars=None, #
role_params=None, #
default_vars=None, #
extra_vars=None, # extra vars specified with he playbook(s)
is_playbook=False, # running from playbook or not?
inventory=None, # reference to Inventory object
...
su=False, # Are we running our command via su?
su_user=None, # User to su to when running command, ex: 'root'
su_pass=C.DEFAULT_SU_PASS,
vault_pass=None,
...
):
Por ejemplo, el comando anterior que especifica un usuario y un pase sudo sería:
runner = ansible.runner.Runner(
module_name="setup",
module_args="",
pattern='dbservers',
remote_user="some_user"
remote_pass="some_pass_or_python_expression_that_returns_a_string"
)
Para los libros de jugadas, consulte el libro de jugadas.PlayBook, que tiene un conjunto similar de inicializadores:
class PlayBook(object):
'''
runs an ansible playbook, given as a datastructure or YAML filename.
...
'''
# *****************************************************
def __init__(self,
playbook = None,
host_list = C.DEFAULT_HOST_LIST,
module_path = None,
....
y se puede ejecutar con el .run()
método. p.ej:
from ansible.playbook import PlayBook
pb = PlayBook(playbook='/path/to/book.yml, --other initializers--)
pb.run()
un uso más robusto se puede encontrar en el ansible-playbook
expediente.
Hasta donde yo sé, traducir los libros de jugadas a los módulos de Python es un poco más complicado, pero la documentación enumerada anteriormente debería cubrirlo y puede reutilizar el analizador YAML integrado en Ansible para convertir los libros de jugadas en variables.
Solo una actualización rápida de código que funciona en 2.8.3,
from ansible import context
from ansible.cli import CLI
from ansible.module_utils.common.collections import ImmutableDict
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager
from ansible.vars.manager import VariableManager
loader = DataLoader()
context.CLIARGS = ImmutableDict(tags={}, listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh',
module_path=None, forks=100, remote_user="xxx", private_key_file=None,
ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True,
become_method='sudo', become_user="root", verbosity=True, check=False, start_at_task=None)
inventory = InventoryManager(loader=loader, sources=('/xxx/inventory_file',))
variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))
pbex = PlaybookExecutor(playbooks=['/xxx/playbook.yml'], inventory=inventory, variable_manager=variable_manager, loader=loader, passwords={})
results = pbex.run()
He respondido a la pregunta aquí Publicar esto aquí porque no se recomienda publicar enlaces en la comunidad. Espero eso ayude.
La documentación es sorprendentemente deficiente y tendrá que comenzar aquí.
Dicho esto, aquí hay un guión rápido que pirateé y que logra ejecutar un libro de jugadas.
#!/usr/bin/env python
import os
import sys
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import Inventory
from ansible.executor.playbook_executor import PlaybookExecutor
loader = DataLoader()
inventory = Inventory(loader=loader, sources="/home/slotlocker/hosts2")
variable_manager = VariableManager(loader=loader, inventory=inventory)
playbook_path="/home/slotlocker/ls.yml"
if not os.path.exists(playbook_path):
print '[INFO] The playbook does not exist'
sys.exit()
Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check','diff'])
options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=100, remote_user="slotlocker", private_key_file=None, ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=True, become_method='sudo', become_user="root", verbosity=None, check=False, diff=False)
variable_manager.extra_vars = {'hosts': 'mywebserver'} # This can accomodate various other command line arguments.`
passwords = {}
pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords)
results = pbex.run()