ansible / awx

AWX provides a web-based user interface, REST API, and task engine built on top of Ansible. It is one of the upstream projects for Red Hat Ansible Automation Platform.
Other
14.04k stars 3.42k forks source link

If value is false or true - it registers a change when there isn't one #13405

Closed davidcba1 closed 1 year ago

davidcba1 commented 1 year ago

Please confirm the following

Bug Summary

Raised this originally here https://github.com/redhat-cop/controller_configuration/issues/459 but as suggested by them raising here.

Ansible is supposed to be idempotent, yet when you provide a setting with the value of true or false it registers a change in ansible

controller_settings:
  - name: LOG_AGGREGATOR_ENABLED
    value: 0  # False - If set to False it changes every run

This is by utilising the 2 roles of the below, but applies even if you just use the settings role in the repo

  roles:
    - {role: redhat_cop.controller_configuration.filetree_read }
    - {role: redhat_cop.controller_configuration.dispatch }

AWX version

Ansible Automation Platform 2.2 - Supported/Paid version

Select the relevant components

Installation method

N/A

Modifications

no

Ansible version

ansible [core 2.13.7]

Operating system

Execution Env - 2.2-supported

Web browser

No response

Steps to reproduce

Using the roles noted above, perform some basic config change like the below

Try setting to False/false and you will notice a change every time.

Expected results

when defining your vars - regardless if you have True, true or 1 - it should not register a change

same for False, false, 0

ok: [xxxx] => (item={'failed': 0, 'started': 1, 'finished': 0, 'ansible_job_id': '66363845749.2967878', 'results_file': '/tmp/.ansible_async/66363845749.2967878', 'changed': False, '__controller_setting_item': {'name': 'ORG_ADMINS_CAN_SEE_ALL_USERS', 'value': 0}, 'ansible_loop_var': '__controller_setting_item'}) => {"__controller_setting_job_async_results_item": {"__controller_setting_item": {"name": "ORG_ADMINS_CAN_SEE_ALL_USERS", "value": 0}, "ansible_job_id": "66363845749.2967878", "ansible_loop_var": "__controller_setting_item", "changed": false, "failed": 0, "finished": 0, "results_file": "/tmp/.ansible_async/66363845749.2967878", "started": 1}, "ansible_job_id": "66363845749.2967878", "ansible_loop_var": "__controller_setting_job_async_results_item", "attempts": 1, "changed": false, "finished": 1, "new_values": {}, "old_values": {}, "results_file": "/tmp/.ansible_async/66363845749.2967878", "started": 1, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

Actual results

changed: [xxxx] => (item={'failed': 0, 'started': 1, 'finished': 0, 'ansible_job_id': '198060949819.2965323', 'results_file': '/tmp/.ansible_async/198060949819.2965323', 'changed': False, '__controller_setting_item': {'name': 'ORG_ADMINS_CAN_SEE_ALL_USERS', 'value': False}, 'ansible_loop_var': '__controller_setting_item'}) => {"__controller_setting_job_async_results_item": {"__controller_setting_item": {"name": "ORG_ADMINS_CAN_SEE_ALL_USERS", "value": false}, "ansible_job_id": "198060949819.2965323", "ansible_loop_var": "__controller_setting_item", "changed": false, "failed": 0, "finished": 0, "results_file": "/tmp/.ansible_async/198060949819.2965323", "started": 1}, "ansible_job_id": "198060949819.2965323", "ansible_loop_var": "__controller_setting_job_async_results_item", "attempts": 1, "changed": true, "finished": 1, "new_values": {"ORG_ADMINS_CAN_SEE_ALL_USERS": "False"}, "old_values": {"ORG_ADMINS_CAN_SEE_ALL_USERS": false}, "results_file": "/tmp/.ansible_async/198060949819.2965323", "started": 1, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [], "value": false}

Additional information

# ansible --version
ansible [core 2.13.7]
  config file = /home/adm/aap/ansible-automation-platform/ansible.cfg
  configured module search path = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/adm/aap/ansible-automation-platform/collections:/home/runner/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.13 (main, Nov  9 2022, 13:16:24) [GCC 8.5.0 20210514 (Red Hat 8.5.0-15)]
  jinja version = 3.0.3
  libyaml = True

# ansible-galaxy collection list

# /usr/share/ansible/collections/ansible_collections
Collection              Version
----------------------- -------
amazon.aws              3.2.0
ansible.controller      4.2.1
ansible.netcommon       3.1.1
ansible.network         1.2.0
ansible.posix           1.3.0
ansible.security        1.0.0
ansible.utils           2.6.1
ansible.windows         1.9.0
ansible.yang            1.0.0
arista.eos              5.0.0
cisco.asa               3.0.0
cisco.ios               3.0.0
cisco.iosxr             3.0.0
cisco.nxos              3.0.0
cloud.common            2.1.1
community.crypto        2.1.0
community.general       4.2.0
community.hashi_vault   4.0.0
frr.frr                 2.0.0
ibm.qradar              2.0.0
junipernetworks.junos   3.0.0
kubernetes.core         2.2.3
openvswitch.openvswitch 2.1.0
redhat.insights         1.0.7
redhat.openshift        2.1.0
redhat.rhv              1.6.5
redhat.satellite        3.3.0
servicenow.itsm         1.3.3
splunk.es               2.0.0
trendmicro.deepsec      2.0.0
vmware.vmware_rest      2.1.5
vyos.vyos               3.0.0

# /home/adm/aap/ansible-automation-platform/collections/ansible_collections
Collection                          Version
----------------------------------- -------
redhat_cop.controller_configuration 2.2.4

Controller version
2.2
john-westcott-iv commented 1 year ago

You can kind of see what is going on if you pass in a couple of -vs, In the case of the 0 you get this:

ok: [localhost] => {
    "changed": false,
    "invocation": {
        "module_args": {
            "controller_config_file": null,
            "controller_host": "https://localhost:8043",
            "controller_oauthtoken": null,
            "controller_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "controller_username": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "name": "LOG_AGGREGATOR_ENABLED",
            "settings": null,
            "validate_certs": false,
            "value": "0"
        }
    },
    "new_values": {},
    "old_values": {}
}

In the case of False you get this:

changed: [localhost] => {
    "changed": true,
    "invocation": {
        "module_args": {
            "controller_config_file": null,
            "controller_host": "https://localhost:8043",
            "controller_oauthtoken": null,
            "controller_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "controller_username": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "name": "LOG_AGGREGATOR_ENABLED",
            "settings": null,
            "validate_certs": false,
            "value": "False"
        }
    },
    "new_values": {
        "LOG_AGGREGATOR_ENABLED": "False"
    },
    "old_values": {
        "LOG_AGGREGATOR_ENABLED": false
    },
    "value": false
}

We may have to change the way that boolean settings are handled inside of this module.

john-westcott-iv commented 1 year ago

We do some coercion of the settings that we are getting from users with this function: https://github.com/ansible/awx/blob/devel/awx_collection/plugins/modules/settings.py#L82

But then don't try and do any coercion on the values we are getting from the settings page: https://github.com/ansible/awx/blob/devel/awx_collection/plugins/modules/settings.py#L137

So we maybe comparing a string to a bool or something along those lines.

AlanCoding commented 1 year ago

Closing as duplicate of https://github.com/ansible/awx/issues/14487

It is suggested to use:

    - name: SET AWX EXPOSE HOST PATHS
      awx.awx.settings:
        settings:
          AWX_MOUNT_ISOLATED_PATHS_ON_K8S: true
      register: this_setting

The dictionary-type parameter allows us to preserve type. The problem is impossible with the "value" parameter, and we should remove it.