我已经做了一段时间了,但是最近开始做一些更高级的事情,例如提取数据以推动外部来源的行动。这导致我不得不更深入地研究Ansible如何允许逻辑和变量解析,这需要我深入研究jinja2。
在我的剧本中,我试图从etcd中提取数据,允许我构造授权的sudo spec文件,然后将其传递给角色以添加到适当的系统中。
我的数据源除了存储构建规范所需的数据外,还具有用于审计和日志记录目的的元数据。
我的数据源的一个关键方面是在删除访问权限后,不应删除任何元数据,即用户XYZ在10天内的密码比sudo少。如此多的方面都有一个状态字段,该状态字段可能是活动,无效,或者在使用sudo规范 grant 或撤销。
我已经成功构建了一个查找,该查找可以拉回类似于以下内容的字典-然后使用后续的ansible语句对其进行解析。我能够成功处理和提取所有数据,但其规格处于 grant 状态的组/用户除外。
当规范处于“ 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"
答案 0 :(得分:0)
最后,我通过创建一个自定义过滤器以供在我的剧本中使用,以解析组成用户的嵌套字典来完成此操作:
#!/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
}
这最终使用户从上面列出的来源变平为所需的输出。