Search code examples
ansibleansible-2.xansible-facts

Convert win_service_info dictionary to lowercase


I am using the win_service_info module to store the services of a Windows machine into a dictionary. But, later, I want to search for a specific service by the path to the executable. I want this to be a case insensitive match because part of the path variable is going to be entered in by a user.

I have tried tons of stuff: map, combine, etc. But, it always fails because my set_fact always seems to set my variable type as something other than a dictionary (a list, a string, etc.).

I just want to do a simple lowercase to lowercase comparison to find a match to the executable path in the list of services.

- name: Getting services...
  ansible.windows.win_service_info:
  register: services

- name: Converting to lowercase...
  set_fact:
    lower_services: "{{ services | lower }}"

- name: Locating service by installation path...
  set_fact:
    target_service: "{{ lower_services |
                        selectattr('path', 'equalto', SchedulerPath | lower) |
                        first }}"

  when: lower_services |
        selectattr('path', 'equalto', SchedulerPath | lower) |
        list | length > 0

Solution

  • You can use the Jinja match test along with its parameter ignorecase in order to make case insensitive search.

    But, since you are now making a regex search, you will have to escape the regex tokens out of your search string. This can be achieved with the regex_escape filter.

    So, your set_fact ends up being something like:

    - set_fact:
        target_service: >-
          {{
            services.services
              | selectattr(
                'path',
                'match',
                SchedulerPath | regex_escape ~ '$',
                ignorecase=True
              )
          }}
    

    For example, given:

    - set_fact:
        target_service: >-
          {{
            services.services
              | selectattr(
                'path',
                'match',
                SchedulerPath | regex_escape ~ '$',
                ignorecase=True
              )
          }}
      vars:
        SchedulerPath: c:\windows\system32\foo.exe
        services:
          services:
            - name: foo
              path: C:\Windows\system32\FOO.exe
            - name: bar
              path: C:\Windows\system32\BAR.exe
    

    This yields:

    ok: [localhost] => changed=false 
      ansible_facts:
        target_service:
        - name: foo
          path: C:\Windows\system32\FOO.exe
    

    Note: the above output was generated running the playbook with the option -v, which, amongst other useful information, shows the result of a set_fact task.