Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting a variable to default(omit) sets it to a string placeholder instead of undefined #44261

Closed
loop-evgeny opened this issue Aug 16, 2018 · 9 comments
Labels
affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. support:core This issue/PR relates to code supported by the Ansible Engineering Team.

Comments

@loop-evgeny
Copy link

loop-evgeny commented Aug 16, 2018

SUMMARY

When I set a variable to anothervariable | default(omit) and anothervariable is undefined I expect the result to be undefined, but instead it's set to a string placeholder ("__omit_place_holder__SOMEGUID").

ISSUE TYPE
  • Bug Report
COMPONENT NAME

Jinja2 expressions?

ANSIBLE VERSION
ansible 2.6.2
  config file = /media/sf_work/lops/ansible.cfg
  configured module search path = [u'/home/em/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
CONFIGURATION

No changes

OS / ENVIRONMENT

Ubuntu 16.04

STEPS TO REPRODUCE
- hosts: all
  gather_facts: false
  connection: local
  vars:
    stillmissing: "{{ missingvar | default(omit) }}"
  tasks:
  - debug:
      msg: "stillmissing = {{ stillmissing | default('still not defined') }}"
EXPECTED RESULTS
"msg": "stillmissing = still not defined"
ACTUAL RESULTS
"msg": "stillmissing = __omit_place_holder__5ebe2a97fd59a2b8a8f0f9772e8e675496a74faa"
@ansibot
Copy link
Contributor

ansibot commented Aug 16, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Aug 16, 2018
@ansibot
Copy link
Contributor

ansibot commented Aug 16, 2018

Files identified in the description:
None

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot removed the module This issue/PR relates to a module. label Aug 16, 2018
@loop-evgeny
Copy link
Author

default(None) also doesn't work to leave the variable undefined - it gets converted to an empty string

@sivel
Copy link
Member

sivel commented Aug 16, 2018

This is the expected behavior. omit is a special variable for omitting an individual argument to a module with only that value, and not for any more generic process. An Example:

- ping:
    data: "{{ omit }}"

It is not designed to leave a variable undefined. The documentation describes it as:

As of Ansible 1.8, it is possible to use the default filter to omit module parameters using the special omit variable

There is actually no way to define a variable as undefined. The act of defining it, will always define it, regardless of your value. You will need to use additional logic to handle your situation.

If you have further questions please stop by IRC or the mailing list:

@sivel sivel closed this as completed Aug 16, 2018
@loop-evgeny
Copy link
Author

The string "__omit_place_holder__5ebe2a97fd59a2b8a8f0f9772e8e675496a74faa" is expected behavior? What user could possibly expect that?

There is actually no way to define a variable as undefined.

That's a problem. "Defining an undefined variable" sounds like a strange use case, but it's not, for example, if you just want to copy one variable to another, especially a dictionary: keys that were not in the input dictionary should not be in the output one.

@samdoran samdoran removed the needs_triage Needs a first human triage before being processed. label Aug 16, 2018
@bcoca
Copy link
Member

bcoca commented Aug 24, 2018

omit is not for 'undefining variables' it is for 'omitting' action options, as such its is hard to meet 'expectations' when it is being misused.

If you want to 'null' a variable, this can be done (yaml ~ or python None will work), but you cannot 'undefine' it. Still, this would be a 'feature' request, not a bug, but considering that the underlying technologies used also don't permit this, it is not something trivial to implement.

@loop-evgeny
Copy link
Author

Looks like there is already a feature request for this: #22417 (I couldn't find it before).

I would say that the current behaviour is still a bug, regardless of what happens with that feature request. If using omit in this way is not allowed then Ansible should produce an error, rather than proceed with the wrong data.

@bcoca
Copy link
Member

bcoca commented Aug 29, 2018

we cannot know how you will use a variable until the play has ended, by that time that information is irrelevant. So having omit value in a variable is not incorrect nor wrong, the usage of it might be, but that is not something we can know at the time of the value assignment.

@loop-evgeny
Copy link
Author

loop-evgeny commented Aug 30, 2018

So having omit value in a variable is not incorrect nor wrong

I see what you're saying, but seeing the string value "__omit_place_holder__5ebe2a97fd59a2b8a8f0f9772e8e675496a74faa" is never the expected behaviour.

I ran into this again yesterday where I tried something similar with the "mode" variable of the "file" module. What happened was that the mode was simply left unchanged (instead of the | default('0700') being used). This is a real trap that I'm sure many others have fallen into.

It's hard to know without digging into the implementation, but surely you can detect when the variable is being evaluated to its string value and that string value is the omit placeholder?

Even if you error after the play has ended that's much better than silently getting the wrong result, as I did with the mode, so no, I don't think it's "irrelevant".

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
Development

No branches or pull requests

5 participants