# test code for lookup plugins
# (c) 2014, James Tanner <tanner.jc@gmail.com>

# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.

# FILE LOOKUP

- name: make a new file to read
  copy: dest={{output_dir}}/foo.txt mode=0644 content="bar"

- name: load the file as a fact
  set_fact:
    foo: "{{ lookup('file', output_dir + '/foo.txt' ) }}"

- debug: var=foo

- name: verify file lookup
  assert:
    that:
        - "foo == 'bar'"


# PASSWORD LOOKUP

- name: remove previous password files and directory
  file: dest={{item}} state=absent
  with_items:
  - "{{output_dir}}/lookup/password"
  - "{{output_dir}}/lookup/password_with_salt"
  - "{{output_dir}}/lookup"

- name: create a password file
  set_fact:
    newpass: "{{ lookup('password', output_dir + '/lookup/password length=8') }}"

- name: stat the password file directory
  stat: path="{{output_dir}}/lookup"
  register: result

- name: assert the directory's permissions
  assert:
    that:
    - result.stat.mode == '0700'

- name: stat the password file
  stat: path="{{output_dir}}/lookup/password"
  register: result

- name: assert the directory's permissions
  assert:
    that:
    - result.stat.mode == '0600'

- name: get password length
  shell: wc -c {{output_dir}}/lookup/password | awk '{print $1}'
  register: wc_result

- debug: var=wc_result.stdout

- name: read password
  shell: cat {{output_dir}}/lookup/password
  register: cat_result

- debug: var=cat_result.stdout

- name: verify password
  assert:
    that:
        - "wc_result.stdout == '9'"
        - "cat_result.stdout == newpass"
        - "' salt=' not in cat_result.stdout"

- name: fetch password from an existing file
  set_fact:
    pass2: "{{ lookup('password', output_dir + '/lookup/password length=8') }}"

- name: read password (again)
  shell: cat {{output_dir}}/lookup/password
  register: cat_result2

- debug: var=cat_result2.stdout

- name: verify password (again)
  assert:
    that:
        - "cat_result2.stdout == newpass"
        - "' salt=' not in cat_result2.stdout"



- name: create a password (with salt) file
  debug: msg={{ lookup('password', output_dir + '/lookup/password_with_salt encrypt=sha256_crypt') }}

- name: read password and salt
  shell: cat {{output_dir}}/lookup/password_with_salt
  register: cat_pass_salt

- debug: var=cat_pass_salt.stdout

- name: fetch unencrypted password
  set_fact:
    newpass: "{{ lookup('password', output_dir + '/lookup/password_with_salt') }}"

- debug: var=newpass

- name: verify password and salt
  assert:
    that:
        - "cat_pass_salt.stdout != newpass"
        - "cat_pass_salt.stdout.startswith(newpass)"
        - "' salt=' in cat_pass_salt.stdout"
        - "' salt=' not in newpass"


- name: fetch unencrypted password (using empty encrypt parameter)
  set_fact:
    newpass2: "{{ lookup('password', output_dir + '/lookup/password_with_salt encrypt=') }}"

- name: verify lookup password behavior
  assert:
    that:
        - "newpass == newpass2"

- name: verify that we can generate a 1st password without writing it
  set_fact:
    newpass: "{{ lookup('password', '/dev/null') }}"

- name: verify that we can generate a 2nd password without writing it
  set_fact:
    newpass2: "{{ lookup('password', '/dev/null') }}"

- name: verify lookup password behavior with /dev/null
  assert:
    that:
        - "newpass != newpass2"

# ENV LOOKUP

- name: get HOME environment var value
  shell: "echo $HOME"
  register: home_var_value

- name: use env lookup to get HOME var
  set_fact:
    test_val: "{{ lookup('env', 'HOME') }}"

- debug: var=home_var_value.stdout
- debug: var=test_val

- name: compare values
  assert:
    that:
        - "test_val == home_var_value.stdout"


# PIPE LOOKUP

# https://github.com/ansible/ansible/issues/6550
- name: confirm pipe lookup works with a single positional arg
  debug: msg="{{ lookup('pipe', 'ls') }}"


# LOOKUP TEMPLATING

- name: use bare interpolation
  debug: msg="got {{item}}"
  with_items: "{{things1}}"
  register: bare_var

- name: verify that list was interpolated
  assert:
    that:
        - "bare_var.results[0].item == 1"
        - "bare_var.results[1].item == 2"

- name: use list with bare strings in it
  debug: msg={{item}}
  with_items:
    - things2
    - things1

- name: use list with undefined var in it
  debug: msg={{item}}
  with_items: "{{things2}}"
  ignore_errors: True


# BUG #10073 nested template handling

- name: set variable that clashes
  set_fact:
      LOGNAME: foobar


- name: get LOGNAME environment var value
  shell: echo {{ '$LOGNAME' }}
  register: known_var_value

- name: do the lookup for env LOGNAME
  set_fact:
    test_val: "{{ lookup('env', 'LOGNAME') }}"

- debug: var=test_val

- name: compare values
  assert:
    that:
        - "test_val == known_var_value.stdout"


- name: set with_dict
  shell: echo "{{ item.key + '=' + item.value  }}"
  with_dict: "{{ mydict }}"

# URL Lookups

- name: Test that retrieving a url works
  set_fact:
    web_data: "{{ lookup('url', 'https://gist.githubusercontent.com/abadger/9858c22712f62a8effff/raw/43dd47ea691c90a5fa7827892c70241913351963/test') }}"

- name: Assert that the url was retrieved
  assert:
    that:
      - "'one' in web_data"

- name: Test that retrieving a url with invalid cert fails
  set_fact:
    web_data: "{{ lookup('url', 'https://{{ badssl_host }}/') }}"
  ignore_errors: True
  register: url_invalid_cert

- assert:
    that:
      - "url_invalid_cert.failed"
      - "'Error validating the server' in url_invalid_cert.msg or ( url_invalid_cert.msg is search('hostname .* doesn.t match .*'))"

- name: Test that retrieving a url with invalid cert with validate_certs=False works
  set_fact:
    web_data: "{{ lookup('url', 'https://{{ badssl_host }}/', validate_certs=False) }}"
  register: url_no_validate_cert

- assert:
    that:
      - "'{{ badssl_host_substring }}' in web_data"

- name: Test cartesian lookup
  debug: var={{item}}
  with_cartesian:
    - ["A", "B", "C"]
    - ["1", "2", "3"]
  register: product

- name: Verify cartesian lookup
  assert:
    that:
        - product.results[0]['item'] == ["A", "1"]
        - product.results[1]['item'] == ["A", "2"]
        - product.results[2]['item'] == ["A", "3"]
        - product.results[3]['item'] == ["B", "1"]
        - product.results[4]['item'] == ["B", "2"]
        - product.results[5]['item'] == ["B", "3"]
        - product.results[6]['item'] == ["C", "1"]
        - product.results[7]['item'] == ["C", "2"]
        - product.results[8]['item'] == ["C", "3"]

# Template lookups

# ref #18526
- name: Test that we have a proper jinja search path in template lookup
  set_fact:
    hello_world: "{{ lookup('template', 'hello.txt') }}"

- assert:
    that:
      - "hello_world|trim == 'Hello world!'"

# Vars lookups

- name: Test that we can give it a single value and receive a single value
  set_fact:
    var_host: '{{ lookup("vars", "ansible_host") }}'

- assert:
    that:
      - 'var_host == ansible_host'

- name: Test that we can give a list of values to var and receive a list of values back
  set_fact:
    var_host_info: '{{ query("vars", "ansible_host", "ansible_user") }}'

- assert:
    that:
      - 'var_host_info[0] == ansible_host'
      - 'var_host_info[1] == ansible_user'
