Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Allow value to be bool where 'yes'/'no' are in choices #4220

Closed
wants to merge 1 commit into from

Conversation

tmshn
Copy link

@tmshn tmshn commented Jul 20, 2016

NOTE This pull request work on same issue as #2593 on ansible-modules-extras. Therefore, below comment is almost copy-and-paste.

ISSUE TYPE
  • Feature Pull Request
COMPONENT NAMES
  • _docker
  • docker_container
  • docker_image
  • _nova_compute
  • cl_img_install
  • apt

I did not modify uri module, since 'yes'/'no' choices of follow_redirects argument is deprecated.

ANSIBLE VERSION
ansible 2.1.0.0
  config file =
  configured module search path = Default w/o overrides
SUMMARY

Many arguments from many modules has limited choices including 'yes' and/or 'no' as a option. However, in some case, these are treated as string type; boolean values cause error.

This pull request fix this problem, in the following two way:

1. Change type to bool

If choices are only 'yes' and 'no', this argument can be easily modified to bool type. Even parameter is passed as string, it will be converted to boolean, so it is 100% backward compatible.

Modules:

  • _nova_compute

Example: _nova_compute module's case

---
# This still works,
- name: launch an instance
  nova_compute: wait=yes # snip...

---
# and this still works too,
- name: launch an instance
  nova_compute:
    wait: "yes"
    # snip...

---
# AND! this will work now.
- name: launch an instance
  nova_compute:
    wait: yes
    # snip...
2. Add options to catch boolean

If choices contains other values than 'yes' or 'no', this argument should be kept to be treated as string. In this case, if you pass boolean argument here, it will be converted to 'True' or 'False' respectively. Therefore, adding them to the choices will solve the problem.

Modules:

  • _docker
  • docker_container
  • docker_image
  • apt

Example: apt module's case

The choices of upgrade argument of apt modules contain "safe", "full" and "dist", so it cannot be treated as boolean.

---
# This still works,
- name: upgrade packages
  apt: upgrade=yes update_cache=yes force=yes

---
# and this still works too,
- name: upgrade packages
  apt:
    upgrade: "yes"
    update_cache: yes
    force: yes

---
# AND! this will work now.
- name: upgrade packages
  apt:
    upgrade: yes
    update_cache: yes
    force: yes

---
# Of course, this
- name: upgrade packages
  apt: upgrade=dist

---
# or this still works.
- name: upgrade packages
  apt:
    upgrade: dist

@gregdek
Copy link
Contributor

gregdek commented Jul 20, 2016

Thanks @tmshn for this PR. This module is maintained by the Ansible core team, so it can take a while for patches to be reviewed. Thanks for your patience.

Core team: please review according to guidelines (http://docs.ansible.com/ansible/developing_modules.html#module-checklist) and comment with 'needs_revision' or merge as appropriate.

[This message brought to you by your friendly Ansibull-bot.]

@gundalow
Copy link
Contributor

gundalow commented Aug 4, 2016

Hi,

Some initial thoughts:

  1. _docker.py and _nova_compute are deprecated modules (they start with _)
  2. Using type='bool'is generally the right option
  3. Have a look at mk_boolean in `basic.py

Having an option that accepts bool(ish) and values just seems confusing

@abadger
Copy link
Contributor

abadger commented Aug 4, 2016

@tmshn The type='bool' is definitely acceptable. I'll be proposing a patch to ansible/ansible that addresses some cases where type='bool' is the wrong answer in a moment. If that works for the majority of the cases we can look at any remaining cases to see what the least kludgey way to solve them is.

For others reading this, the problem is that if you write your playbook and specify:

tasks:
  - docker:
      use_tls: no

Then the yaml parser converts that no into a boolean. Then the module gets {use_tls: False}. The argument handling first transforms that boolean False into the string 'False' and then tries to find 'False' in the choices which is currently failing.

Arguably, the right way to fix this is to be explicit in your playbook that you're handling a string here:

tasks:
  - docker:
      use_tls: "no"

key=value should also work although we don't usually like promoting its use:

tasks:
  - docker: use_tls=no

@abadger
Copy link
Contributor

abadger commented Aug 4, 2016

@tmshn See if ansible/ansible#16961 fixes most of the modules in case (2) for you and doesn't cause further problems. If it looks good we can merge that and you can cut this PR down to the modules that still have issues. If they're all in case (1) I think it will then be good to merge. If there's still things in case(2) we'll have to evaluate each of them to see what the best strategy is. (Same thing for ansible/ansible-modules-extras#2593 )

abadger added a commit to abadger/ansible that referenced this pull request Aug 4, 2016
  uri:
    follow_redirects: no

Will lead yaml to set follow_redirects=False.  This is problematic when
the module parameter is not a boolean value but a string.  For instance:

  follow_redirects = dict(required=False, default='safe', choices=['all', 'safe', 'none', 'yes', 'no']),

Our parameter validation code ends up getting follow_redirects="False"
instead of "no".  The 100% fix is for the user to quote their strings in
playbooks like:
  uri:
    follow_redirects: "no"

But we can fix quite a few common cases by trying to switch "False" back
into the string that it was specified as.  We only do this if there is
only one correct choices value that could have been specified.  In the
follow_redirects example, a value of "True" only maps back to "yes" and
a value of "False" only maps back to "no" so we can do this.  If choices
also contained "on" and "off" then we couldn't map back safely and would
need to force the module author to change the module to handle this
case.

Fixes parts of the following PRs:

* ansible/ansible-modules-core#4220
* ansible/ansible-modules-extras#2593
@tmshn
Copy link
Author

tmshn commented Aug 5, 2016

@abadger Your strategy in ansible/ansible#16191 looks great! I'll wait it to be merged, and then revise this PR. Thus, this pended PR needs_revision now.

@tmshn
Copy link
Author

tmshn commented Aug 5, 2016

@gundalow

  1. _docker.py and _nova_compute are deprecated modules (they start with _)

You mean I don't need to (or should not) update these modules?

@gundalow
Copy link
Contributor

gundalow commented Aug 5, 2016

@tmshn Normally it doesn't make sense to update depreciated modules unless there is a major bug/security concern. People should be moving over to the newer modules.

abadger added a commit to ansible/ansible that referenced this pull request Aug 5, 2016
uri:
    follow_redirects: no

Will lead yaml to set follow_redirects=False.  This is problematic when
the module parameter is not a boolean value but a string.  For instance:

  follow_redirects = dict(required=False, default='safe', choices=['all', 'safe', 'none', 'yes', 'no']),

Our parameter validation code ends up getting follow_redirects="False"
instead of "no".  The 100% fix is for the user to quote their strings in
playbooks like:
  uri:
    follow_redirects: "no"

But we can fix quite a few common cases by trying to switch "False" back
into the string that it was specified as.  We only do this if there is
only one correct choices value that could have been specified.  In the
follow_redirects example, a value of "True" only maps back to "yes" and
a value of "False" only maps back to "no" so we can do this.  If choices
also contained "on" and "off" then we couldn't map back safely and would
need to force the module author to change the module to handle this
case.

Fixes parts of the following PRs:

* ansible/ansible-modules-core#4220
* ansible/ansible-modules-extras#2593
abadger added a commit to ansible/ansible that referenced this pull request Aug 5, 2016
uri:
    follow_redirects: no

Will lead yaml to set follow_redirects=False.  This is problematic when
the module parameter is not a boolean value but a string.  For instance:

  follow_redirects = dict(required=False, default='safe', choices=['all', 'safe', 'none', 'yes', 'no']),

Our parameter validation code ends up getting follow_redirects="False"
instead of "no".  The 100% fix is for the user to quote their strings in
playbooks like:
  uri:
    follow_redirects: "no"

But we can fix quite a few common cases by trying to switch "False" back
into the string that it was specified as.  We only do this if there is
only one correct choices value that could have been specified.  In the
follow_redirects example, a value of "True" only maps back to "yes" and
a value of "False" only maps back to "no" so we can do this.  If choices
also contained "on" and "off" then we couldn't map back safely and would
need to force the module author to change the module to handle this
case.

Fixes parts of the following PRs:

* ansible/ansible-modules-core#4220
* ansible/ansible-modules-extras#2593
(cherry picked from commit 6db6edf)
@gregdek
Copy link
Contributor

gregdek commented Aug 6, 2016

Thanks @tmshn for this PR. Unfortunately, it is not mergeable in its current state due to merge conflicts. Please rebase your PR. When you are done, please comment with text 'ready_for_review' and we will put this PR back into review.

For help on how to do this cleanly please see http://docs.ansible.com/ansible/community.html#contributing-code-features-or-bugfixes

[This message brought to you by your friendly Ansibull-bot.]

@abadger
Copy link
Contributor

abadger commented Aug 8, 2016

ansible/ansible#16191 has been merged. Good to continue on this one.

@tmshn
Copy link
Author

tmshn commented Aug 14, 2016

Thanks to @abadger's commit (and the advice from @gundalow that _nova_compute module is deprecated), this PR no longer has meaning. Closing.

@tmshn tmshn closed this Aug 14, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants