ZZTest
ZZTest

Reputation: 89

Updating an attribute in an Ansible List using

I am trying to "rearrange" a list in Ansible by updating order_number. The general purpose of item order_number is the install order to be used by a jinja template later (not shown), with 0 being the first item to be installed, 1 as the second, etc.

Here is my data set. Basically, I want to increment specified item's order_number by one

site_yml_vars:
  - description: Install 7zip
    name: 7zip
    order_number: 0
    unique_id: uid_1635095146
  - description: Install Microsoft Teams
    name: MSteams
    order_number: 1
    unique_id: uid_1635095169
  - description: Install Microsoft Outlook
    name: MSOutlook
    order_number: 2
    unique_id: uid_1635095316
  - description: Install NotepadPP
    name: NotepadPP
    order_number: 3
    unique_id: uid_1635095329
  - description: Install Remote Desktop Manager
    name: RDPManager
    order_number: 4
    unique_id: uid_1635095340

I have found the "index number" matches the order number, so site_yml_vars[0] will match the item with order_number 0, site_yml_vars[1] will match order_number 1, etc.

How do I run a "loop" that increments/updates those order_numbers by one given by the supplied list e.g. 3 and 4?

e.g.

set_fact:
  site_yml_vars[item].order_number = site_yml_vars[item].order_number + 1
loop:
  - 3
  - 4

with the resulting site_yml_vars looking like the following where the previous order_number of 3 becomes 4, and the previous order_number of 4 becomes 5:

site_yml_vars:
  - description: Install 7zip
    name: 7zip
    order_number: 0
    unique_id: uid_1635095146
  - description: Install Microsoft Teams
    name: MSteams
    order_number: 1
    unique_id: uid_1635095169
  - description: Install Microsoft Outlook
    name: MSOutlook
    order_number: 2
    unique_id: uid_1635095316
  - description: Install NotepadPP
    name: NotepadPP
    order_number: 4
    unique_id: uid_1635095329
  - description: Install Remote Desktop Manager
    name: RDPManager
    order_number: 5
    unique_id: uid_1635095340

Upvotes: 1

Views: 738

Answers (2)

Frenchy
Frenchy

Reputation: 17035

you could use a custm filter: you create a folder filter_plugins in your playbook folder (i have named the file myfilters.py and the filter customfilter)

the filter:

#!/usr/bin/python
class FilterModule(object):
    def filters(self):
        return {
            'move_down_one': self.move_down_one,
            'move_up_one': self.move_up_one
        }

    def move_up_one(self, obj, listint):
        result = []

        for r in obj:
            if(r['order_number'] in listint):
                r['order_number'] += 1
            result.append(r)
        return result

    def move_down_one(self, obj, listint):
        result = []

        for r in obj:
            if(r['order_number'] in listint):
                r['order_number'] -= 1
            result.append(r)
        return result

even if the site_yml_vars is not sorted by order_number, the plugin increments the right order_number . If you need to sort the site_yml_vars, its just a little modification to the result of plugin to do.

use case:

  tasks:  
    - name: fact
      set_fact:
        site_yml_vars: "{{ site_yml_vars | customfilter([3,4]) }}"

    - name: debug
      debug:
        var: site_yml_vars

result:

ok: [localhost] => 
  site_yml_vars:
  - description: Install 7zip
    name: 7zip
    order_number: 0
    unique_id: uid_1635095146
  - description: Install Microsoft Teams
    name: MSteams
    order_number: 1
    unique_id: uid_1635095169
  - description: Install Microsoft Outlook
    name: MSOutlook
    order_number: 2
    unique_id: uid_1635095316
  - description: Install NotepadPP
    name: NotepadPP
    order_number: 4
    unique_id: uid_1635095329
  - description: Install Remote Desktop Manager
    name: RDPManager
    order_number: 5
    unique_id: uid_1635095340

the filters in 2 files distinct :

move_one_up.py:

#!/usr/bin/python
class FilterModule(object):
    def filters(self):
        return {
            'move_up_one': self.move_up_one
        }

    def move_up_one(self, obj, listint):
        result = []

        for r in obj:
            if(r['order_number'] in listint):
                r['order_number'] += 1
            result.append(r)
        return result

move_down_one.py

#!/usr/bin/python
class FilterModule(object):
    def filters(self):
        return {
            'move_down_one': self.move_down_one
        }

    def move_down_one(self, obj, listint):
        result = []

        for r in obj:
            if(r['order_number'] in listint):
                r['order_number'] -= 1
            result.append(r)
        return result

  tasks:  
    - name: fact
      set_fact:
        site_yml_vars1: "{{ site_yml_vars | move_up_one([3,4]) }}"
    - name: fact
      set_fact:
        site_yml_vars2: "{{ site_yml_vars | move_down_one([3,4]) }}"
    - name: debug
      debug:
        var: site_yml_vars1
    - name: debug
      debug:
        var: site_yml_vars2

result:

ok: [localhost] => 
  site_yml_vars2:
  :
  - description: Install NotepadPP
    name: NotepadPP
    order_number: 4
    unique_id: uid_1635095329
  - description: Install Remote Desktop Manager
    name: RDPManager
    order_number: 5
    unique_id: uid_1635095340

ok: [localhost] => 
  site_yml_vars2:
  :
  - description: Install Microsoft Outlook
    name: MSOutlook
    order_number: 2
    unique_id: uid_1635095316
  - description: Install NotepadPP
    name: NotepadPP
    order_number: 2
    unique_id: uid_1635095329
  - description: Install Remote Desktop Manager
    name: RDPManager
    order_number: 3
    unique_id: uid_1635095340

Upvotes: 1

Vladimir Botka
Vladimir Botka

Reputation: 68394

For example, the task below does the job

    - set_fact:
        site_yml_vars: "{{ site_yml_vars[:item] +
                           [_item] +
                           site_yml_vars[(item +1):] }}"
      loop:
        - 3
        - 4
      vars:
        _order_number: "{{ site_yml_vars[item].order_number + 1 }}"
        _item: "{{ site_yml_vars[item]|
                   combine({'order_number': _order_number|int}) }}"

Upvotes: 0

Related Questions