[英]jinja2 Ansible filter dictionary
我已经做了一段时间了,但是最近开始做一些更高级的事情,例如提取数据以推动外部来源的行动。 这导致我不得不更深入地研究Ansible如何允许逻辑和变量解析,这需要我深入研究jinja2。
在我的剧本中,我试图从etcd中提取数据,允许我构造授权的sudo spec文件,然后将其传递给角色以添加到适当的系统中。
我的数据源除了存储构建规范所需的数据外,还具有用于审计和日志记录目的的元数据。
我的数据源的一个关键方面是,在删除访问权限后,不应删除任何元数据,即用户XYZ在10天内的sudo密码少。 如此多的方面都有一个状态字段,该状态字段可能处于活动状态,也可能处于 非活动状态,或者在sudo spec 授予或撤销的情况下。
我已经成功构建了一个查找,该查找可以拉回类似于以下内容的字典-然后使用后续的ansible语句对其进行解析。 我能够成功处理和提取所有数据,但其规格处于授予状态的组/用户除外。
当规范处于“ grant”状态时,我需要提取linuxName字段,并将其传递给配置sudo的角色。
我尝试了多种过滤器变体,其中大多数最终导致我得到拒绝或类似消息,或者是NULL值而不是所需的值列表。
有人对如何实现这一目标有想法吗?
提前致谢。
样本数据
ok: [serverName] => {
"sudoInfraSpecs": [
{
"infra_admins": {
"addedBy": "someUser",
"commands": "FULL_SUDO",
"comment": "platform support admins",
"dateAdded": "20180720",
"defaults": "!requiretty",
"hosts": "SERVERS",
"name": "infra_admins",
"operators": "ROOT",
"state": "active",
"tags": "PASSWD",
"users": {
"admingroup1": {
"addedBy": "someUser",
"dateAdded": "20180719",
"linuxName": "%admingroup1",
"name": "admingroup1",
"state": "grant"
},
"admingroup2": {
"addedBy": "someUser",
"dateAdded": "20180719",
"linuxName": "%admingroup2",
"name": "admingroup2",
"state": "grant"
}
}
},
"ucp_service_account": {
"addedBy": "someUser",
"commands": "FULL_SUDO",
"comment": "platform service account",
"dateAdded": "20180720",
"defaults": "!requiretty",
"hosts": "SERVERS",
"name": "platform_service_account",
"operators": "ROOT",
"state": "active",
"tags": "NOPASSWD,LOG_OUTPUT",
"users": {
"platformUser": {
"addedBy": "someUser",
"dateAdded": "20180719",
"linuxName": "platformUser",
"name": "platformUser",
"state": "grant"
}
}
}
}
]
}
Ansible摘要
- name: Translate infraAdmins sudoers specs from etcd into a list for processing [1]
set_fact:
tempInfraSpecs:
name: "{{ item.value.name}}"
comment: "{{ item.value.comment }}"
users: "{{ item.value.users | list }}"
hosts: "{{ item.value.hosts.split(',') }}"
operators: "{{ item.value.operators.split(',') }}"
tags: "{{ item.value.tags.split(',') }}"
commands: "{{ item.value.commands.split(',') }}"
defaults: "{{ item.value.defaults.split(',') }}"
with_dict: "{{ sudoInfraSpecs }}"
when: item.value.state == 'active'
register: tempsudoInfraSpecs
- name: Translate infraAdmins sudoers specs from etcd into a list for processing [2]
set_fact:
sudoInfraSpecs_fact: "{{ tempsudoInfraSpecs.results | selectattr('ansible_facts','defined')| map(attribute='ansible_facts.tempInfraSpecs') | list }}"
所需的粗略输出字典:
sudoInfraSpecs:
- infra_admins:
addedBy: someUser
commands: FULL_SUDO
comment: platform support admins
dateAdded: '20180720'
defaults: "!requiretty"
hosts: SERVERS
name: infra_admins
operators: ROOT
state: active
tags: PASSWD
users:
"%admingroup1"
"%admingroup2"
- ucp_service_account:
addedBy: someUser
commands: FULL_SUDO
comment: platform service account
dateAdded: '20180720'
defaults: "!requiretty"
hosts: SERVERS
name: platform_service_account
operators: ROOT
state: active
tags: NOPASSWD,LOG_OUTPUT
users:
"platformUser"
最后,我通过创建一个自定义过滤器以供在我的剧本中使用,该剧本解析构成用户的嵌套字典,最终完成了这一点:
#!/usr/bin/python
def getSpecActiveMembers(my_dict):
thisSpecActiveMembers = []
for i, value in my_dict.iteritems():
if value['state'] == 'grant':
thisSpecActiveMembers.append(value['linuxName'])
return thisSpecActiveMembers
class FilterModule(object):
def filters(self):
return {
'getSpecActiveMembers': getSpecActiveMembers
}
最终使用户从上面列出的源平坦化到所需的输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.