I have multiple users from 4x different LDAP domains and am trying to automate a way of adding them across multiple servers. Attributes for each user/group are static except for the identity_source_id which can be one of 4 possible values.
I would like to select the correct identity_source_id value based on the name value.
First step is to get the LDAP IDs and Domains from each server Using
I'm able to get the LDAP ID and Domain Name for each LDAP Config on the server. Then
- name: set fact to store ID and domain_name
set_fact:
id_domain: "{{ id_domain|d([]) + [{'id': item.id, 'domain_name': item.domain_name }] }}"
with_items: "{{id_source_results.json.results }}"
- name: Create dict for domain_name to id
set_fact:
id_domain_dict: "{{ id_domain | items2dict(key_name='domain_name', value_name='id' ) }}"
- name: Print dict
debug:
var: id_domain_dict
Gives
"id_domain_dict": {
"north.acme.com": "1111111-aaaaa",
"south.acme.com": "2222222-bbbbb",
"east.acme.com": "3333333-ccccc",
"west.acme.com": "4444444-ddddd"
}
The playbook i'm using to push the config is
- name: List LDAP Identity Sources
ansible.builtin.uri:
url: https://{{inventory_hostname}}/api/v1/aaa/role-bindings
validate_certs: no
timeout: 15
force_basic_auth: yes
url_username: "administrator"
url_password: "{{ admin_password }}"
method: POST
body_format: json
body:
[{
"name": "frank@NORTH.ACME.COM",
"type": "remote_user",
"identity_source_type": "LDAP",
"identity_source_id": "{{id_domain_dict.value}}",
"roles": [
{
"role": "admin",
"role_display_name": "Admin"
}
],
"resource_type": "RoleBinding",
"display_name": "frank@NORTH.ACME.COM"
},
{
"name": "ruth@SOUTH.ACME.COM",
"type": "remote_user",
"identity_source_type": "LDAP",
"identity_source_id": "{{id_domain_dict.value}}",
"roles": [
{
"role": "network_engineer",
"role_display_name": "Network Engineer"
}
],
"resource_type": "RoleBinding",
"display_name": "ruth@SOUTH.ACME.COM"
},
{
"name": "finance_team@east.acme.com",
"type": "remote_group",
"identity_source_type": "LDAP",
"identity_source_id": "{{id_domain_dict.value}}",
"roles": [
{
"role": "finance_admin",
"role_display_name": "Finance Admin"
}
],
"resource_type": "RoleBinding",
"display_name": "finance_team@east.acme.com"
},
{
"name": "auditors@west.acme.com",
"type": "remote_group",
"identity_source_type": "LDAP",
"identity_source_id": "{{id_domain_dict.value}}",
"roles": [
{
"role": "read-only",
"role_display_name": "Read-Only"
}
],
"resource_type": "RoleBinding",
"display_name": "auditors@west.acme.com"
}]
return_content: yes
status_code: 200
delegate_to: localhost
Because the API Post body is static, i can't figure out how to select the correct value from id_domain_dict. eg for auditors@west.acme.com the id_domain_dict.value should be 4444444-ddddd
I've tried splitting the user value using "@" but can't get this to work
{% for k,v in id_domain_dict.items %}
{% domain = {{name}}.split('@') %}
{% if domain[1] in k %}
{{ v }}
{% endfor %}
I've also tried
"identity_source_id": "{{ v if domain[1] in k '' }}"
But have been unsuccessful in all attempts
id_domain_dict: "{{ dict(id_source_results.json.results|
json_query('[].[domain_name, id]')) }}"
gives
id_domain_dict:
east.acme.com: 3333333-ccccc
north.acme.com: 1111111-aaaaa
south.acme.com: 2222222-bbbbb
west.acme.com: 4444444-ddddd
shell> cat body.yml
- display_name: frank@NORTH.ACME.COM
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: frank@NORTH.ACME.COM
resource_type: RoleBinding
roles:
- {role: admin, role_display_name: Admin}
type: remote_user
- display_name: ruth@SOUTH.ACME.COM
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: ruth@SOUTH.ACME.COM
resource_type: RoleBinding
roles:
- {role: network_engineer, role_display_name: Network Engineer}
type: remote_user
- display_name: finance_team@east.acme.com
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: finance_team@east.acme.com
resource_type: RoleBinding
roles:
- {role: finance_admin, role_display_name: Finance Admin}
type: remote_group
- display_name: auditors@west.acme.com
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: auditors@west.acme.com
resource_type: RoleBinding
roles:
- {role: read-only, role_display_name: Read-Only}
type: remote_group
body: "{{ lookup('file', 'body.yml')|from_yaml }}"
gives
body:
- display_name: frank@NORTH.ACME.COM
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: frank@NORTH.ACME.COM
resource_type: RoleBinding
roles:
- role: admin
role_display_name: Admin
type: remote_user
- display_name: ruth@SOUTH.ACME.COM
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: ruth@SOUTH.ACME.COM
resource_type: RoleBinding
roles:
- role: network_engineer
role_display_name: Network Engineer
type: remote_user
- display_name: finance_team@east.acme.com
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: finance_team@east.acme.com
resource_type: RoleBinding
roles:
- role: finance_admin
role_display_name: Finance Admin
type: remote_group
- display_name: auditors@west.acme.com
identity_source_id: '{{ id_domain_dict.value }}'
identity_source_type: LDAP
name: auditors@west.acme.com
resource_type: RoleBinding
roles:
- role: read-only
role_display_name: Read-Only
type: remote_group
domains: "{{ body|map(attribute='name')|
map('split', '@')|map('last')|map('lower')|
map('extract', id_domain_dict)|
map('community.general.dict_kv', 'identity_source_id') }}"
gives
domains:
- identity_source_id: 1111111-aaaaa
- identity_source_id: 2222222-bbbbb
- identity_source_id: 3333333-ccccc
- identity_source_id: 4444444-ddddd
body_update: "{{ body|zip(domains)|map('combine') }}"
gives the structure you're looking for
body_update:
- display_name: frank@NORTH.ACME.COM
identity_source_id: 1111111-aaaaa
identity_source_type: LDAP
name: frank@NORTH.ACME.COM
resource_type: RoleBinding
roles:
- role: admin
role_display_name: Admin
type: remote_user
- display_name: ruth@SOUTH.ACME.COM
identity_source_id: 2222222-bbbbb
identity_source_type: LDAP
name: ruth@SOUTH.ACME.COM
resource_type: RoleBinding
roles:
- role: network_engineer
role_display_name: Network Engineer
type: remote_user
- display_name: finance_team@east.acme.com
identity_source_id: 3333333-ccccc
identity_source_type: LDAP
name: finance_team@east.acme.com
resource_type: RoleBinding
roles:
- role: finance_admin
role_display_name: Finance Admin
type: remote_group
- display_name: auditors@west.acme.com
identity_source_id: 4444444-ddddd
identity_source_type: LDAP
name: auditors@west.acme.com
resource_type: RoleBinding
roles:
- role: read-only
role_display_name: Read-Only
type: remote_group
{{ body_update|to_nice_json }}
gives
[
{
"display_name": "frank@NORTH.ACME.COM",
"identity_source_id": "1111111-aaaaa",
"identity_source_type": "LDAP",
"name": "frank@NORTH.ACME.COM",
"resource_type": "RoleBinding",
"roles": [
{
"role": "admin",
"role_display_name": "Admin"
}
],
"type": "remote_user"
},
{
"display_name": "ruth@SOUTH.ACME.COM",
"identity_source_id": "2222222-bbbbb",
"identity_source_type": "LDAP",
"name": "ruth@SOUTH.ACME.COM",
"resource_type": "RoleBinding",
"roles": [
{
"role": "network_engineer",
"role_display_name": "Network Engineer"
}
],
"type": "remote_user"
},
{
"display_name": "finance_team@east.acme.com",
"identity_source_id": "3333333-ccccc",
"identity_source_type": "LDAP",
"name": "finance_team@east.acme.com",
"resource_type": "RoleBinding",
"roles": [
{
"role": "finance_admin",
"role_display_name": "Finance Admin"
}
],
"type": "remote_group"
},
{
"display_name": "auditors@west.acme.com",
"identity_source_id": "4444444-ddddd",
"identity_source_type": "LDAP",
"name": "auditors@west.acme.com",
"resource_type": "RoleBinding",
"roles": [
{
"role": "read-only",
"role_display_name": "Read-Only"
}
],
"type": "remote_group"
}
]
Example of a complete playbook for testing
- hosts: localhost
vars:
id_source_results:
json:
results:
- {id: 1111111-aaaaa, domain_name: north.acme.com}
- {id: 2222222-bbbbb, domain_name: south.acme.com}
- {id: 3333333-ccccc, domain_name: east.acme.com}
- {id: 4444444-ddddd, domain_name: west.acme.com}
id_domain_dict: "{{ dict(id_source_results.json.results|
json_query('[].[domain_name, id]')) }}"
body: "{{ lookup('file', 'body.yml')|from_yaml }}"
domains: "{{ body|map(attribute='name')|
map('split', '@')|map('last')|map('lower')|
map('extract', id_domain_dict)|
map('community.general.dict_kv', 'identity_source_id') }}"
body_update: "{{ body|zip(domains)|map('combine') }}"
tasks:
- debug:
var: id_domain_dict
- debug:
var: body
- debug:
var: domains
- debug:
var: body_update
- debug:
msg: |
{{ body_update|to_nice_json }}