Hello,
i am looking to create a tool that pushes sudoers file to remote file using the ansible api
it is a tool for some non technical users
this is what I have
`
from ansible.parsing.dataloader import DataLoader
from ansible.module_utils.common.collections import ImmutableDict
from ansible.inventory.manager import InventoryManager
from ansible.cli import CLI
from ansible.vars.manager import VariableManager
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.playbook.play import Play
from ansible import context
from sudo_manager.objects import Host
from sudo_manager import render_sudoers
from sudo_manager.objects import HostGroup
def get_arguments():
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(“–hostnames”, dest=‘hosts’, help=‘list of hosts seperated by comma or a file name (one hostname per line)’)
group.add_argument(“–hostgroup”, dest=‘hostgrp’, help=‘enter hostgroup name’)
parser.add_argument(“–dest_dir”, dest=‘dest_dir’, help='where to store the sudoers file, dafault is the current directory ', default=“.”)
return parser
def get_hosts(hostgroup):
hostgrp = HostGroup.get_hostgroup(hostgroup)
hosts = hostgrp.hosts
output =
for host in hosts:
output.append(host.hostname)
return output
arguments = get_arguments().parse_args()
hostnames =
if arguments.hosts:
hostnames = arguments.hosts.strip().split(‘,’)
hostnames = [x.strip() for x in list(hostnames)]
hostnames = filter(None, hostnames)
hostnames = set(hostnames)
if arguments.hostgrp:
hostnames = get_hosts(arguments.hostgrp)
for hostname in hostnames:
sudoers_content = render_sudoers(hostname, ‘sudoers.j2’)
sudoers = os.path.join(arguments.dest_dir, 'sudoers%s’ % hostname)
with open(_sudoers, ‘w’) as sudoers_file:
sudoers_file.write(sudoers_content)
my_inv = ‘,’.join(hostnames)+ ‘,’
print (my_inv)
loader = DataLoader()
context.CLIARGS = ImmutableDict(tags={}, listtags=False, listtasks=False, listhosts=False, syntax=False, connection=‘ssh’,
module_path=None, forks=100, private_key_file=None,
ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None,
verbosity=True, check=False, start_at_task=None)
Inventory = InventoryManager(loader=loader, sources=my_inv)
variable_manager = VariableManager(loader=loader, inventory=Inventory)
pbex = PlaybookExecutor(playbooks=[‘/usr/home/secops_ansible/ansible/test.yml’], inventory=Inventory, variable_manager=variable_manager, loader=loader,passwords={})
results = pbex.run()
`
the purpose of this is that user will call a script with a list of hosts or a hostgroup name…then our "sudo_manager will get the hosts, generate the sudoers files… write them to disk and then ansible will push them to all the hosts that were passed as argument.
this is the test,yml contents:
`
- name: deploy sudoers files to remote hosts
hosts: all
become: yes
tasks:
- name: push files
copy:
src: “{{ playbook_dir }}/sudoers_{{ ansible_nodename}}”
dest: /etc/sudoers3x
validate: /usr/sbin/visudo -cf %s
`
when i call the script with some debuging info like show os version it works…
but when i call it with the copy or template module i get an error like this:
an exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: expected string or buffer
fatal: [vm]: FAILED! => {“msg”: “Unexpected failure during module execution.”, “stdout”: “”}
thank you for your assistance.