Exemple #1
0
class MyInventory():
    """
    this is ansible inventory object.
    """
    def __init__(self, resource, loader, variable_manager):
        self.resource = resource
        self.loader = DataLoader()
        self.inventory = InventoryManager(loader=self.loader, sources=['%s/conf/hostslist' %BASE_DIR])
        # self.variable_manager.set_inventory(self.inventory)
        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
        self.dynamic_inventory()

    def add_dynamic_group(self, hosts, groupname, groupvars=None):
        """add new hosts to a group"""
        self.inventory.add_group(groupname)
        my_group = Group(name=groupname)

        # if group variables exists, add them to group
        if groupvars:
            for key in groupvars:
                my_group.set_variable(key, groupvars[key])

        # 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)
            self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_host', value=hostip)
            self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_pass', value=password)
            self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_port', value=hostport)
            self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_user', value=username)
            self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_private_key_file', value=ssh_key)
            # my_host.set_variable('ansible_ssh_pass', password)
            # my_host.set_variable('ansible_ssh_private_key_file', ssh_key)

            # set other variables
            for key in host:
                if key not in ["hostname", "port", "username", "password"]:
                    self.variable_manager.set_host_variable(host=my_host, varname=key, value=host[key])

            # add to group
            self.inventory.add_host(host=hostname, group=groupname, port=hostport)
            #ghost = Host(name="192.168.8.119")

    def dynamic_inventory(self):
        """
            add new hosts to inventory.
        """
        if isinstance(self.resource, list):
            self.add_dynamic_group(self.resource, 'default_group')
        elif isinstance(self.resource, dict):
            for groupname in self.resource:
                self.add_dynamic_group(self.resource[groupname].get("hosts"), groupname, self.resource[groupname].get("vars"))
Exemple #2
0
def add_dynamic_host(hosts_list):
    loader = None
    inventory = InventoryManager(loader=loader, sources=resource)
    for hosts in hosts_list:
        hostname = hosts.get("hostname")
        hostport = hosts.get("hostport")
        password = hosts.get("password")
        username = hosts.get("username")
        my_host = Host(name=hostname, port=hostport)
        variable_manager = VariableManager(loader=loader, inventory=inventory)
        variable_manager.set_host_variable(host=my_host,
                                           varname='ansible_ssh_host',
                                           value=hostname)
        variable_manager.set_host_variable(host=my_host,
                                           varname='ansible_ssh_pass',
                                           value=password)
        variable_manager.set_host_variable(host=my_host,
                                           varname='ansible_ssh_port',
                                           value=hostport)
        variable_manager.set_host_variable(host=my_host,
                                           varname='ansible_ssh_user',
                                           value=username)
        inventory.add_host(host=hostname, port=hostport)
        print()
    print(hosts_list)
Exemple #3
0
def give_inventory_and_data_loader(
) -> Tuple[InventoryManager, dataloader.DataLoader, VariableManager]:
    data_loader = dataloader.DataLoader()
    # create the inventory, and filter it based on the subset specified (if any)
    inventory = InventoryManager(loader=data_loader, sources="localhost")

    inventory.add_group("all")
    inventory.add_group("ungrouped")
    inventory.add_host("localhost", group="ungrouped")
    inventory.add_host("spire_server", group="ungrouped")

    # create the variable manager, which will be shared throughout
    # the code, ensuring a consistent view of global variables
    var_manager = VariableManager(loader=data_loader,
                                  inventory=inventory,
                                  version_info=None)
    var_manager.set_host_variable("spire_server", "ansible_connection",
                                  "local")
    var_manager.set_host_variable("spire_server", "ansible_host", "localhost")
    python_path = sys.executable
    var_manager.set_host_variable("spire_server", "ansible_python_interpreter",
                                  python_path)
    var_manager.set_host_variable("localhost", "ansible_python_interpreter",
                                  python_path)

    return inventory, data_loader, var_manager
Exemple #4
0
    def _run_play(self, play_source, host_vars):
        host_list = play_source['hosts']

        loader = dataloader.DataLoader()

        # FIXME(jpena): we need to behave differently if we are using
        # Ansible >= 2.4.0.0. Remove when only versions > 2.4 are supported
        if PRE_24_ANSIBLE:
            variable_manager = VariableManager()
            inventory_inst = Inventory(loader=loader,
                                       variable_manager=variable_manager,
                                       host_list=host_list)
            variable_manager.set_inventory(inventory_inst)
        else:
            inventory_inst = Inventory(loader=loader,
                                       sources=','.join(host_list) + ',')
            variable_manager = VariableManager(loader=loader,
                                               inventory=inventory_inst)

        for host, variables in host_vars.items():
            host_inst = inventory_inst.get_host(host)
            for var_name, value in variables.items():
                if value is not None:
                    variable_manager.set_host_variable(
                        host_inst, var_name, value)

        storage = []
        callback = MyCallback(storage)

        tqm = task_queue_manager.TaskQueueManager(
            inventory=inventory_inst,
            variable_manager=variable_manager,
            loader=loader,
            options=self.options,
            passwords=self.passwords,
            stdout_callback=callback,
        )

        # create play
        play_inst = play.Play().load(play_source,
                                     variable_manager=variable_manager,
                                     loader=loader)

        # actually run it
        try:
            tqm.run(play_inst)
        finally:
            tqm.cleanup()

        return storage
Exemple #5
0
def execute(playbooks: list, context: dict):
    '''
    '''
    assert playbooks

    os.environ["ANSIBLE_CONDITIONAL_BARE_VARS"] = "False"

    # ctx._init_global_context({})
    # since the API is constructed for CLI it expects certain options to always be set in the context object
    ctx.CLIARGS = ImmutableDict(connection='local',
                                module_path=['./playbooks/roles'],
                                forks=1,
                                become=False,
                                become_method="sudo",
                                syntax=False,
                                start_at_task=None,
                                diff=False,
                                verbosity=0)

    # initialize needed objects
    loader = DataLoader(
    )  # Takes care of finding and reading yaml, json and ini files
    # passwords = dict(become_pass="******")
    passwords = dict()

    # Instantiate our ResultCallback for handling results as they come in. Ansible expects this to be one of its main display outlets
    results_callback = ResultCallback()

    # create inventory, use path to host config file as source or hosts in a comma separated string
    inventory = InventoryManager(loader=loader, sources='localhost,')

    host = Host(name="localhost")
    # variable manager takes care of merging all the different sources to give you a unified view of variables available in each context
    variable_manager = VariableManager(loader=loader, inventory=inventory)

    variable_manager.set_host_variable(host, "current_directory",
                                       context.get("current_directory", ""))

    pbex = PlaybookExecutor(playbooks=playbooks,
                            inventory=inventory,
                            variable_manager=variable_manager,
                            loader=loader,
                            passwords=passwords)
    result = pbex.run()
    post_command = variable_manager.get_vars()["hostvars"]["localhost"].get(
        "mondrik_post_command")
    return result, post_command
Exemple #6
0
class BasisAnsibleobject(object):
    def __init__(self, ):
        self.loader = DataLoader()
        self.options = Options(connection='smart', module_path='/path/to/mymodules', forks=100, timeout=10,
                               remote_user='******', private_key_file='/root/.ssh/id_rsa', ask_pass=False, ssh_common_args=None,
                               ssh_extra_args=None,
                               sftp_extra_args=None, scp_extra_args=None, become=None, become_method=None,
                               become_user=None, ask_value_pass=False, verbosity=None, check=False, listhosts=False,
                               listtasks=False, listtags=False, syntax=False, diff=False)

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

        self.inventory = InventoryManager(loader=self.loader, sources='/etc/ansible/hosts')
        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)

    def createplay(self, filename, hosts, taskid, username, password, sshLoginType, systemType, command):  # action
        try:
            with open('/etc/ansible/{0}'.format(hosts), 'w') as f:
                f.writelines(hosts)
        except Exception as e:
            # logger.error("【错误】 ansible配置文件写入失败 -- mission.py line68")
            pass

        self.inventory = InventoryManager(loader=self.loader, sources='/etc/ansible/{0}'.format(hosts))
        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)

        if sshLoginType == 'ssh_key' and systemType == 'linux':
            command = "iptables-save"  #重启防火墙命令
            remote_command = command
            self.variable_manager.set_host_variable(Host(hosts, '22'), 'ansible_ssh_user', username)
            self.variable_manager.set_host_variable(Host(hosts, '22'), 'ansible_ssh_pass', password)

            play_source = dict(
                name="Ansible Play",
                hosts='all',
                gather_facts='no',
                tasks=[
                    dict(action=dict(module="command", args=remote_command)),
                    dict(action=dict(module="command", args=command)),
                    dict(action=dict(module="command", args="firewall-cmd --reload")),

                ]
            )

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

        return self.play,self.variable_manager,self.inventory
Exemple #7
0
def autocreate_publickey(host_list, password, jobid):
    C.HOST_KEY_CHECKING = False
    loader = DataLoader()
    options = Options(connection='smart',
                      forks=5,
                      ssh_common_args='-C -o ControlPersist=30s')
    passwords = dict()
    if len(host_list) <= 1:
        sources = host_list[0] + ','
    else:
        sources = ','.join(host_list)
    inventory = InventoryManager(loader=loader, sources=sources)
    variable_manager = VariableManager(loader=loader, inventory=inventory)
    for host in host_list:
        host_info = Host(name=host, port=22)
        variable_manager.set_host_variable(host_info, 'ansible_ssh_user',
                                           'root')
        variable_manager.set_host_variable(host_info, 'ansible_ssh_pass',
                                           password)
    play_source = dict(
        name='Generate Publickey',
        hosts=host_list,
        gather_facts='no',
        tasks=[
            dict(action=dict(
                module='authorized_key',
                args=dict(user='******',
                          key="{{ lookup('file','/root/.ssh/id_rsa.pub') }}")))
        ])
    play = Play().load(play_source,
                       variable_manager=variable_manager,
                       loader=loader)
    tqm = None
    callback = ResultsCollector(jobid)
    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()
    return callback.result
Exemple #8
0
class MyInventory:
    """
    Ansible Inventory
    """

    def __init__(self, resource, loader, variable_manager):
        self.resource = resource
        self.loader = DataLoader()
        self.inventory = InventoryManager(loader=self.loader, sources=['/etc/ansible/hosts'])
        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
        self.dynamic_inventory()

    def add_dynamic_group(self, hosts, groupname, groupvars=None):
        """
            add hosts to a group
        """
        self.inventory.add_group(groupname)
        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")
            my_host = Host(name=hostname, port=hostport)
            self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_host', value=hostip)
            self.variable_manager.set_host_variable(host=my_host, varname='ansible_ssh_port', value=hostport)

            # set other variables
            for key, value in host.iteritems():
                if key not in ["hostname", "port", "username", "password"]:
                    self.variable_manager.set_host_variable(host=my_host, varname=key, value=value)

            # add to group
            self.inventory.add_host(host=hostname, group=groupname, port=hostport)

    def dynamic_inventory(self):
        """
            add hosts to inventory.
        """
        if isinstance(self.resource, list):
            self.add_dynamic_group(self.resource, 'default_group')
        elif isinstance(self.resource, dict):
            for groupname, hosts_and_vars in self.resource.iteritems():
                self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
        else:
            pass
Exemple #9
0
# create inventory and pass to var manager
inventory = InventoryManager(loader=loader, sources=None)

#variable_manager = VariableManager(loader=loader, inventory=inventory)
hostname = 'test1'
hostport = 22
hostip = '127.0.0.1'
password = '******'
username = '******'
variable_manager = VariableManager(loader=loader, inventory=inventory)

my_host = Host(name=hostname, port=hostport)

variable_manager.set_host_variable(host=my_host,
                                   varname='ansible_ssh_host',
                                   value=hostip)
variable_manager.set_host_variable(host=my_host,
                                   varname='ansible_ssh_pass',
                                   value=password)
variable_manager.set_host_variable(host=my_host,
                                   varname='ansible_ssh_port',
                                   value=hostport)
variable_manager.set_host_variable(host=my_host,
                                   varname='ansible_ssh_user',
                                   value=username)
# variable_manager.set_host_variable(host=my_host,varname='ansible_become_pass',value='tusbasa1')
# variable_manager.set_host_variable(host=my_host,varname='ansible_become',value=True)
# variable_manager.set_host_variable(host=my_host,varname='ansible_become_method',value='sudo')
# variable_manager.set_host_variable(host=my_host,varname='ansible_become_user',value='root')
Exemple #10
0
from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager
from ansible.vars.manager import VariableManager

loader = DataLoader()
inventory = InventoryManager(loader=loader, sources='hosts')
variable_manager = VariableManager(loader=loader, inventory=inventory)
host = inventory.get_host('192.168.10.150')
# get_vars() # 查看变量
print(variable_manager.get_vars(host=host))
# set_host_variable() # 修改指定主机的变量信息
variable_manager.set_host_variable(host=host,
                                   varname="ansible_ssh_pass",
                                   value="1111111")
print(variable_manager.get_vars(host=host))
print(variable_manager.__dict__)
# _extra_vars={} # 添加指定对象的扩展变量,全局有效
variable_manager._extra_vars = {'mysite': "ys.blog.com"}
print(variable_manager.get_vars(host=host))
Exemple #11
0
class PackageInstallerTask():
    #: Name of the task.
    name = 'PackageInstallerTask'

    def __init__(self, host_dict):
        self.package = None
        self.connection_type = None
        self.connection_port = None
        self.connection_user = None
        self.ansible_password = None
        self.loader = self.get_loader()
        self.variable_manager = VariableManager(loader=self.loader)
        self.inventory = create_inventory(host_dict, self.variable_manager,
                                          self.loader, self.ansible_password)

    def get_loader(self, base_dir='../playbooks'):
        loader = DataLoader(
        )  # Takes care of finding and reading yml, json and ini files
        loader.set_basedir(base_dir)
        return loader

    def variable_manager_initialization(self, ip_address):
        for host in self.inventory._inventory.hosts.values():
            for group in host.groups:
                if group.name == 'ubuntu':
                    self.variable_manager.set_host_variable(
                        host, 'ansible_connection', self.connection_type)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_host', ip_address)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_port', self.connection_port)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_user', self.connection_user)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_ssh_private_key_file',
                        '/home/ansible/.ssh/id_rsa')
                    self.variable_manager.set_host_variable(
                        host, 'ansible_become_user', self.connection_user)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_become', 'yes')
                    self.variable_manager.set_host_variable(
                        host, 'ansible_become_password', 'Mp3b27')
                if group.name == 'windows':
                    self.variable_manager.set_host_variable(
                        host, 'ansible_user', self.connection_user)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_password', self.ansible_password)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_port', self.connection_port)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_username', self.connection_user)
                    self.variable_manager.set_host_variable(
                        host, 'ansible_connection', 'winrm')
                    self.variable_manager.set_host_variable(
                        host, 'ansible_winrm_transport', 'ntlm')
                    self.variable_manager.set_host_variable(
                        host, 'ansible_winrm_server_cert_validation', 'ignore')

    def _install(self, ip_address):
        # initialize needed objects
        # self.variable_manager_initialization(ip_address)
        host_list = [ip_address]
        hosts = ','.join(host_list)
        if len(host_list) == 1:
            hosts += ','

        package = [self.package]
        # create data structure that represents our play
        # including tasks, this is basically what our YAML loader does internally.

        print(f'hosts : {ip_address} \n roles : {package}')

        play_source = {
            'hosts': hosts,
            'gather_facts': True,
            'become': True,
            'become_user': '******',
            'become_method': 'sudo',
            'roles': package
        }
        passwords = dict()
        results_callback = ResultsCollectorJSONCallback()
        tqm = TaskQueueManager(
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            passwords=passwords,
            stdout_callback=results_callback,
        )

        # Create play object, playbook objects use .load instead of init or new methods,
        # this will also automatically create the task objects from the info provided in play_source
        play = Play().load(play_source,
                           variable_manager=self.variable_manager,
                           loader=self.loader,
                           vars={'ansible_become_pass': '******'})

        # Actually run it
        try:
            result = tqm.run(
                play
            )  # most interesting data for a play is actually sent to the callback's methods
        finally:
            # we always need to cleanup child procs and the structures we use to communicate with them
            tqm.cleanup()
            if self.loader:
                self.loader.cleanup_all_tmp_files()
        shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
        print("UP ***********")
        for host, result in results_callback.host_ok.items():
            print('{0} >>> {1}'.format(host, result._result))

        print("FAILED *******")
        for host, result in results_callback.host_failed.items():
            print('{0} >>> {1}'.format(host, result._result['msg']))

        print("DOWN *********")
        for host, result in results_callback.host_unreachable.items():
            print('{0} >>> {1}'.format(host, result._result['msg']))

    def run(self, ip_address, package, connection_type, connection_user,
            connection_port, ansible_password):

        print(f'ip: {ip_address}, connection_user: {connection_user}')

        self.package = package
        self.connection_type = connection_type
        self.connection_port = connection_port
        self.connection_user = connection_user
        self.ansible_password = ansible_password
        self._install(ip_address)
Exemple #12
0
class MyInventory:
    """
    动态生成/etc/ansible/hosts文件
    """
    def __init__(self, hosts_resource):
        #  hosts_resource = {
        #         "Group1": {
        #             "hosts": [{"ip": "10.0.0.62", "port": "22", "username": "******", "password": "******"},
        #                       {"ip": "10.0.0.61", "port": "22", "username": "******", "password": "******"}],
        #             "group_vars": {"var1": "ansible"}
        #         },
        #         # "Group2": {}
        #     }
        self.hosts_resource = hosts_resource
        self.loader = DataLoader()
        self.hosts_file = [""]
        """
        sources这个我们知道这里是设置hosts文件的地方,它可以是一个列表里面包含多个文件路径且文件真实存在,在单纯的执行ad-hoc的时候这里的
        文件里面必须具有有效的hosts配置,但是当通过动态生成的资产信息的时候这个文件必须存在但是它里面可以是空的,如果这里配置成None那么
        它不影响资产信息动态生成但是会有一个警告
         [WARNING]: No inventory was parsed, only implicit localhost is available

         {'all': [], 'ungrouped': [], 'Group1': ['10.0.0.62', '10.0.0.61']}
        """
        self.inventory = InventoryManager(loader=self.loader, sources=self.hosts_file)
        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
        self.dynamic_inventory()

    def add_hosts_group(self, hosts_list, group_name, group_vars=None):
        """
        动态添加主机到指定的主机组

        完整的HOSTS文件格式
        [test1]
        hostname ansible_ssh_host=192.168.1.111 ansible_ssh_user="******" ansible_ssh_pass="******"

        但通常我们都省略hostname,端口也省略因为默认是22,这个在ansible配置文件中有,除非有非22端口的才会配置
        [test1]
        192.168.100.10 ansible_ssh_user="******" ansible_ssh_pass="******" ansible_python_interpreter="/usr/bin/python3"
        [test2]
        192.168.100.10 ansible_ssh_user="******" ansible_ssh_pass="******" ansible_python_interpreter="/usr/bin/python3"
        [parent_group:children]
        test1
        test2
        [test2:vars]
        touch_file=new_file
        :param hosts_list: 主机列表 [{"hostname":"m01","ip": "192.168.100.10", "port": "22",
                                     "username": "******", "password": None}, {}]
        :param group_name:  组名称
        :param group_vars:  组变量,格式为字典group_vars={"var1": "ansible"}
        :return:
        """
        # 如果主机组不存在,就添加主机组,如果存在,就直接获取
        if not self.inventory.groups.get(group_name):
            self.inventory.add_group(group_name)
        # 返回值是Group对象,注意这里一定要保证是同一个对象
        inventory_group = self.inventory.groups.get(group_name)
        # 如果组变量存在,就设置组变量,可用于playbook中
        if group_vars:
            for key, value in group_vars.items():
                inventory_group.set_variable(key, value)
        for host in hosts_list:
            ip = host.get("ip", None)
            hostname = host.get("hostname", ip)
            port = host.get("port", "22")
            username = host.get("username")
            password = host.get("password", None)
            ssh_key = host.get("ssh_key", None)
            python_interpreter = host.get("python_interpreter", None)

            try:
                host_obj = Host(name=hostname, port=port)
                self.variable_manager.set_host_variable(host=host_obj, varname="ansible_ssh_host", value=ip)
                self.variable_manager.set_host_variable(host=host_obj, varname="ansible_ssh_port", value=port)
                self.variable_manager.set_host_variable(host=host_obj, varname="ansible_ssh_user", value=username)
                if password:
                    self.variable_manager.set_host_variable(host=host_obj,
                                                            varname="ansible_ssh_pass",
                                                            value=password)
                if ssh_key:
                    self.variable_manager.set_host_variable(host=host_obj,
                                                            varname="ansible_ssh_private_key_file",
                                                            value=ssh_key)
                if python_interpreter:
                    self.variable_manager.set_host_variable(host=host_obj,
                                                            varname="ansible_python_interpreter",
                                                            value=python_interpreter)

                # 添加其他变量
                for key, value in host.items():
                    if key not in ["ip", "hostname", "port", "username", "password", "ssh_key", "python_interpreter"]:
                        self.variable_manager.set_host_variable(host=host_obj, varname=key, value=value)

                # 添加主机到主机组
                self.inventory.add_host(host=hostname, group=group_name, port=port)
            except Exception as e:
                print(e)

    def dynamic_inventory(self):
        # 为了以后扩展,我们先把该段内容写在这里
        for group_name, hosts_and_vars in self.hosts_resource.items():
            self.add_hosts_group(hosts_and_vars.get("hosts"), group_name, hosts_and_vars.get("group_vars"))

    @property
    def inventory_obj(self):
        """
        返回inventory對象
        :return:
        """
        return self.inventory

    @property
    def variable_manager_obj(self):
        """
       返回variable_manager對象
       :return:
       """
        return self.variable_manager
Exemple #13
0
class AnsibleConfigurer:
    def __init__(self, options=None):
        if not options:
            options = {}
        self.options = options

        self.loader = DataLoader()
        if "inventory_path" in self.options:
            sources = self.options["inventory_path"]
        else:
            sources = None

        self.inventory_manager = InventoryManager(self.loader, sources=sources)

        self.variable_manager = VariableManager(
            loader=self.loader, inventory=self.inventory_manager)

        # TODO load ansible configuration
        self.config_manager = ConfigManager()

    def gen_configuration(self, options=None):
        configuration = {}
        if not options:
            options = {}

        configuration["host_variables"] = dict(
            ansible_connection="ssh",
            ansible_ssh_common_args="-o HostKeyAlgorithms={}".format(
                ",".join(default_host_key_order)),
        )

        if "host_variables" in options and isinstance(
                options["host_variables"], dict):
            configuration["host_variables"].update(options["host_variables"])

        configuration["host_settings"] = {}
        if "host_settings" in options and isinstance(options["host_settings"],
                                                     dict):
            configuration["host_settings"].update(options["host_settings"])

        configuration["apply_kwargs"] = {}
        if "apply_kwargs" in options and isinstance(options["apply_kwargs"],
                                                    dict):
            configuration["apply_kwargs"].update(options["apply_kwargs"])
        return configuration

    def format_configuration(self, configuration, kwargs=None):
        if not kwargs:
            kwargs = {}

        host_variables_kwargs = {
            k: v
            for k, v in configuration["host_variables"].items() if
            isinstance(v, str) or isinstance(v, list) or isinstance(v, dict)
        }

        host_settings_kwargs = {
            k: v
            for k, v in configuration["host_settings"].items() if
            isinstance(v, str) or isinstance(v, list) or isinstance(v, dict)
        }

        apply_kwargs = {
            k: v
            for k, v in configuration["apply_kwargs"].items() if
            isinstance(v, str) or isinstance(v, list) or isinstance(v, dict)
        }

        # Format with kwargs
        for key, value in kwargs.items():
            try:
                recursive_format(host_variables_kwargs, {key: value})
                recursive_format(host_settings_kwargs, {key: value})
                recursive_format(apply_kwargs, {key: value})
            except TypeError:
                pass

        configuration["host_variables"].update(host_variables_kwargs)
        configuration["host_settings"].update(host_settings_kwargs)
        configuration["apply_kwargs"].update(apply_kwargs)
        return configuration

    def apply(self, host, configuration=None, credentials=None):
        if not configuration:
            configuration = {}

        if ("group" in configuration["host_settings"]
                and configuration["host_settings"]["group"]):
            self.inventory_manager.add_group(
                configuration["host_settings"]["group"])

        if host not in self.inventory_manager.hosts:
            self.inventory_manager.add_host(host,
                                            **configuration["host_settings"])

        for k, v in configuration["host_variables"].items():
            self.variable_manager.set_host_variable(host, k, v)

        if "playbook_paths" not in configuration["apply_kwargs"]:
            return False

        if not isinstance(configuration["apply_kwargs"]["playbook_paths"],
                          (list, set)):
            return False

        for playbook_path in configuration["apply_kwargs"]["playbook_paths"]:
            # Expand the playbook path if it is using relative paths
            playbook_path = os.path.expanduser(playbook_path)
            if not exists(playbook_path):
                print("The playbook_path: {} does not exist".format(
                    playbook_path))
                return False

            if credentials:
                self.variable_manager.set_host_variable(
                    host, "ansible_ssh_private_key_file",
                    credentials.private_key_file)

            playbook = Playbook.load(
                playbook_path,
                variable_manager=self.variable_manager,
                loader=self.loader,
            )

            plays = playbook.get_plays()
            for play in plays:
                if not run_playbook(
                        play,
                        variable_manager=self.variable_manager,
                        inventory_manager=self.inventory_manager,
                        loader=self.loader,
                ):
                    return False
        return True

    @classmethod
    def validate_options(cls, options):
        if not isinstance(options, dict):
            raise TypeError("options is not a dictionary")
Exemple #14
0
class MyInventory():
    """
    动态添加resource,中定义的主机组信息到inventory文件中和并进行相关变量操作
    """
    def __init__(self, resource, loader, variable_manager):
        self.resource = resource  # 我们需要动态添加的主机信息
        self.loader = DataLoader()
        self.inventory = InventoryManager(
            loader=self.loader, sources=['%s/conf/auto_hosts' % BASE_DIR])
        # self.variable_manager.set_inventory(self.inventory)
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        self.dynamic_inventory()

    def add_dynamic_group(self, hosts, groupname, groupvars=None):
        """
        将主机添加到对应主机组中
        """
        self.inventory.add_group(groupname)
        my_group = Group(name=groupname)

        # 判断是否有主机组变量
        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)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_host',
                                                    value=hostip)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_pass',
                                                    value=password)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_port',
                                                    value=hostport)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_user',
                                                    value=username)
            self.variable_manager.set_host_variable(
                host=my_host,
                varname='ansible_ssh_private_key_file',
                value=ssh_key)

            # 判断是否还有除hostname,port,username,password之外的变量
            for key, value in host.items():
                if key not in ["hostname", "port", "username", "password"]:
                    self.variable_manager.set_host_variable(host=my_host,
                                                            varname=key,
                                                            value=value)

            # 添加到指定主机组
            self.inventory.add_host(host=hostname,
                                    group=groupname,
                                    port=hostport)

    def dynamic_inventory(self):
        """
        动态添加主机到inventory
        支持列表和字典形式的添加
        :return:
        """
        if isinstance(self.resource, list):
            self.add_dynamic_group(self.resource, 'default_group')
        elif isinstance(self.resource, dict):
            for groupname, hosts_and_vars in self.resource.items():
                self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname,
                                       hosts_and_vars.get("vars"))
class ExecPlaybook(object):
    def __init__(self, playbooks=[], track_id=None):
        ResultModel().inster({"track_id": track_id, "status": "init"})
        self.playbooks = playbooks
        self.track_id = track_id
        self.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'
        ])
        self.options = self.Options(listtags=False,
                                    listtasks=False,
                                    listhosts=False,
                                    syntax=False,
                                    connection='ssh',
                                    module_path=None,
                                    forks=50,
                                    remote_user='******',
                                    private_key_file=None,
                                    ssh_common_args=None,
                                    ssh_extra_args=None,
                                    sftp_extra_args=None,
                                    scp_extra_args=None,
                                    become=True,
                                    become_method=None,
                                    become_user='******',
                                    verbosity=None,
                                    check=False,
                                    diff=False)
        self.loader = DataLoader()

        self.passwords = dict(vault_pass='******')

        self.inventory = InventoryManager(loader=self.loader, sources='')

        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)

    def add_host(self,
                 host,
                 port=None,
                 user=None,
                 passwd=None,
                 private_file=None):
        h = Host(host, port)
        self.inventory.add_host(host, 'all', port)
        self.inventory.add_host(host, 'all', port)
        if user:
            self.variable_manager.set_host_variable(h, 'ansible_ssh_user',
                                                    user)
        if passwd:
            self.variable_manager.set_host_variable(h, 'ansible_ssh_pass',
                                                    passwd)
        if private_file:
            self.variable_manager.set_host_variable(
                h, 'ansible_ssh_private_key_file', private_file)

    def run(self):
        play = PlaybookExecutor(playbooks=self.playbooks,
                                passwords=self.passwords,
                                inventory=self.inventory,
                                loader=self.loader,
                                variable_manager=self.variable_manager,
                                options=self.options)
        # play._tqm._stdout_callback = CallbackModule()
        play._tqm._stdout_callback = ResultCallback(track_id=self.track_id)
        return play.run()

    def add_playbook_vars(self, key, value):
        extra_vars = self.variable_manager.extra_vars
        extra_vars[key] = value
        self.variable_manager.extra_vars = extra_vars

    def get_playbook_vars(self):

        self.variable_manager.get_vars(play=self.playbooks)
Exemple #16
0
class ANSRunner(object):
    """
    This is a General object for parallel execute modules.
    """

    def __init__(self, ips=None, user='******', topology=None, inventory=None, tiargs=None, passwd=None,
                 *args, **kwargs):
        self.ips = ips
        self.list_ip_check()
        self.user = user
        self.topology = topology
        self.inventory = inventory
        self.variable_manager = None
        self.loader = None
        self.options = None
        self.password = passwd
        self.callback = None
        try:
            self.forks = tiargs.forks
        except AttributeError:
            self.forks = 5
        self.results_raw = {}
        try:
            self.cluster_name = tiargs.cluster_name
        except AttributeError:
            pass
        try:
            self.private_key = tiargs.private_key
        except AttributeError:
            self.private_key = None
        self.__initializeData()

    def list_ip_check(self):
        if not self.ips or len(self.ips) < 1:
            return
        iplist = []
        if ',' in self.ips:
            for ip in self.ips.split(','):
                if not ip or not utils.is_valid_ip(ip):
                    continue
                iplist.append(ip)
        else:
            iplist.append(self.ips)
        ipsstr = ','.join(iplist)
        if len(iplist) == 1:
            ipsstr += ','
        return ipsstr

    def __initializeData(self):
        """ 初始化ansible """

        C.DEFAULT_FILTER_PLUGIN_PATH.append(
            '{}/tiops/ansibleapi/plugins/filter'.format(os.environ['TIUP_COMPONENT_INSTALL_DIR']))
        C.HOST_KEY_CHECKING = False
        C.ANSIBLE_SSH_ARGS = '-C -o ControlMaster=auto -o ControlPersist=1d'
        C.PIPELINING = True
        C.CACHE_PLUGIN = 'jsonfile'
        C.CACHE_PLUGIN_CONNECTION = '~/.ansible/ansible_fact_cache'
        C.CACHE_PLUGIN_TIMEOUT = 86400
        C.DEFAULT_GATHER_TIMEOUT = 120

        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',
                              'diff'])

        self.options = Options(connection='smart',
                               module_path=None,
                               forks=self.forks,
                               timeout=60,
                               remote_user=self.user,
                               ask_pass=False,
                               private_key_file=self.private_key,
                               ssh_common_args=None,
                               ssh_extra_args=None,
                               sftp_extra_args=None,
                               scp_extra_args=None,
                               become=None,
                               become_method='sudo',
                               become_user='******',
                               ask_value_pass=False,
                               verbosity=None,
                               check=False,
                               listhosts=False,
                               listtasks=False,
                               listtags=False,
                               syntax=False,
                               diff=True)

        # generate an Ansible inventory object from the topology
        def inventory(topology):
            for grp, srvs in topology.items():
                if grp not in self.inventory.groups:
                    self.inventory.add_group(grp)
                for srv in srvs:
                    self.inventory.add_host(
                        srv.get('uuid', srv['ip']), group=grp, port=srv['ssh_port'])

            self.variable_manager = VariableManager(
                loader=DataLoader(), inventory=self.inventory)
            for group in self.inventory.get_groups_dict().iterkeys():
                for items in self.inventory.get_groups_dict()[group]:
                    host = self.inventory.get_host(hostname=str(items))
                    self.variable_manager.set_host_variable(
                        host=host, varname='ansible_user', value=self.user)

                    for vars in topology[group]:
                        if vars.get('uuid', vars['ip']) != items:
                            continue
                        for key, value in vars.items():
                            if key == 'uuid' or key == 'ssh_port':
                                continue
                            if key == 'ip':
                                self.variable_manager.set_host_variable(
                                    host=host, varname='ansible_host', value=value)
                            else:
                                self.variable_manager.set_host_variable(
                                    host=host, varname=key, value=value)
                        self.variable_manager.set_host_variable(host=host, varname='numa_node',
                                                                value=vars['numa_node'])
                        if group == 'tidb_servers':
                            service_name = 'tidb-{}'.format(vars['port'])
                            self.variable_manager.set_host_variable(host=host, varname='service_name',
                                                                    value=service_name)
                        elif group == 'pd_servers':
                            service_name = 'pd-{}'.format(vars['client_port'])
                            self.variable_manager.set_host_variable(host=host, varname='service_name',
                                                                    value=service_name)
                        elif group == 'tikv_servers':
                            service_name = 'tikv-{}'.format(vars['port'])
                            self.variable_manager.set_host_variable(host=host, varname='service_name',
                                                                    value=service_name)
                        elif group == 'grafana_server':
                            service_name = 'grafana-{}'.format(vars['port'])
                            self.variable_manager.set_host_variable(host=host, varname='service_name',
                                                                    value=service_name)
                        elif group == 'pump_servers':
                            service_name = 'pump-{}'.format(vars['port'])
                            self.variable_manager.set_host_variable(host=host, varname='service_name',
                                                                    value=service_name)
                        elif group == 'drainer_servers':
                            service_name = 'drainer-{}'.format(vars['port'])
                            self.variable_manager.set_host_variable(host=host, varname='service_name',
                                                                    value=service_name)
                        elif group == 'alertmanager_server':
                            service_name = 'alertmanager-{}'.format(vars['web_port'])
                            self.variable_manager.set_host_variable(host=host, varname='service_name',
                                                                    value=service_name)

            return inventory

        self.password = dict(conn_pass=self.password)
        self.loader = DataLoader()
        self.ips = self.list_ip_check()
        if self.ips:
            self.inventory = InvManager(loader=self.loader,
                                        sources=self.ips)
            self.variable_manager = VariableManager(
                loader=DataLoader(), inventory=self.inventory)
        else:
            if self.topology:
                self.inventory = InvManager(loader=self.loader,
                                            sources=self.inventory)
                inventory(self.topology)

    def run_model(self, module_name, module_args, become=False, register=None, with_items=None, group='*',
                  extra_vars=None, node=None):
        """
        run module from andible ad-hoc.
        module_name: ansible module_name
        module_args: ansible module args
        """
        if self.topology:
            service_names = {'node_exporter': ['monitored_servers', 'node_exporter_port'],
                             'blackbox_exporter': ['monitored_servers', 'blackbox_exporter_port'],
                             'prometheus': ['monitoring_server', 'prometheus_port'],
                             'pushgateway': ['monitoring_server', 'pushgateway_port']}

            if extra_vars in service_names and service_names[extra_vars][0] in self.inventory.get_groups_dict():
                for host in self.inventory.get_groups_dict()[service_names[extra_vars][0]]:
                    hostname = self.inventory.get_host(hostname=host)
                    service_name = '{}-{}'.format(extra_vars, self.variable_manager.get_vars(
                        host=hostname)[service_names[extra_vars][1]])
                    self.variable_manager.set_host_variable(
                        host=hostname, varname='service_name', value=service_name)

            if self.cluster_name and extra_vars:
                self.variable_manager.extra_vars = {
                    'cluster_name': self.cluster_name, 'service': extra_vars}
            else:
                self.variable_manager.extra_vars = {
                    'cluster_name': self.cluster_name}

        if register and with_items:
            task = [dict(action=dict(module=module_name,
                                     args=module_args),
                         become=become,
                         register=register,
                         with_items=with_items)]
        elif register is None and with_items:
            task = [dict(action=dict(module=module_name,
                                     args=module_args),
                         become=become,
                         with_items=with_items)]
        elif register and with_items is None:
            task = [dict(action=dict(module=module_name,
                                     args=module_args),
                         become=become,
                         register=register)]
        else:
            task = [dict(action=dict(module=module_name,
                                     args=module_args),
                         become=become)]

        if node:
            node_list = node.split(',')
            if len(node_list) == 1:
                node_str = '{},'.format(node)
            else:
                node_str = ','.join(node_list)

        play_source = dict(
            name="Ansible Play",
            hosts=self.ips if self.ips else (node_str if node else group),
            gather_facts='no',
            tasks=task
        )

        play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)
        tqm = None
        self.callback = ModelResultsCollector()
        import traceback
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.password,
                stdout_callback="minimal",
            )
            tqm._stdout_callback = self.callback
            tqm.run(play)
        except Exception as e:
            term.warn(str(e))
            term.debug(traceback.print_exc())
        finally:
            if tqm is not None:
                tqm.cleanup()

        result = self.get_model_result()
        failed = {}
        unreachable = {}

        offline_list = []

        if self.topology:
            for grp in ['drainer_servers', 'pump_servers', 'tikv_servers']:
                if not self.topology.has_key(grp) or not self.topology[grp]:
                    continue
                for _node in self.topology[grp]:
                    if _node['offline']:
                        offline_list.append(_node['uuid'])

        if result['success']:
            for _uuid, _info in result['success'].iteritems():
                _ip = _info['ansible_host']
                if _info.has_key('stderr') and _info['stderr']:
                    try:
                        failed[_uuid][_ip].append(_info['stderr'])
                    except:
                        if not failed.has_key(_uuid):
                            failed[_uuid] = {}
                        failed[_uuid][_ip] = [_info['stderr']]

        if result['failed']:
            for _uuid, _info in result['failed'].iteritems():
                _ip = _info['ansible_host']
                if _info.has_key('stderr') and _info['stderr']:
                    try:
                        failed[_uuid][_ip].append(_info['stderr'])
                    except:
                        if not failed.has_key(_uuid):
                            failed[_uuid] = {}
                        failed[_uuid][_ip] = [_info['stderr']]
                if _info.has_key('stdout') and _info['stdout']:
                    try:
                        failed[_uuid][_ip].append(_info['stdout'])
                    except:
                        if not failed.has_key(_uuid):
                            failed[_uuid] = {}
                        failed[_uuid][_ip] = [_info['stdout']]
                if _info.has_key('msg') and \
                        _info['msg'] and \
                        "'full_data_dir' is undefined" not in _info['msg'] and \
                        not re.search(r'Could not find.*firewalld', _info['msg']):
                    if _uuid in offline_list and re.search(r'the.*port.*is not up', _info['msg']):
                        continue
                    try:
                        failed[_uuid][_ip].append(_info['msg'])
                    except:
                        if not failed.has_key(_uuid):
                            failed[_uuid] = {}
                        failed[_uuid][_ip] = [_info['msg']]

        if result['unreachable']:
            for _uuid, _info in result['unreachable'].iteritems():
                _ip = _info['ansible_host']
                if _info.has_key('stderr') and _info['stderr']:
                    try:
                        unreachable[_uuid][_ip].append(_info['stderr'])
                    except:
                        if not unreachable.has_key(_uuid):
                            unreachable[_uuid] = {}
                        unreachable[_uuid][_ip] = [_info['stderr']]
                if _info.has_key('stdout') and _info['stdout']:
                    try:
                        unreachable[_uuid][_ip].append(_info['stdout'])
                    except:
                        if not unreachable.has_key(_uuid):
                            unreachable[_uuid] = {}
                        unreachable[_uuid][_ip] = [_info['stdout']]
                if _info.has_key('msg') and _info['msg']:
                    try:
                        unreachable[_uuid][_ip].append(_info['msg'])
                    except:
                        if not unreachable.has_key(_uuid):
                            unreachable[_uuid] = {}
                        unreachable[_uuid][_ip] = [_info['msg']]

        if not failed and not unreachable:
            return result

        msg = {}
        msg['failed'] = failed
        msg['unreachable'] = unreachable
        raise exceptions.TiOPSRuntimeError(msg, result, tp='ansible')

    def run_playbook(self, playbook_path, extra_vars=None):
        """
        运行playbook
        """
        try:
            self.callback = PlayBookResultsCollector()
            if extra_vars:
                self.variable_manager.extra_vars = extra_vars
            executor = PlaybookExecutor(
                playbooks=[playbook_path],
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.password,
            )
            executor._tqm._stdout_callback = self.callback
            executor.run()
        except Exception as e:
            term.warn(str(e))
            return False

    def __ansible_host(self, hostname=None):
        _ansible_host = self.variable_manager.get_vars(host=hostname)[
            'ansible_host'] if 'ansible_host' in self.variable_manager.get_vars(host=hostname) else \
            self.variable_manager.get_vars(host=hostname)['inventory_hostname']
        return _ansible_host

    def get_model_result(self):
        self.results_raw = {
            'success': {},
            'failed': {},
            'unreachable': {}
        }
        for host, result in self.callback.host_ok.items():
            self.results_raw['success'][host] = result._result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['success'][host]['ansible_host'] = self.__ansible_host(hostname)

        for host, result in self.callback.host_failed.items():
            self.results_raw['failed'][host] = result._result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['failed'][host]['ansible_host'] = self.__ansible_host(hostname)

        for host, result in self.callback.host_unreachable.items():
            self.results_raw['unreachable'][host] = result._result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['unreachable'][host]['ansible_host'] = self.__ansible_host(hostname)

        return self.results_raw

    def get_playbook_result(self):
        self.results_raw = {
            'skipped': {},
            'failed': {},
            'ok': {},
            "status": {},
            'unreachable': {},
            "changed": {}
        }
        for host, result in self.callback.task_ok.items():
            self.results_raw['ok'][host] = result._result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['ok'][host]['ansible_host'] = self.__ansible_host(hostname)

        for host, result in self.callback.task_failed.items():
            self.results_raw['failed'][host] = result._result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['failed'][host]['ansible_host'] = self.__ansible_host(hostname)

        for host, result in self.callback.task_status.items():
            self.results_raw['status'][host] = result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['status'][host]['ansible_host'] = self.__ansible_host(hostname)

        for host, result in self.callback.task_skipped.items():
            self.results_raw['skipped'][host] = result._result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['skipped'][host]['ansible_host'] = self.__ansible_host(hostname)

        for host, result in self.callback.task_unreachable.items():
            self.results_raw['unreachable'][host] = result._result
            hostname = self.inventory.get_host(hostname=str(host))
            self.results_raw['unreachable'][host]['ansible_host'] = self.__ansible_host(hostname)
        return self.results_raw
Exemple #17
0
class MyInventory:
    def __init__(self, resource, loader, variable_manager):
        self.resource = resource
        self.loader = DataLoader()
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=[host_list_file])
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        self.dynamic_inventory()

    def add_dynamic_group(self, hosts, group_name, group_vars=None):
        self.inventory.add_group(group_name)
        my_group = Group(name=group_name)

        if group_vars is not None:
            for k, v in group_vars.items():
                my_group.set_variable(k, v)

        for host in hosts:
            hostname = host.get("hostname")
            hostip = host.get("ip", hostname)
            hostport = host.get("port", 22)
            username = host.get("username")
            password = host.get("password")
            ssh_key = host.get("ssh_key", "~/.ssh/id_rsa")
            my_host = Host(name=hostname, port=hostport)

            self.variable_manager.set_host_variable(host=my_host,
                                                    varname="ansible_ssh_host",
                                                    value=hostip)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_pass',
                                                    value=password)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_port',
                                                    value=hostport)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_user',
                                                    value=username)
            self.variable_manager.set_host_variable(
                host=my_host,
                varname='ansible_ssh_private_key_file',
                value=ssh_key)

            for key, value in host.items():
                if key not in ["hostname", "port", "username", "password"]:
                    self.variable_manager.set_host_variable(host=my_host,
                                                            varname=key,
                                                            value=value)

            self.inventory.add_host(host=hostname,
                                    group=group_name,
                                    port=hostport)

    def dynamic_inventory(self):
        if isinstance(self.resource, list):
            self.add_dynamic_group(self.resource, "default_group")
        elif isinstance(self.resource, dict):
            for groupname, hosts_and_vars in self.resource.items():
                self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname,
                                       hosts_and_vars.get("vars"))
Exemple #18
0
class AnsibleApi(object):
    def __init__(self, inventory_file, host_list, groupname):
        self.options = {
            'verbosity': 0,
            'ask_pass': False,
            'private_key_file': None,
            'remote_user': None,
            'connection': 'smart',
            'timeout': 10,
            'ssh_common_args': '',
            'sftp_extra_args': '',
            'scp_extra_args': '',
            'ssh_extra_args': '',
            'force_handlers': False,
            'flush_cache': None,
            'become': False,
            'become_method': 'sudo',
            'become_user': None,
            'become_ask_pass': False,
            'tags': ['all'],
            'skip_tags': [],
            'check': False,
            'syntax': None,
            'diff': False,
            'inventory': inventory_file,
            'listhosts': None,
            'subset': None,
            'extra_vars': [],
            'ask_vault_pass': False,
            'vault_password_files': [],
            'vault_ids': [],
            'forks': 5,
            'module_path': None,
            'listtasks': None,
            'listtags': None,
            'step': None,
            'start_at_task': None,
            'args': ['fake']
        }

        self.ops = Values(self.options)
        self.loader = DataLoader()
        self.passwords = dict()
        self.results_callback = ResultCallback()
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=[self.options['inventory']])
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        self.result_playbook = PlayBookResultsCollector()
        self.results_raw = {}
        self.groupname = groupname
        self.host_list = host_list
        self.add_dynamic_group(self.host_list, self.groupname)

    def add_dynamic_group(self, hosts, groupname):
        self.inventory.add_group(groupname)
        # {
        #    ip1: {key: value},
        #    ip2: {key: value},
        # }
        for host in hosts:
            self.inventory.add_host(host, group=groupname)
            my_host = self.inventory.get_host(host)
            print('add {}'.format(host))

            for var in hosts[host]:
                self.variable_manager.set_host_variable(host=my_host,
                                                        varname=var,
                                                        value=hosts[host][var])
        print('print inventory')
        print(self.inventory.get_groups_dict())

    def ansible_run(self, host_list, task_list):
        context._init_global_context(self.ops)
        play_source = dict(name="Ansible Play",
                           hosts=host_list,
                           gather_facts='no',
                           tasks=task_list)
        play = Play().load(play_source,
                           variable_manager=self.variable_manager,
                           loader=self.loader)

        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                # options=self.ops,
                passwords=self.passwords,
                stdout_callback=self.results_callback,
                run_additional_callbacks=C.DEFAULT_LOAD_CALLBACK_PLUGINS,
                run_tree=False,
            )
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()
                # shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)

        results_raw = {}
        results_raw['success'] = {}
        results_raw['failed'] = {}
        results_raw['unreachable'] = {}

        for host, result in self.results_callback.host_ok.items():
            results_raw['success'][host] = json.dumps(result._result)

        for host, result in self.results_callback.host_failed.items():
            results_raw['failed'][host] = result._result['msg']

        for host, result in self.results_callback.host_unreachable.items():
            results_raw['unreachable'][host] = result._result['msg']

        return results_raw

    def playbook_run(self, playbook_path):

        # self.variable_manager.extra_vars = {'customer': 'test', 'disabled': 'yes'}
        context._init_global_context(self.ops)

        playbook = PlaybookExecutor(playbooks=playbook_path,
                                    inventory=self.inventory,
                                    variable_manager=self.variable_manager,
                                    loader=self.loader,
                                    passwords=self.passwords)

        playbook._tqm._stdout_callback = self.result_playbook
        C.HOST_KEY_CHECKING = False
        playbook.run()
        self.results_raw = {
            'skipped': {},
            'failed': {},
            'ok': {},
            "status": {},
            'unreachable': {},
            "changed": {}
        }
        for host, result in self.result_playbook.task_ok.items():
            self.results_raw['ok'][host] = json.dumps(result._result)

        for host, result in self.result_playbook.task_failed.items():
            self.results_raw['failed'][host] = result._result['msg']

        for host, result in self.result_playbook.task_status.items():
            self.results_raw['status'][host] = result

        for host, result in self.result_playbook.task_skipped.items():
            self.results_raw['skipped'][host] = result._result['msg']

        for host, result in self.result_playbook.task_unreachable.items():
            self.results_raw['unreachable'][host] = result._result['msg']

        return self.results_raw
Exemple #19
0
class MyInventory():
    """
    this is IOPS ansible inventory object.
    """

    # myinvent = MyInventory(self.resource, self.loader, self.variable_manager)
    def __init__(self, resource, loader, variable_manager):
        self.resource = resource
        self.loader = DataLoader()
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=['%s/conf/hosts' % BASE_DIR])
        # self.variable_manager.set_inventory(self.inventory)
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        # 自动执行dynamic_inventory
        self.dynamic_inventory()

    def add_dynamic_group(self, hosts, groupname, groupvars=None):
        """
            add hosts to a group
        """

        self.inventory.add_group(groupname)
        my_group = Group(name=groupname)

        # if group variables exists, add them to group if dict
        # groupvars={'var1': 'ansible', 'var2': 'saltstack'}
        if groupvars:
            for key, value in groupvars.iteritems():
                my_group.set_variable(key, value)


# if list hosts=resource [{"hostname": "192.168.1.111"}], if dict host=[{'username': u'root', 'ip': '192.168.1.11',}]
# add hosts to group,all hosts is list
        for host in hosts:
            # set connection variables
            hostname = host.get("hostname")
            # 拿IP  没有IP就用hostname代替,没有IP一般是新增的
            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)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_host',
                                                    value=hostip)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_pass',
                                                    value=password)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_port',
                                                    value=hostport)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_user',
                                                    value=username)
            self.variable_manager.set_host_variable(
                host=my_host,
                varname='ansible_ssh_private_key_file',
                value=ssh_key)
            # 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.iteritems():
                if key not in ["hostname", "port", "username", "password"]:
                    self.variable_manager.set_host_variable(host=my_host,
                                                            varname=key,
                                                            value=value)

            # add to group

            self.inventory.add_host(host=hostname,
                                    group=groupname,
                                    port=hostport)
            ghost = Host(name="192.168.8.119")

    def dynamic_inventory(self):
        """
            add hosts to inventory.
        """
        if isinstance(self.resource, list):
            self.add_dynamic_group(self.resource, 'default_group')
        elif isinstance(self.resource, dict):
            for groupname, hosts_and_vars in self.resource.iteritems():
                self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname,
                                       hosts_and_vars.get("vars"))
Exemple #20
0
class MyInventory():
    '''
    resource = [{'hostid': '1231', 'hostname': 'h1', 'hostip': '1.1.1.1'},
                {'hostid': '2345', 'hostname': 'h2', 'hostip': '2.2.2.2'},
                ]
    resource = {'groupname1': {
        'hosts': [
            {'hostid': '1231', 'hostname': 'h1', 'hostip': '1.1.1.1'},
            {'hostid': '2231', 'hostname': 'h2', 'hostip': '1.1.1.2'},
                 ],
        'groupvars': {"k1":"v1"}
                              },
                'groupname2': {'hosts': [], 'groupvars': {}},
                              }
    '''

    # edit ori code  ansible/inventory/manage.pay line215  try if C.InventoryManager_PARSE_NOSOURCE:pass
    constants.InventoryManager_PARSE_NOSOURCE = True

    def __init__(self, resource):
        self.resource = resource
        self.loader = DataLoader()
        # self.inventory=InventoryManager(loader=self.loader,sources=['/etc/ansible/hosts'])
        self.inventory = InventoryManager(loader=self.loader)
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        self._parse(self.resource)

    def _parse(self, resource):
        if isinstance(resource, list):
            self._addGroupHosts(self.resource)
        elif isinstance(resource, dict):
            # logging.info('parsing resuorce: %s'%(self.resource))
            for groupname, hosts_and_groupvars in self.resource.items():
                print("[1] groupname: %s |hostsandvars: %s" %
                      (groupname, hosts_and_groupvars))  # debug [1]
                self._addGroupHosts(hosts_and_groupvars.get('hosts'),
                                    groupname,
                                    hosts_and_groupvars.get('groupvars'))

        else:
            logging.error('resource error ,need dict or list')

    def _addGroupHosts(self, hosts, groupname='default', groupvars=None):
        self.inventory.add_group(group=groupname)
        group = Group(groupname)
        if groupvars:
            for k, v in groupvars.items():
                group.set_variable(k, v)

        # hosts=[{'hostid':'123','hostname':'h1','hostip':'192.168.188.20'}
        for host in hosts:
            hostid = host.get('hostid')
            hostname = host.get('hostname')
            hostip = host.get('hostip')
            username = host.get('username')
            password = host.get('password')
            port = host.get('port', 22)
            sshkey = host.get('sshkey')
            if hostname:
                self.inventory.add_host(
                    host=hostname, group=groupname
                )  # by default, indentify by hostname and need
                hostobj = self.inventory.get_host(
                    hostname=hostname)  # add host= , get hostname=

                self.variable_manager.set_host_variable(
                    host=hostobj, varname='ansible_ssh_host', value=hostip)
                self.variable_manager.set_host_variable(
                    host=hostobj, varname='ansible_ssh_port', value=port)
                self.variable_manager.set_host_variable(
                    host=hostobj, varname='ansible_ssh_user', value=username)
                self.variable_manager.set_host_variable(
                    host=hostobj, varname='ansible_ssh_pass', value=password)
                self.variable_manager.set_host_variable(
                    host=hostobj,
                    varname='ansible_ssh_private_key_file',
                    value=sshkey)

                # TODO: other vars such as become-method-user-pass
                #hostobj.set_variable('ansible_ssh_port',port)
                for k, v in host.items():
                    if k not in [
                            'hostip', 'port', 'username', 'password', 'sshkey'
                    ]:
                        hostobj.set_variable(k, v)
            else:
                logging.warning('resource error:cant get hostname from | %s' %
                                resource)

    def testcase(self):
        print(self.inventory.get_groups_dict())
        host = self.inventory.get_host(hostname='h1')
        print(self.variable_manager.get_vars(host=host))
Exemple #21
0
class MyInventory:
    """
    Dynamic Creates and manages inventory
    By default, there are six group names
    """
    def __init__(self, resources):
        self.resource = resources
        self.loader = DataLoader()
        self.inventory = InventoryManager(
            loader=self.loader,
            sources=['%s/conf/inventorys' % settings.BASE_DIR])
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        self.dynamic_inventory()

    def add_dynamic_group(self, hosts, groupname, groupvars=None):
        """
            add hosts to a group
        """
        self.inventory.add_group(groupname)
        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", None)
            hostip = host.get('ip', None)
            if hostip is None:
                print("IP地址为空,跳过该元素。")
                continue
            hostport = host.get("port", 22)
            user = host.get("user", 'root')
            password = host.get("password", None)
            ssh_key = host.get("ssh_key", None)
            if hostname is None:
                hostname = hostip
            my_host = Host(name=hostname, port=hostport)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_port',
                                                    value=hostport)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_host',
                                                    value=hostip)
            self.variable_manager.set_host_variable(host=my_host,
                                                    varname='ansible_ssh_user',
                                                    value=user)
            if password:
                self.variable_manager.set_host_variable(
                    host=my_host, varname='ansible_ssh_pass', value=password)
            if ssh_key:
                self.variable_manager.set_host_variable(
                    host=my_host,
                    varname='ansible_ssh_private_key_file',
                    value=ssh_key)
            # set other variables
            for key, value in host.items():
                if key not in ["hostname", "port", "user", "password"]:
                    self.variable_manager.set_host_variable(host=my_host,
                                                            varname=key,
                                                            value=value)

            # add to group
            self.inventory.add_host(host=hostname,
                                    group=groupname,
                                    port=hostport)

    def dynamic_inventory(self):
        """
            add hosts to inventory.
        """
        if isinstance(self.resource, list):
            self.add_dynamic_group(self.resource, 'default_group')
        elif isinstance(self.resource, dict):
            for groupname, hosts_and_vars in self.resource.items():
                self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname,
                                       hosts_and_vars.get("vars"))
        elif isinstance(self.resource, str):
            return

    @property
    def INVENTORY(self):
        """
        返回资产实例
        :return:
        """
        return self.inventory

    @property
    def VARIABLE_MANAGER(self):
        """
        返回变量管理器实例
        :return:
        """
        return self.variable_manager
Exemple #22
0
        ],
        "ungrouped":[

        ],
        "test_group1":[
            "192.168.1.80",
            "192.168.1.76",
            "192.168.1.77",
            "192.168.1.1"
        ]
    },
    "omit":"__omit_place_holder__3909aaf2b72b39148f1cf8db39bfdb4745bec16d",
    "ansible_version":"Unknown"
}
"""
variable_manager.set_host_variable(host=host, varname='ansible_ssh_pass', value='dsfnbhjkdasnfjkdsaf')
print(variable_manager.get_vars(host=host))

# variable_manager.extra_vars


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', 'diff'])

# 方法1
# ops = Values(Options)
# context._init_global_context(ops)
Exemple #23
0
class AnsibleApi(object):
    def __init__(self, hostinfo, taskinfo=None):
        self.resultinfo = []
        self.taskinfo = taskinfo
        self.hostinfo = hostinfo
        self.host_list = [i.get("host", None) for i in self.hostinfo]
        self.sources = ",".join(self.host_list)
        if len(self.host_list) == 1:
            self.sources += ","
        self.passwords = dict()
        self.callback = None
        self.__initializeData()

    def __initializeData(self):
        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"
        ])
        self.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="sudo",
            become_user=None,
            verbosity=None,
            check=False,
            diff=False,
        )
        self.loader = DataLoader()

        # 设置本次调用的host_list
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=self.sources)
        # 加载之前的变量
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)

        self.__set_hostinfo()

    def __set_hostinfo(self):
        # 设置调用主机认证信息
        for host in self.hostinfo:
            self.inventory.add_host(host.get("host"), port=host.get("port"))
            hostname = self.inventory.get_host(hostname=host.get("host"))
            self.variable_manager.set_host_variable(host=hostname,
                                                    varname='ansible_ssh_pass',
                                                    value=host.get('password'))
            self.variable_manager.set_host_variable(host=hostname,
                                                    varname='ansible_ssh_user',
                                                    value=host.get('user'))
            self.variable_manager.set_host_variable(host=hostname,
                                                    varname='ansible_ssh_port',
                                                    value=host.get('port'))
            if host.get("sudo_pass"):
                self.variable_manager.set_host_variable(
                    host=hostname,
                    varname="ansible_become_user",
                    value=host.get("sudo_user"))
                self.variable_manager.set_host_variable(
                    host=hostname,
                    varname="ansible_become_pass",
                    value=host.get("sudo_pass"))
                self.variable_manager.set_host_variable(
                    host=hostname, varname="ansible_become", value=True)
            if not host.get('password') or host.get('password') == "None":
                self.variable_manager.set_host_variable(
                    host=hostname,
                    varname="ansible_ssh_private_key_file",
                    value=host.get("ansible_ssh_private_key_file"))

    def run_model(self):
        for task in self.taskinfo:
            play_source = dict(name="andible_api_play",
                               hosts=self.host_list,
                               gather_facts="no",
                               tasks=[
                                   dict(action=dict(module=task.get("module"),
                                                    args=task.get("args")))
                               ])
            play = Play().load(play_source,
                               variable_manager=self.variable_manager,
                               loader=self.loader)
            tqm = None
            self.callback = ModelResultsCollector()
            try:
                tqm = TaskQueueManager(
                    inventory=self.inventory,
                    variable_manager=self.variable_manager,
                    loader=self.loader,
                    options=self.options,
                    passwords=self.passwords,
                    stdout_callback="minimal",
                )
                tqm._stdout_callback = self.callback
                result = tqm.run(play)
            except Exception as err:
                import traceback
                print(traceback.print_exc())
            finally:
                if tqm is not None:
                    tqm.cleanup()

    @property
    def get_model_result(self):
        for host, result in self.callback.host_ok.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": 0
                }})
        for host, result in self.callback.host_unreachable.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": -1
                }})
        for host, result in self.callback.host_failed.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": 1
                }})
        return self.resultinfo

    def run_playbook(self, PlayBookPath):
        try:
            self.callback = PlayBookResultsCollector()
            pbex = PlaybookExecutor(playbooks=[PlayBookPath],
                                    inventory=self.inventory,
                                    variable_manager=self.variable_manager,
                                    loader=self.loader,
                                    option=self.options,
                                    passwords=self.passwords)
            pbex._tqm._stdout_callback = self.callback
            pbex.run()
        except Exception as err:
            import traceback
            print(traceback.print_exc())
            return False

    def get_playbook_result(self):
        for host, result in self.callback.host_ok.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": 0
                }})
        for host, result in self.callback.host_unreachable.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": -1
                }})
        for host, result in self.callback.host_failed.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": 1
                }})
        for host, result in self.callback.task_status.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": 2
                }})

        for host, result in self.callback.task_skipped.items():
            self.resultinfo.append(
                {host: {
                    "message": result._result,
                    "code": 3
                }})
        return self.resultinfo
Exemple #24
0
def run_ansible(module_name, module_args, host_list, ansible_user="******"):
    """ansible api"""
    # 负责查找和读取yaml、json和ini文件
    loader = DataLoader()

    # 初始化需要的对象
    Options = namedtuple('Options', [
        'connection', 'module_path', 'forks', 'become', 'become_method',
        'private_key_file', 'become_user', 'remote_user', 'check', 'diff'
    ])
    options = Options(connection='ssh',
                      module_path=None,
                      forks=5,
                      become=True,
                      become_method='sudo',
                      private_key_file="/root/.ssh/id_rsa",
                      become_user='******',
                      remote_user=ansible_user,
                      check=False,
                      diff=False)

    passwords = dict(vault_pass='******')

    # 实例化ResultCallback来处理结果
    callback = ResultsCollector()

    # 创建库存(inventory)并传递给VariableManager
    inventory = InventoryManager(loader=loader, sources='')

    for ip in host_list:
        inventory.add_host(host=ip, port=22)

    # 管理变量的类,包括主机,组,扩展等变量
    variable_manager = VariableManager(loader=loader, inventory=inventory)

    for ip in host_list:
        host = inventory.get_host(hostname=ip)
        variable_manager.set_host_variable(host=host,
                                           varname='ansible_ssh_pass',
                                           value='lzx@2019')

    # 创建任务
    host = ",".join(host_list)

    play_source = dict(name="Ansible Play",
                       hosts=host,
                       gather_facts='no',
                       tasks=[
                           dict(action=dict(module=module_name,
                                            args=module_args),
                                register='shell_out'),
                       ])

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

    # 开始执行
    tqm = None

    tqm = TaskQueueManager(
        inventory=inventory,
        variable_manager=variable_manager,
        loader=loader,
        options=options,
        passwords=passwords,
        stdout_callback=callback,
    )
    result = tqm.run(play)

    result_raw = {'success': {}, 'failed': {}, 'unreachable': {}}

    for host, result in callback.host_ok.items():
        result_raw['success'][host] = result._result

    for host, result in callback.host_failed.items():
        result_raw['failed'][host] = result._result

    for host, result in callback.host_unreachable.items():
        result_raw['unreachable'][host] = result._result

    for host, result in callback.host_skipped.items():
        result_raw['skipped'][host] = result._result

    return json.dumps(result_raw, indent=4, ensure_ascii=False)
VariableManager

实例化需要两个参数:
    1. 参数一为读取yml文件的信息,需要实例化DataLoader。
    2. 参数二为资产管理配置变量。
"""
loader = DataLoader()
inventory = InventoryManager(loader='', sources=ansible_host_sources)
variable = VariableManager(loader=loader, inventory=inventory)

# 获取变量
print(variable.get_vars())

host = inventory.get_host(hostname='django2.example.com')
host_vars = variable.get_vars(host=host)
print(host_vars)
print('- ' * 80)

# 设置主机变量方法,传入的host是inventory.get_host获得的主机对象
host = inventory.get_host(hostname='django2.example.com')
variable.set_host_variable(host=host,
                           varname='ansible_ssh_pass',
                           value='12345')
host_vars = variable.get_vars(host=host)
print(host_vars)

variable.set_host_variable(host=host,
                           varname='ansible_ssh_pass',
                           value='12345_again')
host_vars = variable.get_vars(host=host)
print(host_vars)
Exemple #26
0
class Api(object):
    def __init__(self):
        # disable check the host key at ansible running
        C.HOST_KEY_CHECKING = False
        self._callback = None
        self._loader = DataLoader()
        self._inventory = InventoryManager(loader=self._loader, sources=",")
        self._variable_manager = VariableManager(loader=self._loader,
                                                 inventory=self._inventory)
        self._tasks = []

    def _parse_host(self, hosts):
        for host in hosts:
            hostname = host.get("hostname", None)
            if hostname is None:
                raise ValueError("error: not found hostname")
            port = host.get("port", 22)
            variables = host.get("vars", {})
            self._add_host(hostname, port, variables)

    def _add_host(self, hostname, port, variables):
        self._inventory.add_host(host=hostname, port=port)
        host = self._inventory.get_host(hostname)
        for varname, value in variables.items():
            self._set_variable(host, varname, value)

    def _set_variable(self, host, varname, value):
        self._variable_manager.set_host_variable(host, varname, value)

    def json(self):
        self._callback = JsonCallBack()
        return self

    def module(self, module, task_name=None, args=None, **kwargs):
        '''
		Args:
			module: string, ansible模板名称
			task_name: string, 此任务的名称,如果为None, 则使用模块名称
			args: string, dict, 模块的参数
			kwargs: dict, 任务的其它参数
		Return:
			Api对象实例
		'''
        if args is not None:
            if isinstance(args, str) or isinstance(args, dict):
                self._tasks.append(
                    dict(action=dict(module=module, args=args),
                         name=task_name,
                         **kwargs))
            else:
                raise ValueError("args type is error")
        else:
            self._tasks.append(
                dict(action=dict(module=module), name=task_name, **kwargs))
        return self

    def run(self,
            hosts,
            play_name="Ansible Play",
            gather_facts="no",
            callback=None,
            **kwargs):
        '''
		Args:
			hosts: list, example:
				[
					{
						"hostname": "127.0.0.1",
						"port": 22,
						"vars": {
							"asisble_ssh_pass": "******"
						}
					}
				]
			play_name: string, ansible play name
			gather_facts: string, no/yes; 是否在运行任务前使用steup模块收集主机信息
			callback: object, Ansible CallbackBase实现 
			kwargs: dict, 选项参数
		'''
        Options = namedtuple("Options", [
            "connection", "module_path", "forks", "become", "become_method",
            "become_user", "check", "diff"
        ])
        options = Options(connection=kwargs.get("connection", "smart"),
                          module_path=kwargs.get("module_path", []),
                          forks=kwargs.get("forks", 10),
                          become=kwargs.get("become", None),
                          become_method=kwargs.get("become_method", None),
                          become_user=kwargs.get("become_method", None),
                          check=kwargs.get("check", False),
                          diff=kwargs.get("diff", False))
        if self._callback is None:
            self._callback = callback

        self._parse_host(hosts)

        play_source = dict(name=play_name,
                           hosts=[host["hostname"] for host in hosts],
                           gather_facts=gather_facts,
                           tasks=self._tasks)

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

        tqm = None
        try:
            tqm = TaskQueueManager(inventory=self._inventory,
                                   variable_manager=self._variable_manager,
                                   loader=self._loader,
                                   options=options,
                                   passwords=dict(),
                                   stdout_callback=self._callback)
            tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()
            shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
        results = getattr(self._callback, "results", None)
        return results