def inventory_html(): loader = DataLoader() variable_manager = VariableManager() sa_inv = Inventory(loader=loader, variable_manager=variable_manager, host_list='%s/hosts' % app.config.get('ANSIBLE_PATH')) # print sa_inv.serialize() if request.args.get('group'): hosts = sa_inv.get_hosts(request.args.get('group')) group_vars = sa_inv.get_group_variables( groupname=request.args.get('group')) else: hosts = sa_inv.get_hosts() group_vars = None if request.args.get('host'): host_vars = sa_inv.get_host_vars( host=sa_inv.get_host(request.args.get('host'))) else: host_vars = None return render_template('inventory.html', group=request.args.get('group'), host=request.args.get('host'), groups=sa_inv.get_groups(), hosts=hosts, group_vars=group_vars, host_vars=host_vars)
def execute_playbook(playbook, host, *args, **kwargs): playbook = os.path.join(playbook_store_path,playbook) Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'remote_user', 'listhosts', 'listtasks', 'listtags', 'syntax', 'verbose']) #needed objects variable_manager = VariableManager() loader = DataLoader() options = Options(connection='ssh', module_path='./modules', forks=100, become=None, become_method=None, become_user=None, check=False, remote_user='******', listhosts=None, listtasks=None, listtags=None, syntax=None, verbose=None) passwords = dict(vault_pass='******') #Create inventory and pass to manager inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[host]) variable_manager.set_inventory(inventory) hostobj = inventory.get_host(host) for varname, value in kwargs.iteritems(): variable_manager.set_host_variable(hostobj, varname, value) #Should execute fine executor = PlaybookExecutor(playbooks=[ playbook ], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) #Forcing our callback object into the executor executor._tqm._stdout_callback = "json" results = executor.run() pprint.pprint(results) report_tasks = executor._tqm._stdout_callback.results[0]['tasks'] report = executor._tqm._stdout_callback.results report_stats = executor._tqm._stats.summarize(host) results_output = get_output(report_tasks, host) return dict(stats = report_stats, results = results_output)
def _provision_node(self, node_name, ip_address, playbook_name): # playbook_path = '/etc/ansible/install_git.yml' user = None password = None playbook_path = playbook_name host_name = ip_address # if not os.path.exists(playbook_path): # raise Exception('The playbook does not exist') variable_manager = VariableManager() loader = DataLoader() inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=[host_name]) variable_manager.set_inventory(inventory) options = Options(connection='smart', become_user=user) passwords = {} host = inventory.get_host(host_name) variable_manager.set_host_variable(host, 'connection', 'ssh') variable_manager.set_host_variable(host, 'ansible_ssh_user', 'root') variable_manager.set_host_variable(host, 'ansible_ssh_pass', 'root') pbex = PlaybookExecutor( playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=passwords) try: pbex.run() except Exception as ex: click.echo(ex.message)
class AnsibleInventory(object): def __init__(self, inventory_generator): """ :type inventory_generator: ops.inventory.generator.InventoryGenerator """ self.inventory_generator = inventory_generator self.generated_path, self.ssh_config_path = inventory_generator.generate( ) # clean up variables cache for tests ansible_vars.VARIABLE_CACHE = dict() ansible_vars.HOSTVARS_CACHE = dict() ansible_inventory.HOSTS_PATTERNS_CACHE = dict() self.variable_manager = VariableManager() loader = DataLoader() self.inventory = Inventory(loader=loader, variable_manager=self.variable_manager, host_list=self.generated_path) self.variable_manager.set_inventory(self.inventory) self.inventory.set_playbook_basedir(self.generated_path) def get_hosts(self, limit): return self.inventory.get_hosts(limit) def get_host(self, host): return self.inventory.get_host(unicode(host)) def get_vars(self, host): return self.inventory.get_vars(unicode(host)) def get_ssh_config(self): return self.ssh_config_path
class InventoryWrapper: def __init__(self, host_list): self.loader = DataLoader() # this code is a bit ugly, because Ansible 2.4 switched the order # of the object and the pattern (InventoryManager is a argument to # VariableManager, and vice-versa on version <2.3) if ANSIBLE_24: self.im = InventoryManager(loader=self.loader, sources=[host_list, ]) self.vm = VariableManager(loader=self.loader, inventory=self.im) else: self.vm = VariableManager() self.im = Inventory(self.loader, self.vm, host_list) def get_loader(self): return self.loader def get_variable_manager(self): return VariableManagerWrapper(self.vm) def get_groups(self): if ANSIBLE_24: return self.im.groups return self.im.get_groups() def get_hosts(self, group): if ANSIBLE_24: return self.im.get_hosts(pattern=group) return self.im.get_hosts(group) def get_host(self, host): return self.im.get_host(host) def refresh_inventory(self): return self.im.refresh_inventory()
class ACHost(object): """ Wrap an host from an aeriscloud inventory and provides ssh informations for scripts """ def __init__(self, inventory, hostname): from ansible.inventory import Inventory as AnsibleInventory from ansible.parsing.dataloader import DataLoader from ansible.vars import VariableManager inv_file = os.path.join(inventory_path, inventory) if not os.path.isfile(inv_file): raise IOError('Inventory %s does not exists' % inventory) self._name = inventory self._hostname = hostname self._inventory = AnsibleInventory( host_list=inv_file, loader=DataLoader(), variable_manager=VariableManager() ) self._host = self._inventory.get_host(hostname) if not self._host: raise NameError('Host "%s" not found in the inventory %s' % (hostname, inventory)) self._vars = self._host.get_group_vars().copy() self._vars.update(self._host.get_vars()) def ssh_host(self): for idx in ['ansible_host', 'ansible_ssh_host']: if idx in self._vars: return self._vars[idx] return self._hostname def ssh_key(self): for idx in ['ansible_private_key_file', 'ansible_ssh_private_key_file']: if idx in self._vars: return self._vars[idx] return None def ssh_user(self): for idx in ['ansible_user', 'ansible_ssh_user', 'username']: if idx in self._vars: return self._vars[idx] return None def variables(self): return self._vars
class ACHost(object): """ Wrap an host from an aeriscloud inventory and provides ssh informations for scripts """ def __init__(self, inventory, hostname): from ansible.inventory import Inventory as AnsibleInventory inv_file = os.path.join(inventory_path, inventory) if not os.path.isfile(inv_file): raise IOError('Inventory %s does not exists' % inventory) self._name = inventory self._hostname = hostname self._inventory = AnsibleInventory(host_list=inv_file) self._host = self._inventory.get_host(hostname) if not self._host: raise NameError('Host "%s" not found in the inventory %s' % (hostname, inventory)) self._vars = self._host.get_variables() def ssh_host(self): if 'ansible_ssh_host' in self._vars: return self._vars['ansible_ssh_host'] return self._hostname def ssh_key(self): if 'ansible_ssh_private_key_file' in self._vars: return self._vars['ansible_ssh_private_key_file'] return None def ssh_user(self): if 'ansible_ssh_user' in self._vars: return self._vars['ansible_ssh_user'] if 'username' in self._vars: return self._vars['username'] return None def variables(self): return self._vars
class SSHInventory: def __init__(self): variable_manager = VariableManager() loader = DataLoader() self.inventory = Inventory(loader=loader, variable_manager=variable_manager) def get_host(self, host): return self.inventory.get_host(host) def get_ssh_cmd(self, host): port = "22" user = "******" options = "" if 'ansible_port' in host.vars: port = host.vars['ansible_port'] if 'ansible_ssh_port' in host.vars: port = host.vars['ansible_ssh_port'] if 'ansible_user' in host.vars: user = host.vars['ansible_user'] if 'ansible_ssh_user' in host.vars: user = host.vars['ansible_ssh_user'] ssh_args = load_ssh_args() if ssh_args: options += ssh_args if 'ansible_ssh_private_key_file' in host.vars: options += " -i %s" % host.vars['ansible_ssh_private_key_file'] return "ssh {}@{} -p {} {}".format(user, host.address, port, options)
print('[X] Some servers were not contacted:') for server, why in results['dark'].items(): print('\t%s: %s' % (server, why['msg'])) print('\n\n\n') if not results['contacted']: print('[X] All servers failed, exiting') exit(1) pg = connect('host=127.0.0.1 user=admin password=... dbname=...') pg.autocommit = True with pg.cursor() as cursor: print('[✓] Contacted %s servers' % (len(results['contacted']))) for server, details in results['contacted'].items(): nameservers = details['stdout'].split('\n') server_id = inventory.get_host(server).get_variables()['srv_id'] print('\t[✓] Cleaning up for server %s (%s)' % (server, server_id)) cursor.execute('DELETE FROM nameservers WHERE srv_id = %s', server_id) print('\t[✓] Inserting %s (%s):' % (server, server_id)) for nameserver in nameservers: cursor.execute( 'INSERT INTO nameservers (srv_id, ip) VALUES (%s, %s)', (server_id, nameserver)) print('\t\t[✓] Inserted %s ' % nameserver) print('\t\t[✓] Done inserting') exit(0)
def test_variable_manager_precedence(self, mock_basedir): ''' Tests complex variations and combinations of get_vars() with different objects to modify the context under which variables are merged. ''' v = VariableManager() v._fact_cache = defaultdict(dict) fake_loader = DictDataLoader({ # inventory1 '/etc/ansible/inventory1': """ [group2:children] group1 [group1] host1 host_var=host_var_from_inventory_host1 [group1:vars] group_var = group_var_from_inventory_group1 [group2:vars] group_var = group_var_from_inventory_group2 """, # role defaults_only1 '/etc/ansible/roles/defaults_only1/defaults/main.yml': """ default_var: "default_var_from_defaults_only1" host_var: "host_var_from_defaults_only1" group_var: "group_var_from_defaults_only1" group_var_all: "group_var_all_from_defaults_only1" extra_var: "extra_var_from_defaults_only1" """, '/etc/ansible/roles/defaults_only1/tasks/main.yml': """ - debug: msg="here i am" """, # role defaults_only2 '/etc/ansible/roles/defaults_only2/defaults/main.yml': """ default_var: "default_var_from_defaults_only2" host_var: "host_var_from_defaults_only2" group_var: "group_var_from_defaults_only2" group_var_all: "group_var_all_from_defaults_only2" extra_var: "extra_var_from_defaults_only2" """, }) mock_basedir.return_value = './' inv1 = Inventory(loader=fake_loader, variable_manager=v, host_list='/etc/ansible/inventory1') inv1.set_playbook_basedir('./') play1 = Play.load(dict( hosts=['all'], roles=['defaults_only1', 'defaults_only2'], ), loader=fake_loader, variable_manager=v) # first we assert that the defaults as viewed as a whole are the merged results # of the defaults from each role, with the last role defined "winning" when # there is a variable naming conflict res = v.get_vars(loader=fake_loader, play=play1) self.assertEqual(res['default_var'], 'default_var_from_defaults_only2') # next, we assert that when vars are viewed from the context of a task within a # role, that task will see its own role defaults before any other role's blocks = play1.compile() task = blocks[1].block[0] res = v.get_vars(loader=fake_loader, play=play1, task=task) self.assertEqual(res['default_var'], 'default_var_from_defaults_only1') # next we assert the precendence of inventory variables v.set_inventory(inv1) h1 = inv1.get_host('host1') res = v.get_vars(loader=fake_loader, play=play1, host=h1) self.assertEqual(res['group_var'], 'group_var_from_inventory_group1') self.assertEqual(res['host_var'], 'host_var_from_inventory_host1') # next we test with group_vars/ files loaded fake_loader.push("/etc/ansible/group_vars/all", """ group_var_all: group_var_all_from_group_vars_all """) fake_loader.push("/etc/ansible/group_vars/group1", """ group_var: group_var_from_group_vars_group1 """) fake_loader.push("/etc/ansible/group_vars/group3", """ # this is a dummy, which should not be used anywhere group_var: group_var_from_group_vars_group3 """) fake_loader.push("/etc/ansible/host_vars/host1", """ host_var: host_var_from_host_vars_host1 """) fake_loader.push("group_vars/group1", """ playbook_group_var: playbook_group_var """) fake_loader.push("host_vars/host1", """ playbook_host_var: playbook_host_var """) v.add_group_vars_file("/etc/ansible/group_vars/all", loader=fake_loader) v.add_group_vars_file("/etc/ansible/group_vars/group1", loader=fake_loader) v.add_group_vars_file("/etc/ansible/group_vars/group2", loader=fake_loader) v.add_group_vars_file("group_vars/group1", loader=fake_loader) v.add_host_vars_file("/etc/ansible/host_vars/host1", loader=fake_loader) v.add_host_vars_file("host_vars/host1", loader=fake_loader) res = v.get_vars(loader=fake_loader, play=play1, host=h1) self.assertEqual(res['group_var'], 'group_var_from_group_vars_group1') self.assertEqual(res['group_var_all'], 'group_var_all_from_group_vars_all') self.assertEqual(res['playbook_group_var'], 'playbook_group_var') self.assertEqual(res['host_var'], 'host_var_from_host_vars_host1') self.assertEqual(res['playbook_host_var'], 'playbook_host_var') # add in the fact cache v._fact_cache['host1'] = dict(fact_cache_var="fact_cache_var_from_fact_cache") res = v.get_vars(loader=fake_loader, play=play1, host=h1) self.assertEqual(res['fact_cache_var'], 'fact_cache_var_from_fact_cache')
for place in places: kwargs = dict(host_list='{}/hosts'.format(place)) if place else {} try: inventory = Inventory(**kwargs) break except AnsibleError: pass if not inventory: tpl = 'could not find a valid host file! looked in: <current directory>, {}' sys.stderr.write(tpl.format(', '.join(filter(None, places)))) sys.exit(2) sys.stdout.write('hosts file found in `{}` directory\n'.format(place or 'current')) host = inventory.get_host(arg_host) if not host: sys.stderr.write('host `{}` not found!'.format(arg_host)) sys.exit(2) args = [ 'ssh', '-p', str(host.vars['ansible_ssh_port']), '{ansible_ssh_user}@{ansible_ssh_host}'.format(**host.vars) ] sys.stdout.write('Connecting to: {}\n'.format(' '.join(args))) call(args) except AnsibleError as e:
def test_variable_manager_precedence(self, mock_basedir): ''' Tests complex variations and combinations of get_vars() with different objects to modify the context under which variables are merged. ''' v = VariableManager() v._fact_cache = defaultdict(dict) fake_loader = DictDataLoader({ # inventory1 '/etc/ansible/inventory1': """ [group2:children] group1 [group1] host1 host_var=host_var_from_inventory_host1 [group1:vars] group_var = group_var_from_inventory_group1 [group2:vars] group_var = group_var_from_inventory_group2 """, # role defaults_only1 '/etc/ansible/roles/defaults_only1/defaults/main.yml': """ default_var: "default_var_from_defaults_only1" host_var: "host_var_from_defaults_only1" group_var: "group_var_from_defaults_only1" group_var_all: "group_var_all_from_defaults_only1" extra_var: "extra_var_from_defaults_only1" """, '/etc/ansible/roles/defaults_only1/tasks/main.yml': """ - debug: msg="here i am" """, # role defaults_only2 '/etc/ansible/roles/defaults_only2/defaults/main.yml': """ default_var: "default_var_from_defaults_only2" host_var: "host_var_from_defaults_only2" group_var: "group_var_from_defaults_only2" group_var_all: "group_var_all_from_defaults_only2" extra_var: "extra_var_from_defaults_only2" """, }) mock_basedir.return_value = './' inv1 = Inventory(loader=fake_loader, variable_manager=v, host_list='/etc/ansible/inventory1') inv1.set_playbook_basedir('./') play1 = Play.load(dict( hosts=['all'], roles=['defaults_only1', 'defaults_only2'], ), loader=fake_loader, variable_manager=v) # first we assert that the defaults as viewed as a whole are the merged results # of the defaults from each role, with the last role defined "winning" when # there is a variable naming conflict res = v.get_vars(loader=fake_loader, play=play1) self.assertEqual(res['default_var'], 'default_var_from_defaults_only2') # next, we assert that when vars are viewed from the context of a task within a # role, that task will see its own role defaults before any other role's blocks = play1.compile() task = blocks[1].block[0] res = v.get_vars(loader=fake_loader, play=play1, task=task) self.assertEqual(res['default_var'], 'default_var_from_defaults_only1') # next we assert the precendence of inventory variables v.set_inventory(inv1) h1 = inv1.get_host('host1') res = v.get_vars(loader=fake_loader, play=play1, host=h1) self.assertEqual(res['group_var'], 'group_var_from_inventory_group1') self.assertEqual(res['host_var'], 'host_var_from_inventory_host1') # next we test with group_vars/ files loaded fake_loader.push( "/etc/ansible/group_vars/all", """ group_var_all: group_var_all_from_group_vars_all """) fake_loader.push( "/etc/ansible/group_vars/group1", """ group_var: group_var_from_group_vars_group1 """) fake_loader.push( "/etc/ansible/group_vars/group3", """ # this is a dummy, which should not be used anywhere group_var: group_var_from_group_vars_group3 """) fake_loader.push( "/etc/ansible/host_vars/host1", """ host_var: host_var_from_host_vars_host1 """) v.add_group_vars_file("/etc/ansible/group_vars/all", loader=fake_loader) v.add_group_vars_file("/etc/ansible/group_vars/group1", loader=fake_loader) v.add_group_vars_file("/etc/ansible/group_vars/group2", loader=fake_loader) v.add_host_vars_file("/etc/ansible/host_vars/host1", loader=fake_loader) res = v.get_vars(loader=fake_loader, play=play1, host=h1) self.assertEqual(res['group_var'], 'group_var_from_group_vars_group1') self.assertEqual(res['group_var_all'], 'group_var_all_from_group_vars_all') self.assertEqual(res['host_var'], 'host_var_from_host_vars_host1') # add in the fact cache v._fact_cache['host1'] = dict( fact_cache_var="fact_cache_var_from_fact_cache") res = v.get_vars(loader=fake_loader, play=play1, host=h1) self.assertEqual(res['fact_cache_var'], 'fact_cache_var_from_fact_cache')
class Inventory: def __init__(self, source): self._source = source self._loader = DataLoader() self._variables = VariableManager() self._inventory = AnsibleInventory(loader=self._loader, variable_manager=self._variables, host_list=self._source) self._groups = dict() self._hosts = dict() def __getitem__(self, name): return self.get(name) def get(self, name): result = None host = self.get_host(name) if host != None: result = host else: group = self.get_group(name) if group != None: result = group else: group_all = self._inventory.get_group('all') if group_all != None: var = group_all.get_vars()[name] if var != None: result = var return result def get_group(self, group_name): result = None if self._groups.has_key(group_name): result = self._groups[group_name] elif self._inventory.get_group(group_name) != None: result = Group(group_name, self) self._groups[group_name] = result return result def get_group_vars(self, group_name): result = None group = self._inventory.get_group(group_name) if group != None: result = group.get_vars() return result def get_host(self, host_name): result = None if self._hosts.has_key(host_name): result = self._hosts[host_name] elif self._inventory.get_host(host_name) != None: result = Host(host_name, self) self._hosts[host_name] = result return result def get_host_vars(self, host_name): result = None host = self._inventory.get_host(host_name) if host != None: result = self._variables.get_vars(self._loader, host=host) return result
class ResourceBase(object): """ generate inventory :param resource: inventory resource, format: { "hosts" : { "host1": {"port": "22", "username": "******", "password": "******"}, "host2": {"port": "22", "username": "******", "password": "******"}, }, "groups": { "group1": {"hosts": ["host1", "host2",...], "vars": {'var1':'xxxx', 'var2':'yyy',...} }, "group2": {"hosts": ["host1", "host2",...], "child": ["group1"], "vars": {'var1':'xxxx', 'var2':'yyy',...} }, } } """ def __init__(self, resource=None): host_list = not resource and ANS_CONS.DEFAULT_HOST_LIST or [] self.loader = DataLoader() self.variable_manager = VariableManager() self.resource = resource self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=host_list) #resource and self.gen_inventory() self.gen_inventory() @staticmethod def gen_host(host_name=None, host_vars=None): """ Generate ansible Host object :param host_name: <string> ansible inventory hostname :param host_vars: <dict> host variables :return: Host object """ if host_vars is None: host_vars = {} ssh_host = host_vars.get('ip', host_name) ssh_port = host_vars.get('port', ANS_CONS.DEFAULT_REMOTE_PORT) ssh_user = host_vars.get('username') ssh_pass = host_vars.get('password') ssh_fkey = host_vars.get('ssh_key') # init Host host = Host(name=host_name, port=ssh_port) host.set_variable('ansible_ssh_host', ssh_host) # shortcut variables ssh_user and host.set_variable('ansible_ssh_user', ssh_user) ssh_pass and host.set_variable('ansible_ssh_pass', ssh_pass) ssh_fkey and host.set_variable('ansible_private_key_file', ssh_fkey) # extra variables for key, value in host_vars.items(): if key not in ['ip', 'port', 'username', 'password', 'ssh_key']: host.set_variable(key, value) # return Host object return host @staticmethod def gen_group(group_name=None, group_vars=None): """ Generate ansible Group object :param group_name: <string> Group Name :param group_vars: <dict> Group Variables :return: ansible Group object """ if group_vars is None: group_vars = {} group = Group(name=group_name) for key, value in group_vars.items(): group.set_variable(key, value) return group def gen_inventory(self): """ :return: None """ # set hosts if 'hosts' in self.resource.keys(): for host, info in self.resource['hosts'].items(): obj_host = self.gen_host(host, info) self.inventory.get_group('all').add_host(obj_host) # add group if 'groups' in self.resource.keys(): for group, detail in self.resource['groups'].items(): obj_group = self.gen_group(group, detail.get('vars', {})) for host in detail.get('hosts', []): obj_group.add_host(self.inventory.get_host(host)) if 'child' in detail.get('child', []): for child in detail.get('child', []): obj_group.add_child_group( self.inventory.get_group(child)) self.inventory.add_group(obj_group) def get_lists(self): print("Host: ") print("=================") for host in self.inventory.list_hosts(): print(host) print("Group: ") print("=================") for group in self.inventory.list_groups(): print(group)
if results['dark']: print('[X] Some servers were not contacted:') for server, why in results['dark'].items(): print('\t%s: %s' % (server, why['msg'])) print('\n\n\n') if not results['contacted']: print('[X] All servers failed, exiting') exit(1) pg = connect('host=127.0.0.1 user=admin password=... dbname=...') pg.autocommit = True with pg.cursor() as cursor: print('[✓] Contacted %s servers' % (len(results['contacted']))) for server, details in results['contacted'].items(): nameservers = details['stdout'].split('\n') server_id = inventory.get_host(server).get_variables()['srv_id'] print('\t[✓] Cleaning up for server %s (%s)' % (server, server_id)) cursor.execute('DELETE FROM nameservers WHERE srv_id = %s', server_id) print('\t[✓] Inserting %s (%s):' % (server, server_id)) for nameserver in nameservers: cursor.execute('INSERT INTO nameservers (srv_id, ip) VALUES (%s, %s)', (server_id, nameserver)) print('\t\t[✓] Inserted %s ' % nameserver) print('\t\t[✓] Done inserting') exit(0)