I want to create a new dictionary list, 'path: value' to be looped for each user and appended under each item in the user list. The end result would look something like below:
"userdata": [
{
"ClassType": "Full Time",
"FirstName": "Grace",
"LastName": "Higgins",
"path": "OU=fulltime,OU=Test OU,DC=localdemo,DC=local"
},
{
"ClassType": "Part Time",
"FirstName": "Robert",
"LastName": "Miller",
"path": "OU=parttime,OU=Test OU,DC=localdemo,DC=local"
},
{
"ClassType": "Flexi",
"FirstName": "Jeffrey",
"LastName": "Keller",
"path": "OU=flexi,OU=Test OU,DC=localdemo,DC=local"
}
]
The values for path is dependent on the value of the ClassType.
However, when I tried to append the new path: value dictionary list to the original userdata list, the 'path: item.path' is in the wrong layout and also has the wrong value:
TASK [Read_csv_creation : Append to original userdata list] *******************************************************************************************
ok: [localhost] => (item={'FirstName': '}) => {
"ansible_facts": {
"userdata": [
{
"ClassType": "Full Time",
"FirstName": "Grace",
"LastName": "Higgins"
},
{
"ClassType": "Part Time",
"FirstName": "Robert",
"LastName": "Miller"
},
{
"ClassType": "Flexi",
"FirstName": "Jeffrey",
"LastName": "Keller"
},
"path: item.path"
]
},
How can I get the final output as shown below?
"userdata": [
{
"ClassType": "Full Time",
"FirstName": "Grace",
"LastName": "Higgins",
"path": "OU=fulltime,OU=Test OU,DC=localdemo,DC=local"
},
{
"ClassType": "Part Time",
"FirstName": "Robert",
"LastName": "Miller",
"path": "OU=parttime,OU=Test OU,DC=localdemo,DC=local"
},
{
"ClassType": "Flexi",
"FirstName": "Jeffrey",
"LastName": "Keller",
"path": "OU=flexi,OU=Test OU,DC=localdemo,DC=local"
}
]
Below is my tasks file. The variable 'data_list' would be my original list.
- name: Read input file
read_csv:
path: /var/lib/awx/projects/file/creation.csv
key: FirstName
fieldnames: FirstName,LastName,ClassType
delimiter: ','
register: userdata
- name: Initialise data list
set_fact:
data_list: []
- name: Extract the list
set_fact:
data_list: "{{ data_list + [{ 'FirstName': item.FirstName, 'LastName': item.LastName, 'ClassType': item.ClassType }] }}"
loop: "{{ userdata | community.general.json_query('dict.[*][0]') }}"
- name: Set fact for data_list
set_fact:
data_list: "{{ data_list[1:] }}"
- name: If class is full time
set_fact:
path: "OU=fulltime,OU=Test OU,DC=localdemo,DC=local"
when: item.ClassType == "Full Time"
loop: "{{ data_list }}"
- name: If employment type is part time
set_fact:
path: "OU=parttime,OU=Test OU,DC=localdemo,DC=local"
when: item.ClassType == "Part Time"
loop: "{{ data_list }}"
- name: If employment type is flexi
set_fact:
path: "OU=flexi,OU=Test OU,DC=localdemo,DC=local"
when: item.ClassType == "Flexi"
loop: "{{ data_list }}"
- name: Append to original userdata list
set_fact:
userdata: "{{ data_list + ['path: item.path'] }}"
loop: "{{ data_list }}"
The job run output is as below. I have omitted some of it as it is very lengthy:
TASK [Read_csv_creation : Initialise data list] *******************************************************************************************************
ok: [localhost] => {
"ansible_facts": {
"data_list": []
},
"changed": false
}
TASK [Read_csv_creation : Read input file] ************************************************************************************************************
ok: [localhost] => {
"changed": false,
"dict": {
" FirstName ": {
"ClassType": " Employment Type ",
"FirstName": " FirstName ",
"LastName": " Last Name "
},
"Grace": {
"ClassType": "Sub Contract",
"FirstName": "Grace",
"LastName": "Higgins"
},
"Robert": {
"ClassType": "Contract",
"FirstName": "Robert",
"LastName": "Miller"
},
"Jeffrey": {
"ClassType": "Full Time",
"FirstName": "Jeffrey",
"LastName": "Keller"
}
},
"invocation": {
"module_args": {
"delimiter": ",",
"dialect": "excel",
"fieldnames": [
"FirstName",
"LastName",
"ClassType"
],
"key": "FirstName",
"path": "/var/lib/awx/projects/file/creation.csv",
"skipinitialspace": null,
"strict": null,
"unique": true
}
},
"list": []
}
TASK [Read_csv_creation : Extract the list] ***********************************************************************************************************
ok: [localhost] => (item={'FirstName': ' FirstName ', 'LastName': ' Last Name ', 'ClassType': ' Class Type '}) => {
"ansible_facts": {
"data_list": [
{
"ClassType": " Class Type ",
"FirstName": " FirstName ",
"LastName": " Last Name "
}
]
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"ClassType": " Class Type ",
"FirstName": " FirstName ",
"LastName": " Last Name ",
}
}
ok: [localhost] => (item={'FirstName': '}) => {
"ansible_facts": {
"data_list": [
{
"ClassType": " Class Type ",
"FirstName": " FirstName ",
"LastName": " Last Name ",
}
]
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"ClassType": "Class Time",
"FirstName": "Grace",
"LastName": "Higgins"
}
}
TASK [Read_csv_creation : Set fact for data_list] *****************************************************************************************************
ok: [localhost] => {
"ansible_facts": {
"data_list": [
{
"ClassType": "Full Time",
"FirstName": "Grace",
"LastName": "Higgins"
},
{
"ClassType": "Part Time",
"FirstName": "Robert",
"LastName": "Miller"
},
{
"EmploymentType": "Flexi",
"FirstName": "Jeffrey",
"LastName": "Keller"
}
]
},
"changed": false
}
TASK [Read_csv_creation : If class type is full time] *******************************************************************************************
ok: [localhost] => (item={'FirstName': 'Grace', 'LastName': 'Higgins', 'ClassType': 'Full Time'}) => {
"ansible_facts": {
"path": "OU=fulltime,OU=Test OU,DC=localdemo,DC=local"
},
"ansible_loop_var": "item",
"changed": false,
"item": {
"ClassType": "Full Time",
"FirstName": "Grace",
"LastName": "Higgins"
}
}
skipping: [localhost] => (item={'FirstName': 'Robert', 'LastName': 'Miller', 'ClassType': 'Part Time'}) => {
"ansible_loop_var": "item",
"changed": false,
"item": {
"EmploymentType": "Contract",
"FirstName": "Robert",
"LastName": "Miller"
},
"skip_reason": "Conditional result was False"
}
skipping: [localhost] => (item={'FirstName': .....
"ansible_loop_var": "item",
"changed": false,
"item": {
.......
"ClassType": "Flexi"
},
"skip_reason": "Conditional result was False"
}
Given the file for mre testing
shell> cat /tmp/creation.csv
Grace,Higgins,Full Time
Robert,Miller,Part Time
Jeffrey,Keller,Flexi
read the CSV file
- read_csv:
path: /tmp/creation.csv
# key: FirstName
fieldnames: FirstName,LastName,ClassType
delimiter: ','
register: userdata
When you omit the parameter key you get the list without 'extracting'
userdata.list:
- ClassType: Full Time
FirstName: Grace
LastName: Higgins
- ClassType: Part Time
FirstName: Robert
LastName: Miller
- ClassType: Flexi
FirstName: Jeffrey
LastName: Keller
To add the attribute path create the dictionary class_path
class_path:
Full Time: "OU=fulltime,OU=Test OU,DC=localdemo,DC=local"
Part Time: "OU=parttime,OU=Test OU,DC=localdemo,DC=local"
Flexi: "OU=flexi,OU=Test OU,DC=localdemo,DC=local"
From the list map the attribute ClassType, extract the path, and create the list of the hashes
path: "{{ userdata.list|map(attribute='ClassType')|
map('extract', class_path)|
map('community.general.dict_kv', 'path') }}"
gives
path:
- path: OU=fulltime,OU=Test OU,DC=localdemo,DC=local
- path: OU=parttime,OU=Test OU,DC=localdemo,DC=local
- path: OU=flexi,OU=Test OU,DC=localdemo,DC=local
zip the lists and combine the items. You have to use set_facts because the variable userdata has already been used in registered vars
- set_fact:
userdata: "{{ userdata.list|zip(path)|map('combine') }}"
gives what you want
userdata:
- ClassType: Full Time
FirstName: Grace
LastName: Higgins
path: OU=fulltime,OU=Test OU,DC=localdemo,DC=local
- ClassType: Part Time
FirstName: Robert
LastName: Miller
path: OU=parttime,OU=Test OU,DC=localdemo,DC=local
- ClassType: Flexi
FirstName: Jeffrey
LastName: Keller
path: OU=flexi,OU=Test OU,DC=localdemo,DC=local
Example of a complete playbook for testing
- hosts: localhost
vars:
class_path:
Full Time: "OU=fulltime,OU=Test OU,DC=localdemo,DC=local"
Part Time: "OU=parttime,OU=Test OU,DC=localdemo,DC=local"
Flexi: "OU=flexi,OU=Test OU,DC=localdemo,DC=local"
path: "{{ userdata.list|map(attribute='ClassType')|
map('extract', class_path)|
map('community.general.dict_kv', 'path') }}"
tasks:
- read_csv:
path: /tmp/creation.csv
# key: FirstName
fieldnames: FirstName,LastName,ClassType
delimiter: ','
register: userdata
- debug:
var: userdata.list
- debug:
var: path
- set_fact:
userdata: "{{ userdata.list|zip(path)|map('combine') }}"
- debug:
var: userdata