设为首页 收藏本站
查看: 819|回复: 0

[经验分享] ansible2.x 版本api 调用(适用于web开发使用)

[复制链接]

尚未签到

发表于 2018-7-29 11:20:23 | 显示全部楼层 |阅读模式
# ~*~ coding: utf-8 ~*~  
from __future__ import unicode_literals
  

  
import os
  
from collections import namedtuple, defaultdict
  
import sys
  
sys.path.append('hostinfo/ansible_runner/')
  

  

  
from ansible.executor.task_queue_manager import TaskQueueManager
  
from ansible.vars import VariableManager
  
from ansible.parsing.dataloader import DataLoader
  
from ansible.executor.playbook_executor import PlaybookExecutor
  
from ansible.playbook.play import Play
  
import ansible.constants as C
  
from ansible.utils.vars import load_extra_vars
  
from ansible.utils.vars import load_options_vars
  

  
from inventory import JMSInventory
  
from callback import AdHocResultCallback, PlaybookResultCallBack, \
  
    CommandResultCallback
  
#from common.utils import get_logger
  

  

  
__all__ = ["AdHocRunner", "PlayBookRunner"]
  

  
C.HOST_KEY_CHECKING = False
  

  
#logger = get_logger(__name__)
  

  

  
# Jumpserver not use playbook
  
class PlayBookRunner(object):
  
    """
  
    用于执行AnsiblePlaybook的接口.简化Playbook对象的使用.
  
    """
  
    Options = namedtuple('Options', [
  
        'listtags', 'listtasks', 'listhosts', 'syntax', 'connection',
  
        'module_path', 'forks', 'remote_user', 'private_key_file', 'timeout',
  
        'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
  
        'scp_extra_args', 'become', 'become_method', 'become_user',
  
        'verbosity', 'check', 'extra_vars'])
  

  
    def __init__(self,
  
                 hosts=None,
  
                 playbook_path=None,
  
                 forks=C.DEFAULT_FORKS,
  
                 listtags=False,
  
                 listtasks=False,
  
                 listhosts=False,
  
                 syntax=False,
  
                 module_path=None,
  
                 remote_user='root',
  
                 timeout=C.DEFAULT_TIMEOUT,
  
                 ssh_common_args=None,
  
                 ssh_extra_args=None,
  
                 sftp_extra_args=None,
  
                 scp_extra_args=None,
  
                 become=True,
  
                 become_method=None,
  
                 become_user="root",
  
                 verbosity=None,
  
                 extra_vars=None,
  
                 connection_type="ssh",
  
                 passwords=None,
  
                 private_key_file=None,
  
                 check=False):
  

  
        C.RETRY_FILES_ENABLED = False
  
        self.callbackmodule = PlaybookResultCallBack()
  
        if playbook_path is None or not os.path.exists(playbook_path):
  
            raise AnsibleError(
  
                "Not Found the playbook file: %s." % playbook_path)
  
        self.playbook_path = playbook_path
  
        self.loader = DataLoader()
  
        self.variable_manager = VariableManager()
  
        self.passwords = passwords or {}
  
        self.inventory = JMSInventory(hosts)
  

  
        self.options = self.Options(
  
            listtags=listtags,
  
            listtasks=listtasks,
  
            listhosts=listhosts,
  
            syntax=syntax,
  
            timeout=timeout,
  
            connection=connection_type,
  
            module_path=module_path,
  
            forks=forks,
  
            remote_user=remote_user,
  
            private_key_file=private_key_file,
  
            ssh_common_args=ssh_common_args or "",
  
            ssh_extra_args=ssh_extra_args or "",
  
            sftp_extra_args=sftp_extra_args,
  
            scp_extra_args=scp_extra_args,
  
            become=become,
  
            become_method=become_method,
  
            become_user=become_user,
  
            verbosity=verbosity,
  
            extra_vars=extra_vars or [],
  
            check=check
  
        )
  

  
        self.variable_manager.extra_vars = load_extra_vars(loader=self.loader,
  
                                                           options=self.options)
  
        self.variable_manager.options_vars = load_options_vars(self.options)
  

  
        self.variable_manager.set_inventory(self.inventory)
  

  
        # 初始化playbook的executor
  
        self.runner = PlaybookExecutor(
  
            playbooks=[self.playbook_path],
  
            inventory=self.inventory,
  
            variable_manager=self.variable_manager,
  
            loader=self.loader,
  
            options=self.options,
  
            passwords=self.passwords)
  

  
        if self.runner._tqm:
  
            self.runner._tqm._stdout_callback = self.callbackmodule
  

  
    def run(self):
  
        if not self.inventory.list_hosts('all'):
  
            raise AnsibleError('Inventory is empty')
  
        self.runner.run()
  
        self.runner._tqm.cleanup()
  
        return self.callbackmodule.output
  

  

  
class AdHocRunner(object):
  
    """
  
    ADHoc接口
  
    """
  
    Options = namedtuple("Options", [
  
        'connection', 'module_path', 'private_key_file', "remote_user",
  
        'timeout', 'forks', 'become', 'become_method', 'become_user',
  
        'check', 'extra_vars',
  
        ]
  
    )
  

  
    results_callback_class = AdHocResultCallback
  

  
    def __init__(self,
  
                 hosts=C.DEFAULT_HOST_LIST,
  
                 forks=C.DEFAULT_FORKS,  # 5
  
                 timeout=C.DEFAULT_TIMEOUT,  # SSH timeout = 10s
  
                 remote_user=C.DEFAULT_REMOTE_USER,  # root
  
                 module_path=None,  # dirs of custome modules
  
                 connection_type="smart",
  
                 become=None,
  
                 become_method=None,
  
                 become_user=None,
  
                 check=False,
  
                 passwords=None,
  
                 extra_vars=None,
  
                 private_key_file=None,
  
                 gather_facts='no'):
  

  
        self.pattern = ''
  
        self.variable_manager = VariableManager()
  
        self.loader = DataLoader()
  
        self.gather_facts = gather_facts
  
        self.results_callback = AdHocRunner.results_callback_class()
  
        self.options = self.Options(
  
            connection=connection_type,
  
            timeout=timeout,
  
            module_path=module_path,
  
            forks=forks,
  
            become=become,
  
            become_method=become_method,
  
            become_user=become_user,
  
            check=check,
  
            remote_user=remote_user,
  
            extra_vars=extra_vars or [],
  
            private_key_file=private_key_file,
  
        )
  

  
        self.variable_manager.extra_vars = load_extra_vars(self.loader,
  
                                                           options=self.options)
  
        self.variable_manager.options_vars = load_options_vars(self.options)
  
        self.passwords = passwords or {}
  
        self.inventory = JMSInventory(hosts)
  
        self.variable_manager.set_inventory(self.inventory)
  
        self.tasks = []
  
        self.play_source = None
  
        self.play = None
  
        self.runner = None
  

  
    @staticmethod
  
    def check_module_args(module_name, module_args=''):
  
        if module_name in C.MODULE_REQUIRE_ARGS and not module_args:
  
            err = "No argument passed to '%s' module." % module_name
  
            print(err)
  
            return False
  
        return True
  

  
    def run(self, task_tuple, pattern='all', task_name='Ansible Ad-hoc'):
  
        """
  
        :param task_tuple:  (('shell', 'ls'), ('ping', ''))
  
        :param pattern:
  
        :param task_name:
  
        :return:
  
        """
  
        for module, args in task_tuple:
  
            if not self.check_module_args(module, args):
  
                return
  
            self.tasks.append(
  
                dict(action=dict(
  
                    module=module,
  
                    args=args,
  
                ))
  
            )
  

  
        self.play_source = dict(
  
            name=task_name,
  
            hosts=pattern,
  
            gather_facts=self.gather_facts,
  
            tasks=self.tasks
  
        )
  

  
        self.play = Play().load(
  
            self.play_source,
  
            variable_manager=self.variable_manager,
  
            loader=self.loader,
  
        )
  

  
        self.runner = TaskQueueManager(
  
            inventory=self.inventory,
  
            variable_manager=self.variable_manager,
  
            loader=self.loader,
  
            options=self.options,
  
            passwords=self.passwords,
  
            stdout_callback=self.results_callback,
  
        )
  

  
        if not self.inventory.list_hosts("all"):
  
            raise AnsibleError("Inventory is empty.")
  

  
        if not self.inventory.list_hosts(self.pattern):
  
            raise AnsibleError(
  
                "pattern: %s  dose not match any hosts." % self.pattern)
  

  
        try:
  
            self.runner.run(self.play)
  
        except Exception as e:
  
            logger.warning(e)
  
        else:
  
            #logger.debug(self.results_callback.result_q)
  
            return self.results_callback.result_q
  
        finally:
  
            if self.runner:
  
                self.runner.cleanup()
  
            if self.loader:
  
                self.loader.cleanup_all_tmp_files()
  

  
    def clean_result(self):
  
        """
  
        :return: {
  
            "success": ['hostname',],
  
            "failed": [('hostname', 'msg'), {}],
  
        }
  
        """
  
        result = {'success': [], 'failed': []}
  
        for host in self.results_callback.result_q['contacted']:
  
            result['success'].append(host)
  

  
        for host, msgs in self.results_callback.result_q['dark'].items():
  
            msg = '\n'.join(['{} {}: {}'.format(
  
                msg.get('module_stdout', ''),
  
                msg.get('invocation', {}).get('module_name'),
  
                msg.get('msg', '')) for msg in msgs])
  
            result['failed'].append((host, msg))
  
        return result
  

  

  
def test_run():
  
    assets = [
  
        {
  
                "hostname": "192.168.244.129",
  
                "ip": "192.168.244.129",
  
                "port": 22,
  
                "username": "root",
  
                "password": "redhat",
  
        },
  
    ]
  
    task_tuple = (('shell', 'ls'),)  ##例子,调用普通的模块命令
  
    hoc = AdHocRunner(hosts=assets)
  
    hoc.results_callback = CommandResultCallback()
  
    ret = hoc.run(task_tuple)
  
    print(ret)
  

  
    task_tuple = (('setup',''),)  ##例子,调用setup,获取资产信息
  
    runner = AdHocRunner(assets)
  
    result = runner.run(task_tuple=task_tuple,pattern='all', task_name='Ansible Ad-hoc')
  
    print(result)
  

  
    #play = PlayBookRunner(assets, playbook_path='/tmp/some.yml')  ##yml
  
    """
  
    # /tmp/some.yml
  
    ---
  
    - name: Test the plabybook API.
  
      hosts: all
  
      remote_user: root
  
      gather_facts: yes
  
      tasks:
  
       - name: exec uptime
  
         shell: uptime
  
    """
  
    #play.run()
  

  

  
if __name__ == "__main__":
  
    test_run()

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-542961-1-1.html 上篇帖子: 浅谈Puppet、Chef、Ansible和SaltStack四大运维管理工具 下篇帖子: ansible yml语法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表