通过ansible-api 来添加免密认证

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author : liuyu
# date : 2018/8/6 0006


from collections import namedtuple
from subprocess import Popen, PIPE
import re

from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.playbook.play import Play
from ansible.plugins.callback import CallbackBase
from ansible.vars.manager import VariableManager
import ansible.constants as C

C.HOST_KEY_CHECKING = False


def default_taskinfos():
    TaskInfos = {
        "hostinfo": [
            {
                "host": "0.0.0.0",
                "port": 22,
                "user": "root",
                "password": "root"
            },
        ],
        "taskinfo": [
            {
                "module": "setup",
                "args": ""
            },
        ]
    }
    return TaskInfos


# Create a callback object so we can capture the output
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


class AnsibleApi(object):

    def __init__(self, TaskInfos):
        self.taskinfo = TaskInfos.get('taskinfo', default_taskinfos()["taskinfo"])
        self.hostinfo = TaskInfos.get('hostinfo', default_taskinfos()["hostinfo"])
        self.resultinfo = []

    def run(self):
        host_list = []
        [host_list.append(i.get("host", '0.0.0.0')) for i in self.hostinfo]
        Options = namedtuple('Options', ['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'])
        # required for
        # https://github.com/ansible/ansible/blob/devel/lib/ansible/inventory/manager.py#L204
        sources = ','.join(host_list)
        if len(host_list) == 1:
            sources += ','

        # initialize needed objects
        loader = DataLoader()
        options = Options(connection='smart', module_path=['/usr/share/ansible'], forks=100,
                          remote_user=None, 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=None, verbosity=None, check=False, diff=False, )

        passwords = dict(sshpass=None, becomepass=None)

        # create inventory and pass to var manager
        inventory = InventoryManager(loader=loader, sources=sources)
        variable_manager = VariableManager(loader=loader, inventory=inventory)
        for host in self.hostinfo:
            inventory.add_host(host=host.get('host'), port=host.get('port'))
            hostname = inventory.get_host(hostname=host.get('host'))
            variable_manager.set_host_variable(host=hostname, varname='ansible_ssh_pass', value=host.get('password'))
            variable_manager.set_host_variable(host=hostname, varname='ansible_ssh_user', value=host.get('user'))
            variable_manager.set_host_variable(host=hostname, varname='ansible_ssh_port', value=host.get('port'))
            # print("设置全局管理变量 %s"%host.get('host'))
        # create play with tasks
        tasks = []
        # print(self.taskinfo)
        for task in self.taskinfo:
            # tasks.append(dict(action=dict(module=task.get("module"), args=task.get("args"))))
            play_source = dict(
                name="Ansible API Play",
                hosts=host_list,
                gather_facts='no',
                # tasks=[dict(action=dict(module='command', args=dict(cmd='/usr/bin/uptime')))]
                # tasks=[dict(action=dict(module='shell', args='/usr/sbin/ip a'))]
                tasks=[dict(action=dict(module=task.get("module"), args=task.get("args")))]
                # dict(action=dict(module='setup', args='')),
                #        dict(action=dict(module='setup', args=''),register='shell_out'),
                #        dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))

            )
            play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
            # actually run it
            tqm = None
            callback = ResultsCollector()
            try:
                tqm = TaskQueueManager(
                    inventory=inventory,
                    variable_manager=variable_manager,
                    loader=loader,
                    options=options,
                    passwords=passwords,
                )
                tqm._stdout_callback = callback
                result = tqm.run(play)
            finally:
                if tqm is not None:
                    tqm.cleanup()

            # print("UP ***********")
            # print(callback.host_ok.items())
            for host, result in callback.host_ok.items():
                try:
                    # print('{0} >>> {1}'.format(host, result._result['stdout']))
                    self.resultinfo.append({host: {"message":result._result['stdout'],"code":0}})
                except:
                    # print('{0} >>> {1}'.format(host, result._result['ansible_facts']))
                    self.resultinfo.append({host: {"message":result._result['ansible_facts'],"code":0}})

            # print("FAILED *******")
            for host, result in callback.host_failed.items():
                # print('{0} >>> {1}'.format(host, result._result['msg']))
                self.resultinfo.append({host: {"message":result._result['msg'],"code":1}})

            # print("DOWN *********")
            for host, result in callback.host_unreachable.items():
                # print('{0} >>> {1}'.format(host, result._result['msg']))
                self.resultinfo.append({host: {"message":result._result['msg'],"code":-1}})

        return self.resultinfo




def execshell(hostinfo, shellcmd):
    TaskInfos = {
        "hostinfo": [
            {
                "host": "10.1.41.210",
                "port": 65534,
                "user": "root",
                "password": "root"
            },
          
        ],
        "taskinfo": [
            {
                "module": "shell",
                "args": ""
            },
        ]
    }
    TaskInfos["hostinfo"]=hostinfo
    TaskInfos["taskinfo"][0]["args"] = shellcmd
    ansibleapi = AnsibleApi(TaskInfos)
    result = ansibleapi.run()
    return result



def setremotenopass(ip,port,username,password,fs):
    #data=execshell([{"host": ip,"port": port,"user": username,"password": password}], "sed -i '/oldauthorized/d' /root/.ssh/authorized_keys")
    data=execshell([{"host": ip,"port": port,"user": username,"password": password}], "echo {} >> /root/.ssh/authorized_keys".format(fs))

    child = Popen(["ssh -o StrictHostKeyChecking=no %s 'hostname && ip a| grep global'"%(ip)],shell=True,stdout=PIPE)
    out,err=child.communicate()
    print(data,out)

if __name__ == "__main__":
    
    
    password="hostpassword"
    port=15625
    id_rsa_file="/root/.ssh/id_rsa.pub"
    
    hosts="./ip"
    
    with open(hosts,'r') as f:
        lines=f.readlines()
    with open(id_rsa_file,'r') as fpub:
        fpubrsa=fpub.readlines()[0].strip('\n')


    for i in lines:
        result = re.findall(r"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b", i)
        if result:
           for ip in result:
               setremotenopass(ip,port,'root',password,fpubrsa)
  • 通过ansible-api 来添加免密认证已关闭评论
  • 1,478 views
    A+
发布日期:2018年09月13日  所属分类:Python