O Ansible 2.2 tem loop_control.label
para isso.
- name: Secure ssl keys
file: path={{ item.path }} user=root group=root mode=600
with_items: secure_ssl_keys_result.files
loop_control:
label: "{{ item.path }}"
Estou protegendo automaticamente as chaves ssl assim:
- name: Find ssl keys
find: paths="/etc/ssl/" patterns="*.key" recurse=yes
register: secure_ssl_keys_result
- name: Secure ssl keys
file: path={{ item.path }} user=root group=root mode=600
with_items: secure_ssl_keys_result.files
Agora, para cada item, há uma enorme mensagem de log com todo o conteúdo do item:
ok: [127.0.0.1] => (item={u'uid': 0, u'woth': False, u'mtime': 1454939377.264, u'inode': 400377, u'isgid': False, u'size': 3243, u'roth': False, u'isuid': False, u'isreg': True, u'gid': 0, u'ischr': False, u'wusr': True, u'xoth': False, u'rusr': True, u'nlink': 1, u'issock': False, u'rgrp': False, u'path': u'/etc/ssl/foo.key', u'xusr': False, u'atime': 1454939377.264, u'isdir': False, u'ctime': 1454939657.116, u'isblk': False, u'xgrp': False, u'dev': 65025, u'wgrp': False, u'isfifo': False, u'mode': u'0600', u'islnk': False})
Isso é incrivelmente ilegível, pois eu só quero saber o caminho do item que está sendo processado (e talvez alterado). Com um grande número de teclas, isso fica fora de controle muito rápido.
Como posso alterar essa jogada de uma maneira que apenas o item.path esteja sendo impresso para cada item?
Eu já tentei no_log: True
, mas isso omite completamente a saída do curso.
Use
secure_ssl_keys_result.files|map(attribute='path')|list
Ele retornará uma lista de caminhos:
['/etc/ssl../', '/etc/ssl/.../']
Toda a sua tarefa se tornaria:
- name: Secure ssl keys
file: path={{ item }} user=root group=root mode=600
with_items: secure_ssl_keys_result.files|map(attribute='path')|list
Cuidado, você só pode selecionar um único atributo, não é possível usar attribute=['path', 'mode']
ou similar.
Pensei em usar o extrato para obter várias chaves ( porque às vezes é necessário ter uma segunda chave para uma condição when
), mas não consegui fazer isso, já que eu precisaria mapear a lista de dicts, então mapear a lista de chaves sobre o dict específico, que não parece possível, já que o mapa aceita apenas um nome de função, mas não uma função / função encadeada. Eu ficaria grato por uma sugestão aqui!
Uma ótima idéia dos comentários (Obrigado, Uditha Desilva !):
- name: Secure ssl keys file: path={{ item.0 }} mode=600 owner={{ item.1 }}
with_together:
- secure_ssl_keys_result.files|map(attribute='path')|list
- secure_ssl_keys_result.files|map(attribute='uid')|list
Como alternativa, um filtro personalizado como este pode ser usado (foi o que eu fiz antes de descobrir map
):
from ansible import errors
import re
def cleandict(items, keepkeys):
try:
newitems = []
if not isinstance(items, list):
items = [items]
if not isinstance(keepkeys, list):
keepkeys = [keepkeys]
for dictionary in items:
newdictionary = {}
for keepkey in keepkeys:
newdictionary[keepkey] = dictionary.get(keepkey)
newitems.append(newdictionary)
return newitems
except Exception, e:
raise errors.AnsibleFilterError('split plugin error: %s' % str(e) )
#raise errors.AnsibleFilterError('split plugin error: %s, string=%s' % str(e),str(items) )
class FilterModule(object):
''' A filter to split a string into a list. '''
def filters(self):
return {
'cleandict' : cleandict
}
ansible.cfg
:
filter_plugins = ~/.ansible/plugins/filter_plugins/:/usr/share/ansible_plugins/filter_plugins
Você não pode. É tudo ou nada (via no_log: True
)
Tags ansible