def playbookrun(self, playbook_path): playbook_inventory = InventoryManager(loader=self.loader, sources=['playbook_hosts']) playbook_variable = VariableManager(loader=self.loader, inventory=playbook_inventory) playbook_inventory.add_host(host="192.168.122.102", port=22, group='all') playbook_inventory.add_group('test_group') playbook_inventory.add_host(host="192.168.122.103", port=22, group="test_group") print(playbook_inventory.get_groups_dict()) host = playbook_inventory.get_host(hostname="192.168.122.102") host.set_variable("ansible_ssh_pass", "/*bankentan123") host.set_variable("ansible_ssh_user", "root") host.set_variable("ansible_ssh_port", "22") host.set_variable("ansible_ssh_host", "192.168.122.102") host.set_variable("myname", "bankentan") vars = playbook_variable.get_vars(host=host) print(vars) context._init_global_context(self.ops) playbook = PlaybookExecutor(playbooks=playbook_path, inventory=playbook_inventory, variable_manager=self.variable_manager, loader=self.loader, passwords=self.passwords) result = playbook.run() return result
class Playbook(object): loader = None inventory = None def __init__(self, group, key, callback): self.options = Options(connection='smart', module_path='', forks=100, become=None, become_method=None, become_user='******', check=False, private_key_file=key, diff=False) self.key = key self.make_inventory(group) self.stdout_callback = callback self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) self.play = [] def make_inventory(self, group): self.loader = DataLoader() self.inventory = InventoryManager(loader=DataLoader(), ) self.inventory.add_group(str(group.uuid)) for host in group.hosts.all(): self.inventory.add_host(host.connect_ip, str(group.uuid), host.sshport) def delete_key(self): import os if os.path.exists(self.key): os.remove(self.key) def import_vars(self, vars_dict): vars_dict['KEY'] = self.key self.variable_manager.extra_vars = vars_dict def import_task(self, play_source): for source in play_source: self.play.append(Play().load( source, variable_manager=self.variable_manager, loader=self.loader)) def run(self): tqm = None try: tqm = TaskQueueManager(inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=self.options, passwords={}, stdout_callback=self.stdout_callback) for p in self.play: result = tqm.run(p) self.delete_key() finally: if tqm is not None: tqm.cleanup()
class Common_inventory_vars(object): def __init__(self): self.dataloader = DataLoader() self.inventory_file = os.path.join(BASE_DIR, 'run_an/aninfo/hosts') self.inventory = InventoryManager(loader=self.dataloader, sources=[self.inventory_file]) self.varobj = VariableManager(loader=self.dataloader, inventory=self.inventory) self.hostip = None def check_host(self, chip): self.hostip = chip if self.inventory.get_host(self.hostip): return True else: return False def add_host(self, add_to_group): self.inventory.add_host(host=self.hostip, group=add_to_group) def check_group(self, groupname): inventory_file_all_groups = self.inventory.groups if groupname in inventory_file_all_groups: return True else: return False def add_group(self, add_groupname): self.inventory.add_group(add_groupname)
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
def ansible_playbook_api(tid, hosts, playbooks, sources, extra_vars={}): Options = namedtuple('Options', [ 'remote_user', 'connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff', 'listhosts', 'listtasks', 'listtags', 'syntax', ]) options = Options( remote_user=ansible_remote_user, connection='paramiko', module_path=['/to/mymodules'], forks=10, become=None, become_method=None, become_user=None, check=False, diff=False, listhosts=None, listtasks=None, listtags=None, syntax=None ) loader = DataLoader() passwords = dict(vault_pass='******') inventory = InventoryManager(loader=loader, sources=sources) # 創建默认的主机组 inventory.add_group("all") for host, port in hosts: print(host, port) inventory.add_host(host, group="all", port=port) variable_manager = VariableManager(loader=loader, inventory=inventory) variable_manager.extra_vars = extra_vars pb = MyPlaybookExecutor(tid=tid, playbooks=playbooks, inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) # pb = PlaybookExecutor( # playbooks=playbooks, # inventory=inventory, # variable_manager=variable_manager, # loader=loader, # options=options, # passwords=passwords) # raise ValueError("1123") result = pb.run()
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"))
def run(self, terms, variables=None, **kwargs): manager = InventoryManager(self._loader, parse=False) for group, hosts in variables['groups'].items(): manager.add_group(group) for host in hosts: manager.add_host(host, group=group) try: return [h.name for h in manager.get_hosts(pattern=terms)] except AnsibleError: return []
def runner(self, groups, command_arg): username = '******' private_key_file = 'ansible-poc.pem' results_callback = ResultCallback() context.CLIARGS = ImmutableDict(connection='smart', module_path=None, forks=10, become=True, check=None, sudo="yes", sudo_user="******", become_method='sudo', become_user='******', remote_user=username, verbosity=5, private_key_file=private_key_file) loader = DataLoader() inventory = InventoryManager(loader=loader, sources='localhost,') inventory.add_group('nginx') inventory.add_host(host='52.82.73.36', group='nginx') variable_manager = VariableManager(loader=loader, inventory=inventory) play_source = dict( name=groups, hosts=groups, gather_facts='no', tasks=[ dict(action=dict(module='shell', args=command_arg), register='shell_out'), dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}'))) ]) play = Play().load(play_source, variable_manager=variable_manager, loader=loader) tqm = None try: tqm = TaskQueueManager( inventory=inventory, variable_manager=variable_manager, loader=loader, passwords=dict(valute_pass='******'), stdout_callback=results_callback, ) result = tqm.run(play) finally: if tqm is not None: tqm.cleanup() shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
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
class MyInventory(InventoryManager): """ this is my ansible inventory object. """ def __init__(self, resource, loader, sources=None): self.resource = resource self.inventory = InventoryManager(loader=loader, sources=sources) self.gen_inventory() def my_add_group(self, hosts, groupname, groupvars=None): self.inventory.add_group(groupname) # if group variables exists, add them to group if groupvars: my_group = self.inventory.groups().get(groupname, None) if my_group is None: return 'my group is none' for key, value in groupvars.iteritems(): my_group.set_variable(key, value) # add hosts to group for host in hosts: # set connection variables if not host.has_key("hostname"): continue hostname = host.get("hostname") self.inventory.add_host(host=hostname, group=groupname) my_host = self.inventory.get_host(hostname) # set other variables for key, value in host.iteritems(): if key not in ["hostname"]: my_host.set_variable(key, value) def gen_inventory(self): """ add hosts to inventory. """ if self.resource is None: pass elif isinstance(self.resource, list): #self.my_add_group(self.resource, 'default_group') self.my_add_group(self.resource, 'all') elif isinstance(self.resource, dict): for groupname, hosts_and_vars in self.resource.iteritems(): self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
class MyInventory: def __init__(self, resource, source=None): self.resource = resource self.loader = DataLoader() self.inventory = InventoryManager(loader=self.loader, sources=source) self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) self.dynamic_resource() def add_group(self, hosts, group_name): # 添加组 self.inventory.add_group(group_name) for host in hosts: hostip = host.get('host') hostport = host.get("port") username = host.get("username") password = host.get("password") # 必须是已有的组 # print("添加组", hostip, group_name) self.inventory.add_host(hostip, group_name) # 添加到ansible主机变量,ansible自身调用 self.inventory.get_host(hostip).set_variable('ansible_ssh_ip', hostip) self.inventory.get_host(hostip).set_variable('ansible_ssh_port', hostport) self.inventory.get_host(hostip).set_variable('ansible_ssh_user', username) self.inventory.get_host(hostip).set_variable('ansible_ssh_pass', password) # 老版本 self.inventory.get_host(hostip).set_variable('ansible_ip', hostip) self.inventory.get_host(hostip).set_variable('ansible_port', hostport) self.inventory.get_host(hostip).set_variable('ansible_user', username) self.inventory.get_host(hostip).set_variable('ansible_pass', password) # 管理员密码 self.inventory.get_host(hostip).set_variable('ansible_sudo_pass', password) # add to group self.inventory.add_host(host=hostip, group=group_name, port=hostport) def dynamic_resource(self): if isinstance(self.resource, list): self.add_group(self.resource, "all") elif isinstance(self.resource, dict): self.resource = [self.resource] self.add_group(self.resource, "all")
class MyInventory(InventoryManager): """ this is my ansible inventory object. """ def __init__(self, resource, loader, sources=None): self.resource = resource self.inventory = InventoryManager(loader=loader, sources=sources) self.gen_inventory() def my_add_group(self, hosts, groupname, groupvars=None): self.inventory.add_group(groupname) if groupvars: my_group = self.inventory.groups().get(groupname, None) if my_group is None: return 'my group is none' for key, value in groupvars.items(): my_group.set_variable(key, value) for host in hosts: if 'ansible_host' not in host: continue hostname = host.get("ansible_host") self.inventory.add_host(host=hostname, group=groupname) my_host = self.inventory.get_host(hostname) for key, value in host.items(): if key not in ["ansible_host"]: my_host.set_variable(key, value) def gen_inventory(self): """ 添加主机到inventory """ if self.resource is None: pass elif isinstance(self.resource, list): self.my_add_group(self.resource, 'all') elif isinstance(self.resource, dict): for groupname, hosts_and_vars in self.resource.items(): self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
def _create_inventory(loader, host_list=None, groups=None): """ Returns an inventory object for playbook execution. Args: loader (ansible.parsing.dataloader.DataLoader): Ansible data loader for PlaybookExecutor host_list (list): list of IP addresses or resolvable host names for hosts that do not belong to a group groups (dict): dictionary of group name keys whose values contain a list of IP addresses or resolvable host names belonging to that group Returns: ansible.inventory.manager.InventoryManager for PlaybookExecutor """ if groups is None: groups = {} if host_list is None: host_list = [] inventory = InventoryManager(loader=loader) for host in host_list: inventory.add_host(host) for group_name, host_names in groups.iteritems(): inventory.add_group(group_name) # for some reason it's necessary to use Ansible's reference to this group, # not the reference returned from Group() group = inventory.groups[group_name] for host_name in host_names: inventory.add_host(host_name, group=group_name) host = inventory.get_host(host_name) host.add_group(group) group.add_host(host) inventory.reconcile_inventory() return inventory
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))
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
def run_playbook(playbook, host_list, vars): # https://github.com/celery/billiard/issues/189 # https://github.com/Mirantis/kostyor-openstack-ansible/commit/407ec033514600cd62f4931f199efd13405b0aae import multiprocessing import billiard multiprocessing.Process = billiard.Process 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' ]) loader = DataLoader() variable_manager = VariableManager(loader=loader) options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, 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=False, become_method='sudo', become_user='******', verbosity=None, check=False, diff=False) passwords = {} inventory = InventoryManager(loader=loader) inventory.add_group('ci') inventory.add_host(host_list.values()[0], 'ci') inventory.reconcile_inventory() variable_manager.set_inventory(inventory) variable_manager.extra_vars = vars playbook_path = playbook constants.HOST_KEY_CHECKING = False pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) results = pbex.run() pubkey = None try: pubkey = variable_manager._nonpersistent_fact_cache[ host_list['ci']]['pubkey']['stdout'] except KeyError: pass return results, pubkey
class NetworkTest(object): def __init__(self, playbook): self.loader = DataLoader() self.inventory = InventoryManager(loader=self.loader, sources=None) self.variable_manager = VariableManager(self.loader,self.inventory) self.playbook = playbook self.sender_group = 'sender' self.inventory.add_group(self.sender_group) self.receiver_group = 'receiver' self.inventory.add_group(self.receiver_group) self.master_group = 'master' self.inventory.add_group(self.master_group) def set_inventory_vars(self, inv_vars): self.variable_manager.extra_vars = inv_vars def add_sender(self, sender): sender_host = sender self.inventory.add_host(sender_host, self.sender_group) def add_receiver(self, receiver): receiver_host = receiver self.inventory.add_host(receiver_host, self.receiver_group) def add_master(self, master): master_host = master self.inventory.add_host(master_host, self.master_group) def run(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']) options = Options(listtags=False, listtasks=False, listhosts=False, syntax=False, connection='ssh', module_path=None, forks=100, 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) #OPTION_FLAGS = ('connection', 'remote_user', 'private_key_file', 'verbosity', 'force_handlers', 'step', 'start_at_task', 'diff', # 'ssh_common_args', 'docker_extra_args', 'sftp_extra_args', 'scp_extra_args', 'ssh_extra_args') passwords = {} pbex = PlaybookExecutor(playbooks=[self.playbook], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, options=options, passwords=passwords) result = pbex.run() return result
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
class MyAnsiable2(): def __init__( self, connection='local', # 连接方式 local 本地方式,smart ssh方式 remote_user=None, # 远程用户 ack_pass=None, # 提示输入密码 sudo=None, sudo_user=None, ask_sudo_pass=None, module_path=None, # 模块路径,可以指定一个自定义模块的路径 become=None, # 是否提权 become_method=None, # 提权方式 默认 sudo 可以是 su become_user=None, # 提权后,要成为的用户,并非登录用户 check=False, diff=False, listhosts=None, listtasks=None, listtags=None, verbosity=3, syntax=None, start_at_task=None, inventory=None, group_name='', host_ip='', varsdic=''): # 函数文档注释 """ 初始化函数,定义的默认的选项值, 在初始化的时候可以传参,以便覆盖默认选项的值 """ context.CLIARGS = ImmutableDict( connection=connection, remote_user=remote_user, ack_pass=ack_pass, sudo=sudo, sudo_user=sudo_user, ask_sudo_pass=ask_sudo_pass, module_path=module_path, become=become, become_method=become_method, become_user=become_user, verbosity=verbosity, listhosts=listhosts, listtasks=listtasks, listtags=listtags, syntax=syntax, start_at_task=start_at_task, group_name=group_name, host_ip=host_ip, varsdic=varsdic, ) # 三元表达式,假如没有传递 inventory, 就使用 "localhost," self.inventory = inventory if inventory else "localhost," # 实例化数据解析器 self.loader = DataLoader() # 实例化 资产配置对象 self.inv_obj = InventoryManager(loader=self.loader, sources=self.inventory) # 设置密码,可以为空字典,但必须有此参数 self.passwords = {} # 实例化回调插件对象 self.results_callback = ResultCallback() # 动态添加组 self.inv_obj.add_group(group_name) # 动态添加组内成员 self.inv_obj.add_host(host_ip, group_name) # 动态给组添加变量 group_obj = self.inv_obj.groups[group_name] if varsdic: shellkey, shellval = varsdic.item() group_obj.set_variable(shellkey, shellval) else: group_obj.set_variable("", "") # 变量管理器 self.variable_manager = VariableManager(self.loader, self.inv_obj) def run(self, hosts='localhost', gether_facts="no", module=' ', args=' '): play_source = dict( name="Ad-hoc", hosts=hosts, gather_facts=gether_facts, tasks=[ # 这里每个 task 就是这个列表中的一个元素,格式是嵌套的字典 # 也可以作为参数传递过来,这里就简单化了。 { "action": { "module": module, "args": args } }, ]) play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader) tqm = None try: tqm = TaskQueueManager(inventory=self.inv_obj, variable_manager=self.variable_manager, loader=self.loader, passwords=self.passwords, stdout_callback=self.results_callback) result = tqm.run(play) finally: if tqm is not None: tqm.cleanup() shutil.rmtree(C.DEFAULT_LOCAL_TMP, True) def playbook(self, playbooks): from ansible.executor.playbook_executor import PlaybookExecutor playbook = PlaybookExecutor( playbooks=playbooks, # 注意这里是一个列表 inventory=self.inv_obj, variable_manager=self.variable_manager, loader=self.loader, passwords=self.passwords) # 使用回调函数 playbook._tqm._stdout_callback = self.results_callback result = playbook.run() def get_result(self): result_raw = {'success': {}, 'failed': {}, 'unreachable': {}} # print(self.results_callback.host_ok) for host, result in self.results_callback.host_ok.items(): result_raw['success'][host] = result._result for host, result in self.results_callback.host_failed.items(): result_raw['failed'][host] = result._result for host, result in self.results_callback.host_unreachable.items(): result_raw['unreachable'][host] = result._result # 最终打印结果,并且使用 JSON 继续格式化 result_raw = json.dumps(result_raw) return result_raw
class AnsibleAPI: """ 初始化ansible的相关对象及参数 """ def __init__(self, check=False, remote_user="******", private_key_file=None, forks=cpu_count, inventory_source=None, extra_vars=None, dynamic_inventory=None): """ 可以选择性的针对业务场景在初始化中加入用户定义的参数 :param check: :param remote_user: :param private_key_file: :param forks: :param inventory_source: :param extra_vars: :param dynamic_inventory: """ # 运行前检查,即命令行的-C self.check = check # key登陆文件 self.private_key_file = private_key_file # 并发连接数 self.forks = forks # 远端登陆用户 self.remote_user = remote_user # 资产来源,可以是一个配置好的 inventory 文件,也可以是一个含有以 "," 为分割符的字符串 self.inventory_source = inventory_source # 数据解析器 self.loader = DataLoader() # 具体的资产对象,此对象可以用来操作group,host,variable self.inventory = InventoryManager(loader=self.loader, sources=self.inventory_source) # 必须有此参数,假如通过了公钥信任,可以为空dict self.passwords = {} # 回调结果 self.results_callback = CallbackModule() # 变量管理器 self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory) self.variable_manager._extra_vars = extra_vars if extra_vars is not None else {} # 自定义选项的初始化 self.__init_options() # 组和主机相关,处理动态资产 self._hosts = set() self.dynamic_inventory = dynamic_inventory if dynamic_inventory is not None and isinstance( dynamic_inventory, dict) else {} self.__init_dynamic_inventory() # 其他 def __init_options(self): """ 自定义选项,不用默认值的话可以加入到__init__的参数中 :return: """ # constants里面可以找到这些参数,ImmutableDict代替了较老的版本的nametuple的方式 context.CLIARGS = ImmutableDict( connection="smart", remote_user=self.remote_user, ack_pass=None, sudo=True, sudo_user="******", ask_sudo_pass=False, module_path=None, become=True, become_method="sudo", become_user="******", check=self.check, listhosts=None, listtasks=None, listtags=None, syntax=None, diff=True, subset=None, timeout=10, private_key_file=self.private_key_file, host_key_checking=False, forks=self.forks, ssh_common_args='-o StrictHostKeyChecking=no', ssh_extra_args='-o StrictHostKeyChecking=no', verbosity=0, start_at_task=None, ) def __init_dynamic_inventory(self): """ 处理动态inventory,可以通过前端表单等方式转化而来,最终动态inventory的格式如下: dynamic_inventory = { "test02": { "hosts": ["192.168.56.112"], "vars": {"gvar2": "gtest2"}, "children": ['test03'] }, "test03": { "hosts": ["192.168.56.113"], "vars": {"gvar3": "gtest3"} }, "_meta": { "hostvars": { "192.168.56.111": {"hvar1": "htest1"}, "192.168.56.112": {"hvar2": "htest2"} } } } 需要做如下处理: 组部分 1. inventoy添加组:self.inventory.add_group(group) 2. group添加host:self.inventory.add_host(hostname, group) 3. group添加组变量:self.inventory._inventory.set_variable(group, k, v) 4. inventory添加子组:self.inventory.add_group(child_name) 5. group添加子组:self.inventory._inventory.add_child(group, child_name) 主机部分 6. inventory添加host:self.inventory.add_host(host) 7. host添加主机变量:self.inventory._inventory.set_variable(host, k, got[k]) :return: """ # dynamic_inventory中的"_meta"获取的主机变量 data_from_meta = None # 提取主机变量并解析组信息 if len(dynamic_inventory) != 0: for group, gdata in dynamic_inventory.items(): if group == '_meta': if 'hostvars' in gdata: data_from_meta = gdata['hostvars'] else: self._parse_group(group, gdata) if len(self._hosts) != 0: for host in self._hosts: self.inventory.add_host(host) if data_from_meta is None: continue got = data_from_meta.get(host, {}) for k, v in got.items(): self.inventory._inventory.set_variable(host, k, v) # 解析组信息 def _parse_group(self, group, data): # 返回组名,同group = self.inventory._inventory.add_group(group),2.8相比老版本添加组相关的不好找,在_inventory里 group = self.inventory.add_group(group) # 感觉这段没啥用?不用这段逻辑应该没啥关系 if not isinstance(data, dict): data = {'hosts': data} # is not those subkeys, then simplified syntax, host with vars elif not any(k in data for k in ('hosts', 'vars', 'children')): data = {'hosts': [group], 'vars': data} if 'hosts' in data: if not isinstance(data['hosts'], list): raise AnsibleError( "You defined a group '%s' with bad data for the host list:\n %s" % (group, data)) for hostname in data['hosts']: self._hosts.add(hostname) self.inventory.add_host(hostname, group) if 'vars' in data: if not isinstance(data['vars'], dict): raise AnsibleError( "You defined a group '%s' with bad data for variables:\n %s" % (group, data)) for k, v in data['vars'].items(): # 重点1,给组设置变量 self.inventory._inventory.set_variable(group, k, v) if group != '_meta' and isinstance(data, dict) and 'children' in data: for child_name in data['children']: child_name = self.inventory.add_group(child_name) # 重点2,添加子组 self.inventory._inventory.add_child(group, child_name) def run_playbook(self, playbook_yml): playbook = PlaybookExecutor( playbooks=[playbook_yml], inventory=self.inventory, variable_manager=self.variable_manager, loader=self.loader, passwords=self.passwords, ) playbook._tqm._stdout_callback = self.results_callback playbook.run() # self.result_row = self.results_callback.result_row def run_module(self, module_name, module_args, hosts=None): play_source = dict(name="Ansible Run Module", hosts=hosts, gather_facts='no', tasks=[ { "action": { "module": module_name, "args": module_args } }, ]) 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, passwords=self.passwords, stdout_callback=self.results_callback, ) tqm.run(play) # self.result_row = self.results_callback.result_row finally: if tqm is not None: tqm.cleanup() # 这个临时目录会在 ~/.ansible/tmp/ 目录下 shutil.rmtree(C.DEFAULT_LOCAL_TMP, True) def get_result(self): result_raw = {'success': {}, 'failed': {}, 'unreachable': {}} # print(self.results_callback.host_ok) for host, result in self.results_callback.host_ok.items(): result_raw['success'][host] = result._result for host, result in self.results_callback.host_failed.items(): result_raw['failed'][host] = result._result for host, result in self.results_callback.host_unreachable.items(): result_raw['unreachable'][host] = result._result # 最终打印结果,并且使用 JSON 继续格式化 print(json.dumps(result_raw, indent=4))
class MyInventory: def __init__(self, hostsresource): """ 初始化函数 :param hostsresource: 主机资源可以有2种形式 列表形式: [{"ip": "172.16.48.171", "port": "22", "username": "******", "password": "******"}] 字典形式: { "Group1": { "hosts": [{"ip": "192.168.200.10", "port": "1314", "username": "******", "password": None}], "vars": {"var1": "ansible"} }, "Group2": {} } """ self._hostsresource = hostsresource self._loader = DataLoader() # self._hostsfilelist = ["temphosts"] """ sources这个我们知道这里是设置hosts文件的地方,它可以是一个列表里面包含多个文件路径且文件真实存在,在单纯的执行ad-hoc的时候这里的 文件里面必须具有有效的hosts配置,但是当通过动态生成的资产信息的时候这个文件必须存在但是它里面可以是空的,如果这里配置成None那么 它不影响资产信息动态生成但是会有一个警告,所以还是要配置一个真实文件。 """ self._inventory = InventoryManager(loader=self._loader, sources="localhost,") # self._variable_manager = VariableManager(loader=self._loader, inventory=self._inventory) self._dynamic_inventory() def _add_dynamic_group(self, hosts_list, groupname, groupvars=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="/PATH/python3/bin/python3" :param hosts_list: 主机列表 [{"ip": "192.168.100.10", "port": "22", "username": "******", "password": None}, {}] :param groupname: 组名称 :param groupvars: 组变量,格式为字典 :return: """ # 添加组 my_group = Group(name=groupname) self._inventory.add_group(groupname) # 添加组变量 if groupvars: for key, value in groupvars.items(): my_group.set_variable(key, value) # 添加一个主机 for host in hosts_list: hostname = host.get("hostname", None) hostip = host.get("ip", None) if hostip is None: print("IP地址为空,跳过该元素。") continue hostport = host.get("port", "22") username = host.get("username", "root") password = host.get("password", None) ssh_key = host.get("ssh_key", None) python_interpreter = host.get("python_interpreter", None) try: # hostname可以不写,如果为空默认就是IP地址 if hostname is None: hostname = hostip # 添加主机到组 self._inventory.add_host(host=hostname, group=groupname, port=hostport) inv_host = self._inventory.get_host(hostname) # 添加主机变量 inv_host.set_variable('ansible_ssh_host', hostip) inv_host.set_variable('ansible_ssh_port', hostport) inv_host.set_variable('ansible_ssh_user', username) if password: inv_host.set_variable('ansible_ssh_pass', password) if ssh_key: inv_host.set_variable('ansible_ssh_private_key_file', ssh_key) if python_interpreter: inv_host.set_variable('ansible_python_interpreter', python_interpreter) # 添加其他变量 for key, value in host.items(): if key not in [ "ip", "hostname", "port", "username", "password", "ssh_key", "python_interpreter" ]: inv_host.set_variable(key, value) except Exception as err: print(err) def _dynamic_inventory(self): """ 添加 hosts 到inventory :return: """ if isinstance(self._hostsresource, list): self._add_dynamic_group(self._hostsresource, "default_group") elif isinstance(self._hostsresource, dict): for groupname, hosts_and_vars in self._hostsresource.items(): self._add_dynamic_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars")) @property def INVENTORY(self): """ 返回资产实例 :return: """ return self._inventory
class MyAnsiable2: def __init__( self, connection="local", # 连接方式 local 本地方式,smart ssh方式 remote_user=None, # 远程用户 ack_pass=None, # 提示输入密码 sudo=None, sudo_user=None, ask_sudo_pass=None, module_path=None, # 模块路径,可以指定一个自定义模块的路径 become=None, # 是否提权 become_method=None, # 提权方式 默认 sudo 可以是 su become_user=None, # 提权后,要成为的用户,并非登录用户 check=False, diff=False, listhosts=None, listtasks=None, listtags=None, verbosity=3, syntax=None, start_at_task=None, inventory=None, ): # 函数文档注释 """ 初始化函数,定义的默认的选项值, 在初始化的时候可以传参,以便覆盖默认选项的值 """ context.CLIARGS = ImmutableDict( connection=connection, remote_user=remote_user, ack_pass=ack_pass, sudo=sudo, sudo_user=sudo_user, ask_sudo_pass=ask_sudo_pass, module_path=module_path, become=become, become_method=become_method, become_user=become_user, verbosity=verbosity, listhosts=listhosts, listtasks=listtasks, listtags=listtags, syntax=syntax, start_at_task=start_at_task, ) # 三元表达式,假如没有传递 inventory, 就使用 "localhost," self.inventory = inventory if inventory else "localhost," # 实例化数据解析器 self.loader = DataLoader() # 实例化 资产配置对象 self.inv_obj = InventoryManager(loader=self.loader, sources=self.inventory) # 添加组,主机 self.inv_obj.add_group("nginx") self.inv_obj.add_host('manger_id', 'nginx') # 添加组变量 group_obj = self.inv_obj.groups['nginx'] group_obj.set_variable('name', 'shark') # 设置密码,可以为空字典,但必须有此参数 self.passwords = {} # 实例化回调插件对象 self.results_callback = ResultCallback() # 变量管理器 self.variable_manager = VariableManager(self.loader, self.inv_obj) def run(self, hosts="localhost", gether_facts="no", module="ping", args=""): play_source = dict( name="Ad-hoc", hosts=hosts, gather_facts=gether_facts, tasks=[ # 这里每个 task 就是这个列表中的一个元素,格式是嵌套的字典 # 也可以作为参数传递过来,这里就简单化了。 { "action": { "module": module, "args": args } } ], ) play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader) tqm = None try: tqm = TaskQueueManager( inventory=self.inv_obj, variable_manager=self.variable_manager, loader=self.loader, passwords=self.passwords, stdout_callback=self.results_callback, ) result = tqm.run(play) finally: if tqm is not None: tqm.cleanup() shutil.rmtree(C.DEFAULT_LOCAL_TMP, True) def playbook(self, playbooks): from ansible.executor.playbook_executor import PlaybookExecutor playbook = PlaybookExecutor( playbooks=playbooks, # 注意这里是一个列表 inventory=self.inv_obj, variable_manager=self.variable_manager, loader=self.loader, passwords=self.passwords, ) # 使用回调函数 playbook._tqm._stdout_callback = self.results_callback result = playbook.run() def get_result(self): result_raw = {"success": {}, "failed": {}, "unreachable": {}} # print(self.results_callback.host_ok) for host, result in self.results_callback.host_ok.items(): result_raw["success"][host] = result._result for host, result in self.results_callback.host_failed.items(): result_raw["failed"][host] = result._result for host, result in self.results_callback.host_unreachable.items(): result_raw["unreachable"][host] = result._result print(result_raw) return json.dumps(result_raw, indent=4)
ansible_host_sources = ['/etc/ansible/hosts'] inventory = InventoryManager(loader='', sources=ansible_host_sources) # 以字典的方式打印出主机和主机组相关信息 # print(inventory.get_groups_dict()) # 获取所有的主机 # print(inventory.get_hosts()) """ 添加主机到指定主机组: 1. 参数一指定主机地址。 2. 参数二指定主机端口。 3. 参数三指定主机群组,必须存在的群组。 """ inventory.add_group('foreman') print(inventory.get_groups_dict()) print(inventory.get_hosts()) print('- ' * 80) inventory.add_host(host='foreman.example.com', port=22, group='foreman') print(inventory.get_groups_dict()) print(inventory.get_hosts(pattern='*')) print('- ' * 80, end='\n\n') """ VariableManager 实例化需要两个参数: 1. 参数一为读取yml文件的信息,需要实例化DataLoader。 2. 参数二为资产管理配置变量。 """
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 MyInventory: def __init__(self, hostsresource, sources=None): """ 初始化函数 :param hostsresource: 主机资源可以有2种形式 列表形式: [{"ip": "192.168.1.1", "port": "22", "username": "******", "password": "******"}] 字典形式: { "Group1": { "hosts": [{"ip": "192.168.1.1", "port": "22", "username": "******", "password": None}], "vars": {"var": "ansible"} } """ self._hostsresource = eval(hostsresource) print(self._hostsresource) print(type(self._hostsresource)) self._loader = DataLoader() self._hostsfilelist = ["hosts"] self._inventory = InventoryManager(loader=self._loader, sources=sources) self._variable_manager = VariableManager(loader=self._loader, inventory=self._inventory) self._dynamic_inventory() def _add_dynamic_group(self, hosts_list, groupname, groupvars=None, cluster=None): """ 动态添加主机到指定的主机组 :param hosts_list: 主机列表 [{"ip": "192.168.100.10", "port": "22", "username": "******", "password": None}, {}] :param groupname: 组名称 :param groupvars: 组变量,格式为字典 :param cluster: 先前集群信息,字典列表 :return: """ # 添加组 my_group = self._inventory.add_group(groupname) pre_group = self._inventory.add_group("pregroup") # 添加组变量 if groupvars: for key, value in groupvars.items(): self._inventory._inventory.set_variable(my_group, key, value) # my_group.set_variable(key, value) if cluster: # print(cluster) setcluster = sorted(cluster["clustervalue"]) # print(setcluster) self._inventory._inventory.set_variable(my_group, "pre_clusters", setcluster) # pre_group = self._inventory.add_group("pregroup") for i in setcluster: hostip = i.split(':')[0] self._inventory.add_host(hostip, "pregroup") username = i.split(':')[2] password = i.split(':')[3] sshport = i.split(':')[1] installpath = i.split(':')[-1] self._inventory._inventory.set_variable( hostip, "ansible_ssh_host", hostip) self._inventory._inventory.set_variable( hostip, "ansible_ssh_port", sshport) self._inventory._inventory.set_variable( hostip, "ansible_ssh_user", username) self._inventory._inventory.set_variable( hostip, "ansible_ssh_pass", password) self._inventory._inventory.set_variable( hostip, "inspath", installpath) if cluster["clustertype"] == "flink": jmip = i.split(':')[-2] self._inventory._inventory.set_variable( hostip, "jmip", jmip) allhosts = [] # 记录所有主机生成seed供安装集群时使用 # 添加一个主机 print(hosts_list) hosts_list = sorted(hosts_list, key=lambda i: i["ip"]) for host in hosts_list: hostname = host.get("hostname", None) hostip = host.get("ip", None) allhosts.append(hostip) if hostip is None: print("IP地址为空,跳过该元素。") continue hostport = host.get("port", "22") username = host.get("username", "root") password = host.get("password", None) ssh_key = host.get("ssh_key", None) python_interpreter = host.get("python_interpreter", None) try: # hostname可以不写,如果为空默认就是IP地址 if hostname is None: hostname = hostip # 添加主机到组 self._inventory.add_host(hostip, groupname) # 添加主机变量 self._inventory._inventory.set_variable( hostip, "ansible_ssh_host", hostip) self._inventory._inventory.set_variable( hostip, "hostname", hostname) self._inventory._inventory.set_variable( hostip, "ansible_ssh_port", hostport) self._inventory._inventory.set_variable( hostip, "ansible_ssh_user", username) if password: self._inventory._inventory.set_variable( hostip, "ansible_ssh_pass", password) if ssh_key: self._inventory._inventory.set_variable( hostip, "ansible_ssh_private_key_file", ssh_key) if python_interpreter: self._inventory._inventory.set_variable( hostip, "ansible_python_interpreter", python_interpreter) # 添加其他变量 for key, value in host.items(): if key not in [ "ip", "hostname", "port", "username", "password", "ssh_key", "python_interpreter" ]: self._inventory._inventory.set_variable( hostip, key, value) except Exception as err: print(err) allhosts = sorted(allhosts) self._inventory._inventory.set_variable(my_group, "seed_hosts", allhosts) self._inventory._inventory.set_variable(pre_group, "flink_hosts", allhosts) self._inventory._inventory.set_variable(my_group, "firstnode", allhosts[0]) if len(allhosts) > 1: self._inventory._inventory.set_variable(my_group, "secondnode", allhosts[1]) # if pre_group: self._inventory.add_host(allhosts[0], "pregroup") self._inventory._inventory.set_variable(pre_group, "excludenode", allhosts[0]) def _dynamic_inventory(self): """ 添加 hosts 到inventory :return: """ if isinstance(self._hostsresource, list): self._add_dynamic_group(self._hostsresource, "groups") elif isinstance(self._hostsresource, dict): print("dict") for groupname, hosts_and_vars in self._hostsresource.items(): if "cluster" in hosts_and_vars.keys(): self._add_dynamic_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"), hosts_and_vars.get("cluster")) else: self._add_dynamic_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"), cluster=None) @property def INVENTORY(self): """ 返回资产实例 :return: """ return self._inventory @property def VARIABLE_MANAGER(self): """ 返回变量管理器实例 :return: """ return self._variable_manager
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"))
class AnsibleRunner(object): """Run ansible playbook and retrieve results""" def __init__(self, hosts, playbook, verbosity='info', config={}, vars_filename='.variables', vault_password=""): required_defaults = ( 'forks', 'remote_user', 'private_key_file', 'become', 'become_method', 'become_user' ) for default in required_defaults: if default not in config: config[default] = getattr( C, 'DEFAULT_{}'.format(default.upper()) ) config['connection'] = config.get('connection', 'smart') config['ssh_common_args'] = config.get('ssh_common_args', None) config['ssh_extra_args'] = config.get('ssh_extra_args', None) config['sftp_extra_args'] = config.get('sftp_extra_args', None) config['scp_extra_args'] = config.get('scp_extra_args', None) config['extra_vars'] = config.get('extra_vars', {}) config['diff'] = config.get('diff', False) config['listhosts'] = config.get('listhosts', False) config['listtasks'] = config.get('listtasks', False) config['listtags'] = config.get('listtags', False) config['syntax'] = config.get('syntax', False) config['verbosity'] = VERBOSITY.get(verbosity) config['module_path'] = './' config['check'] = False self.options = options_as_class(config) # create default data loader self.loader = DataLoader() # self.loader.set_vault_password(vault_password) variables = {} try: variables = self.loader.load_from_file(vars_filename) except Exception: pass # loading inventory self.inventory = InventoryManager( loader=self.loader, sources=None ) for group in hosts.keys(): self.inventory.add_group(group) for host in hosts[group]: self.inventory.add_host(host=host, group=group) # create variable manager self.vm = VariableManager( loader=self.loader, inventory=self.inventory ) self.vm.extra_vars = variables # create a playbook executor self.pbex = playbook_executor.PlaybookExecutor( playbooks=[playbook], inventory=self.inventory, variable_manager=self.vm, loader=self.loader, options=self.options, passwords={} ) self.result_callback = JsonResultCallback() # self.result_callback.set_options(self.options) self.pbex._tqm._callback_plugins.append(self.result_callback) pass def run(self): self.pbex.run() return { 'plays': self.result_callback.results, 'stats': self.result_callback.summary } pass
class AnsibleApi_v2(object): """ call ansible execute modules """ def __init__( self, rediskey=None, logid=None, private_key_file=None, *args, **kwargs): # self.resource = resource self.inventory = None self.variable_manage = None self.loader = None # self.options = None self.passwords = None self.callback = None self.__initializeDate() self.results_raw = {} self.redisKey = rediskey self.logId = logid # self.private_key_file = private_key_file def __initializeDate(self): """ 初始化ansible option :return: """ self.loader = DataLoader() # ansible >= 2.8 api为cli构建,改为利用上下文对象来设置某些选项 context.CLIARGS = ImmutableDict( connection='smart', module_path=None, forks=10, timeout=60, remote_user='******', ask_pass=True, private_key_file=None, ssh_common_args='-o StrictHostKeyChecking=no', ssh_extra_args='-o StrictHostKeyChecking=no', sftp_extra_args=None, scp_extra_args=None, become=True, become_method="sudo", become_user='******', ask_value_pass=False, verbosity=3, check=False, listhosts=None, listtasks=None, listtags=None, syntax=None, diff=True, start_at_task=None) # self.passwords = dict(sshpass=None, becomepass=None) self.passwords = dict() self.inventory = InventoryManager( loader=self.loader, sources='../../hosts', ) self.variable_manage = VariableManager( loader=self.loader, inventory=self.inventory) def adh_model( self, hostip, group, port, sshuser, password, phpbin, mysqladdress, mysqluser, mysqlpassword, shop_version, vhost_path, mongodbaddress, mongodbuser, mongodbpassword, subdomain, module_name, module_args, fastcgi_pass, *args, **kwargs): """ run module from ansible ad-hoc :param hostip: 主机列表 :param module_name: ansible模块名 :param module_args: ansible模块参数 :return: result """ # 构建数据模型 self.inventory.add_group(group=group) self.inventory.add_host(host=hostip, port=port, group=group) hosts = self.inventory.get_host(hostname=hostip) # self.variable_manage.set_host_variable( # host=hosts, varname="ansible_ssh_pass", value=password) # self.variable_manage.extra_vars = {"phpbin": phpbin} vars = { 'ansible_ssh_host': hostip, "phpbin": phpbin, "ansible_user": sshuser, "ansible_ssh_pass": password} self.variable_manage.extra_vars.update(**vars) print(self.variable_manage.get_vars(host=hosts)) play_source = dict( name='ansible play', hosts=hostip, gather_facts='no', tasks=[dict(action=dict(module=module_name, args=module_args))] ) play = Play().load( play_source, variable_manager=self.variable_manage, loader=self.loader) tqm = None self.callback = AdhocResultsCollector() import traceback try: tqm = TaskQueueManager( inventory=self.inventory, variable_manager=self.variable_manage, loader=self.loader, # options=self.options, passwords=self.passwords, stdout_callback="minimal", ) tqm._stdout_callback = self.callback constants.HOST_KEY_CHECKING = False print(tqm.run(play)) except Exception as err: print(traceback.print_exc()) finally: if tqm is not None: tqm.cleanup() def playbookrun(self, *args, **kwargs): """playbook runner""" self.callback = PlaybookResultsCollector() # 构建数据模型 self.inventory.add_group(group=kwargs["group"]) self.inventory.add_host(host=kwargs["domain"], port=kwargs["port"], group=kwargs["group"]) self.variable_manage.extra_vars.update(**kwargs) playbook = PlaybookExecutor( playbooks=kwargs["playbook_path"], inventory=self.inventory, variable_manager=self.variable_manage, loader=self.loader, passwords=self.passwords) playbook._tqm._stdout_callback = self.callback constants.HOST_KEY_CHECKING = False # 关闭第一次使用ansible连接客户端时输入命令 # print(self.variable_manage.get_vars(host=hosts)) playbook.run() 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 for host, result in self.callback.host_failed.items(): self.results_raw['failed'][host] = result._result for host, result in self.callback.host_unreachable.items(): self.results_raw['unreachable'][host] = result._result 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 self.results_raw['ok'] = result._result for host, result in self.callback.task_failed.items(): self.results_raw['failed'] = result._result for host, result in self.callback.task_status.items(): self.results_raw['status'] = result for host, result in self.callback.task_skipped.items(): self.results_raw['skipped'] = result._result for host, result in self.callback.task_unreachable.items(): self.results_raw['unreachable'] = result._result return self.results_raw
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"))
class MyInventory(InventoryManager): """ 定义ansible的清单目录(静态在/etc/ansible/hosts中获取,动态通过定义) """ def __init__(self, resource, loader): """ resource的数据格式是一个列表字典,比如 { "group1": { "hosts": [{"hostname": "10.0.0.0", "port": "22", "username": "******", "password": "******"}, ...], "vars": {"var1": value1, "var2": value2, ...} } } 如果你只传入1个列表,这默认该列表内的所有主机属于my_group组,比如 [{"hostname": "10.0.0.0", "port": "22", "username": "******", "password": "******"}, ...] """ self.resource = resource self.inventory = InventoryManager(loader=loader, sources=[]) self.gen_inventory() def my_add_group(self, hosts, groupname, groupvars=None): """ add hosts to a group """ my_group = Group(name=groupname) # if group variables exists, add them to group if groupvars: for key, value in groupvars.iteritems(): my_group.set_variable(key, value) # add hosts to group for host in hosts: # set connection variables hostname = host.get("hostname") hostip = host.get('ip', hostname) hostport = host.get("port") username = host.get("username") password = host.get("password") ssh_key = host.get("ssh_key") my_host = Host(name=hostname, port=hostport) my_host.set_variable('ansible_ssh_host', hostip) my_host.set_variable('ansible_ssh_port', hostport) my_host.set_variable('ansible_ssh_user', username) my_host.set_variable('ansible_ssh_pass', password) my_host.set_variable('ansible_ssh_private_key_file', ssh_key) # set other variables for key, value in host.items(): if key not in ["hostname", "port", "username", "password"]: my_host.set_variable(key, value) # add to group my_group.add_host(my_host) self.inventory.add_group(my_group) def gen_inventory(self): """ 增加主机到清单中 """ if isinstance(self.resource, list): self.my_add_group(self.resource, 'default_group') elif isinstance(self.resource, dict): for groupname, hosts_and_vars in self.resource.iteritems(): self.my_add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))