Skip to content

Instantly share code, notes, and snippets.

@choldrim
Created March 3, 2017 10:22
Show Gist options
  • Select an option

  • Save choldrim/3211f1660291f871739379082f204c83 to your computer and use it in GitHub Desktop.

Select an option

Save choldrim/3211f1660291f871739379082f204c83 to your computer and use it in GitHub Desktop.

Revisions

  1. choldrim created this gist Mar 3, 2017.
    261 changes: 261 additions & 0 deletions ansible-2.0-api-example.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,261 @@
    #!/usr/bin/env python3
    # coding=utf-8
    import json

    from ansible.executor.task_queue_manager import TaskQueueManager
    from ansible.inventory import Inventory
    from ansible.inventory.group import Group
    from ansible.inventory.host import Host
    from ansible.parsing.dataloader import DataLoader
    from ansible.playbook.play import Play
    from ansible.plugins.callback import CallbackBase
    from ansible.vars import VariableManager


    class CallbackModule(CallbackBase):
    """
    Reference: https://github.com/ansible/ansible/blob/v2.0.0.2-1/lib/ansible/plugins/callback/default.py
    """

    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'stored'
    CALLBACK_NAME = 'database'

    def __init__(self):
    super(CallbackModule, self).__init__()
    self.state = None
    self.result = None

    def v2_runner_on_failed(self, result, ignore_errors=False):
    self.state = 'failed'
    self.result = result._result

    def v2_runner_on_ok(self, result):
    self.result = result._result
    self.state = 'ok'

    def v2_runner_on_skipped(self, result):
    self.state = 'skipped'
    self.result = result._result

    def v2_runner_on_no_hosts(self, task):
    print('skipping: no hosts matched')

    def v2_playbook_on_task_start(self, task, is_conditional):
    print("TASK [%s]" % task.get_name().strip())

    def v2_playbook_on_play_start(self, play):
    name = play.get_name().strip()
    if not name:
    msg = "PLAY"
    else:
    msg = "PLAY [%s]" % name

    print(msg)

    def v2_playbook_on_stats(self, stats):
    hosts = sorted(stats.processed.keys())
    for h in hosts:
    t = stats.summarize(h)

    msg = "PLAY RECAP [%s] : %s %s %s %s %s" % (
    h,
    "ok: %s" % (t['ok']),
    "changed: %s" % (t['changed']),
    "unreachable: %s" % (t['unreachable']),
    "skipped: %s" % (t['skipped']),
    "failed: %s" % (t['failures']),
    )

    print(msg)


    class MyInventory(Inventory):

    def __init__(self, resource, loader, variable_manager, host_list=[]):
    """
    resource的数据格式是一个列表字典,比如
    {
    "group1": {
    "hosts": [{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...],
    "vars": {"var1": value1, "var2": value2, ...}
    }
    }
    如果你只传入1个列表,这默认该列表内的所有主机属于my_group组,比如
    [{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...]
    """
    super(MyInventory, self).__init__(loader=loader, variable_manager=variable_manager, host_list=host_list)
    self.resource = resource
    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.items():
    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.items():
    if key not in ["hostname", "port", "username", "password"]:
    my_host.set_variable(key, value)
    # add to group
    my_group.add_host(my_host)

    self.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"))


    class Options(object):
    """
    Options class to replace Ansible OptParser
    """
    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=None, become_method=None, become_user=None, 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 = verbosity
    self.inventory = inventory
    self.listhosts = listhosts
    self.subset = subset
    self.module_paths = module_paths
    self.extra_vars = extra_vars
    self.forks = forks
    self.ask_vault_pass = ask_vault_pass
    self.vault_password_files = vault_password_files
    self.new_vault_password_file = new_vault_password_file
    self.output_file = output_file
    self.tags = tags
    self.skip_tags = skip_tags
    self.one_line = one_line
    self.tree = tree
    self.ask_sudo_pass = ask_sudo_pass
    self.ask_su_pass = ask_su_pass
    self.sudo = sudo
    self.sudo_user = sudo_user
    self.become = become
    self.become_method = become_method
    self.become_user = become_user
    self.become_ask_pass = become_ask_pass
    self.ask_pass = ask_pass
    self.private_key_file = private_key_file
    self.remote_user = remote_user
    self.connection = connection
    self.timeout = timeout
    self.ssh_common_args = ssh_common_args
    self.sftp_extra_args = sftp_extra_args
    self.scp_extra_args = scp_extra_args
    self.ssh_extra_args = ssh_extra_args
    self.poll_interval = poll_interval
    self.seconds = seconds
    self.check = check
    self.syntax = syntax
    self.diff = diff
    self.force_handlers = force_handlers
    self.flush_cache = flush_cache
    self.listtasks = listtasks
    self.listtags = listtags
    self.module_path = module_path


    class Runner:

    def __init__(self, resource):

    self.options = Options()
    self.options.connection = 'ssh' # Need a connection type "smart" or "ssh"
    self.options.become = True
    self.options.become_method = 'sudo'
    self.options.become_user = 'root'

    # Become Pass Needed if not logging in as user root (do not support now)
    passwords = {'become_pass': ''}

    # Gets data from YAML/JSON files
    self.loader = DataLoader()

    # All the variables from all the various places
    self.variable_manager = VariableManager()

    # Set inventory, using most of above objects
    self.inventory = MyInventory(resource=resource, loader=self.loader, variable_manager=self.variable_manager)
    self.variable_manager.set_inventory(self.inventory)

    # set callback object
    self.results_callback = CallbackModule()

    # playbook
    self.tqm = TaskQueueManager(
    inventory=self.inventory,
    variable_manager=self.variable_manager,
    loader=self.loader,
    options=self.options,
    passwords=passwords,
    stdout_callback=self.results_callback,
    )

    def run(self, module_name='shell', module_args='',):
    play_source = dict(
    name='Ansible Play',
    hosts='*',
    gather_facts='no',
    tasks=[
    dict(action=dict(module=module_name, args=module_args)),
    ]
    )

    self.play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)
    try:
    ret = self.tqm.run(self.play)
    print(ret)
    return ret, self.results_callback.result
    finally:
    self.tqm.cleanup()


    if __name__ == '__main__':
    res = [{
    'ssh_key': 'deepin.pem',
    'username': 'deepin',
    'ip': '10.10.120.114',
    'hostname': 'payOrder-provider01',
    'port': 16001,
    'password': 'deepin'
    }]
    tqm = Runner(res)
    ret, result = tqm.run(module_args='ls /')
    print(json.dumps(result, indent=4))