Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to build a list of file names in a local directory?

Tags:

ansible

I have bunch of .keys files in my /files folder. What I want to do is to create users on remote hosts that match these keys files.

Say I have alice.keys, bob.keys, and john.keys in /files. I want the script to create alice, bob and john users, if they do not exist and update/add SSH keys from appropriate .keys file for each user.

I know I can use the loop module to loop through the files, but I do not know how to form the list which contains just file-names, so I can use it later.

My role structure looks like:

sshrole
├── defaults
│   └── main.yml
├── files
│   ├── alice.keys
│   ├── bob.keys
│   └── john.keys
├── handlers
│   └── main.yml
├── README.md
├── tasks
│   ├── main.yml
│   ├── setup.yml
│   ├── update.yml
│   ├── useradd.yml
│   └── userdel.yml
├── templates
│   └── ssh_config.j2
└── vars
    └── main.yml

In short, what I want is to have a variable ssh_users containing {'alice', 'bob', 'john'} values.

UPDATE: Using the accepted answer as a guide, I decided to have a task like:

- name: Extract user-names.
  shell: echo {{item}} | sed 's/.*\/\(.*\)\.keys/\1/'
  register: sed_commands
  with_fileglob: ../files/*.keys

And then I use {{sed_commands.results}} in other tasks.

like image 547
DejanLekic Avatar asked Oct 29 '15 17:10

DejanLekic


People also ask

Can you print a list of file names in a folder?

To print all of the files in a folder, open that folder in Windows Explorer (File Explorer in Windows 8), press CTRL-a to select all of them, right-click any of the selected files, and select Print. Of course, you can also select a few specific files and print them the same way.


1 Answers

You can get the list of files and the contents using a with_fileglob loop, like this:

- hosts: target
  tasks:

    - command: cat {{item}}
      register: ssh_keys
      with_fileglob: files/*.keys
      delegate_to: localhost

When this completes, you will have a variable ssh_keys that contains a results key, which is a list of dictionaries where item is the filename and stdout will contain the content of the file. That is, it looks like this:

"ssh_keys": {
    "changed": true, 
    "msg": "All items completed", 
    "results": [
        {
            "item": "/home/lars/tmp/filetetst/files/john.keys", 
            "stdout": "ssh-rsa ...",
        }, 
        {
            "item": "/home/lars/tmp/filetetst/files/alice.keys", 
            "stdout": "ssh-rsa ...",
        }, 
        {
            "item": "/home/lars/tmp/filetetst/files/bob.keys", 
            "stdout": "ssh-rsa ...",
        }, 
    ]
}

You can use this in a with_items loop to actually make your configuration changes.

- hosts: target
  tasks:

    - command: cat {{item}}
      register: ssh_keys
      with_fileglob: files/*
      delegate_to: localhost

- hosts: target
  tasks:

    - user:
        # username is the last path component of the
        # filename (item.item.split('/')[-1]), and then 
        # we need to remove .keys ([:-5]).
        name: "{{item.item.split('/')[-1][:-5]}}"
      with_items: "{{ssh_keys.results}}"

    - authorized_key:
        user: "{{item.item.split('/')[-1][:-5]}}"
        key: "{{item.stdout}}"
        manage_dir: yes
      with_items: "{{ssh_keys.results}}"
like image 146
larsks Avatar answered Sep 22 '22 03:09

larsks