鍍金池/ 問答/Python  網(wǎng)絡安全/ python調(diào)用ansible api 秘鑰密碼設置無效

python調(diào)用ansible api 秘鑰密碼設置無效

# -*- conding:utf-8 -*-
import json
import os
import sys
import time

from collections import namedtuple
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
from ansible.executor.playbook_executor import PlaybookExecutor



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
    
    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):
    """
    this is my ansible inventory object.
    """
    
    def __init__(self, resource, loader, variable_manager):
        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.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.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.items():
                self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))


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/local/python36/lib/python3.6/site-packages/ansible/modules', 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
        print(host_list, module_name, module_args)
        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)
        
        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)
            time.sleep(10)
        finally:
            if tqm is not None:
                tqm.cleanup()

   # def run_playbook(self, host_list, role_name, role_uuid, temp_param):
    def run_playbook(self, hosts, playbookfile, playbookvars):
        """
        run ansible palybook
        """
        try:
            self.callback = ResultsCollector()
            filenames = [playbookfile]  # playbook的路徑
            print('ymal file path:%s' % filenames)

            extra_vars = playbookvars  # 額外的參數(shù) sudoers.yml以及模板中的參數(shù),它對應ansible-playbook test.yml --extra-vars "host='aa' name='cc' "
            self.variable_manager.extra_vars = extra_vars
            print('playbook 額外參數(shù):%s' % self.variable_manager.extra_vars)

            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:
            print("run_playbook:%s" % e) 
    
#    def run_rule(self, hosts, playbookfile, playbooktag):
#        """
#        run ansible palybook
#        """
#        try:
#            self.callback = ResultsCollector()
#            filenames = [playbookfile]  # playbook的路徑
#            print('ymal file path:%s' % filenames)
#
#            extra_vars = {}  # 額外的參數(shù) sudoers.yml以及模板中的參數(shù),它對應ansible-playbook test.yml --extra-vars "host='aa' name='cc' "
#            extra_vars['host'] = hosts
#            self.variable_manager.extra_vars = extra_vars
#            print('playbook 額外參數(shù):%s' % self.variable_manager.extra_vars)
#        
#            self.options = self.options._replace(tags=playbooktag)
##            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:
#            print("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']
        
        print("Ansible執(zhí)行結(jié)果集:%s" % json.dumps(self.results_raw, indent=4))
        return json.dumps(self.results_raw, indent=4) 

if __name__ == '__main__':
    res ={
        "app": {
            "hosts": [
                {
                    'hostname': '192.168.176.112'
                }
            ]
        },
        "one": {
            "hosts": [
                {
                    'username': 'root',
                    'hostname': '192.168.1.1',
                    'ip': '192.168.1.1',
                    'ssh_key': '/usr/local/python36/django/key/local', 
                    'password': '12345678', #password 不能認證
                    'port': 22
                }
            ]
       }
    }
    rapi = MyRunner(res)
    rapi.run('one', 'shell', 'ss -tnl')
    rapi.get_result()

python調(diào)用ansibleapi ,api版本是2.3的,這段配置的是秘鑰的密碼:('password': '12345678', #password 不能認證)執(zhí)行時沒有效果,一直卡住不動, 把這段去掉,也就是my_host.set_variable('ansible_ssh_pass', password)的password為None的時候在執(zhí)行會出現(xiàn)交互模式輸入密鑰密碼,哪里寫的有問題嗎,或者該怎么寫?? 0-0

注:是生成密鑰時設置的密碼,不是賬戶的密碼

回答
編輯回答
溫衫

from ansible import constants as C
C.HOST_KEY_CHECKING = False
加上這段代碼,關(guān)閉HOST_KEY檢查

2017年7月5日 12:14
編輯回答
骨殘心

好主意是全用SSH keys進行遠程登錄.

如果你執(zhí)意想用username/password方式, 可以通過建立inventory文件的方式存儲.默認放到/etc/ansible/hosts下面, 也可以用參數(shù)的方式指定-i <path>.

版本 Ansible <2.0:

[all:vars]
ansible_connection=ssh
ansible_ssh_user=用戶名 
ansible_ssh_pass=密碼

版本 Ansible >=2.0:

[all:vars]
ansible_connection=ssh 
ansible_user=用戶名 
ansible_pass=密碼

參考:
https://serverfault.com/quest...

2018年1月7日 04:45
編輯回答
有你在

有知道的嗎 0-0

2018年8月4日 18:12
編輯回答
心癌

本地配置SSH別名進行登錄。具體步驟見下文:
http://www.cnblogs.com/everfi...

2018年3月26日 05:55