Я автоматически защищаю ключи SSL следующим образом:
- 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
Теперь для каждого элемента есть огромное сообщение журнала со всем содержимым элемента:
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': Ложь, u'isuid ': Ложь, u'isreg': Верно, u'gid ': 0, u'ischr': Ложь, u'wusr ': Верно, u'xoth ': False, u'rusr': True, u'nlink ': 1, u'issock': False, u'rgrp ': False, u'path': u '/ etc / ssl / foo.key', u 'xusr': Ложь, u'atime ': 1454939377.264, u'isdir': Ложь, u'ctime ': 1454939657.116, u'isblk': Ложь, u'xgrp ': Ложь, u'dev': 65025, u ' wgrp ': False, u'isfifo': False, u'mode ': u'0600', u'islnk ': False})
Это невероятно нечитаемо, так как я хочу знать только путь элемента, который обрабатывается (и, возможно, изменяется). С большим количеством клавиш это очень быстро выходит из-под контроля.
Как я могу изменить эту игру так, чтобы только item.path
распечатывается по каждой позиции?
Я уже пробовал no_log: True
, но это, конечно, полностью исключает вывод.
Ansible 2.2 имеет loop_control.label
для этого.
- 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 }}"
Использовать
secure_ssl_keys_result.files|map(attribute='path')|list
Он вернет список путей:
['/etc/ssl../', '/etc/ssl/.../']
Вся ваша задача станет:
- name: Secure ssl keys
file: path={{ item }} user=root group=root mode=600
with_items: secure_ssl_keys_result.files|map(attribute='path')|list
Помните, что вы можете выбрать только один атрибут, его нельзя использовать attribute=['path', 'mode']
или похожие.
Я думал об использовании извлекать чтобы иметь возможность получить несколько ключей (потому что иногда необходимо иметь второй ключ для when
condition), но не смог этого сделать, так как мне нужно было бы сопоставить список dicts, а затем сопоставить список ключей с конкретным dict, что не кажется возможным, поскольку map принимает только имя функции, но не определение функции / связанные функции. Буду благодарен за предложение здесь!
Отличная идея из комментариев (спасибо, Удита Десилва!):
- 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
В качестве альтернативы можно использовать настраиваемый фильтр, подобный этому (это то, что я сделал до того, как узнал о 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
Вы не можете. Либо все, либо ничего (через no_log: True
)