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

The module awx.awx.inventory is failing to create constructed inventories - Edge case uncaught #15310

Closed
5 of 11 tasks
cnfrancis opened this issue Jun 28, 2024 · 3 comments
Closed
5 of 11 tasks
Labels
community component:awx_collection issues related to the collection for controlling AWX needs_triage type:bug

Comments

@cnfrancis
Copy link

cnfrancis commented Jun 28, 2024

Please confirm the following

  • I agree to follow this project's code of conduct.
  • I have checked the current issues for duplicates.
  • I understand that AWX is open source software provided for free and that I might not receive a timely response.
  • I am NOT reporting a (potential) security vulnerability. (These should be emailed to [email protected] instead.)

Bug Summary

Edge Case

hello, I believe there is an edge case uncaught with the module awx.awx.inventory when attempting to add an input_inventories which causes the error message below:

“msg”: “The requested object could not be found at /api/v2/constructed_inventories/24/input_inventories/” 

It's due to the fact the URL built is wrong when adding an associations of type input_inventories to a resource constructed_inventory

Related discussion: https://forum.ansible.com/t/awx-awx-inventory-is-failing-to-create-constructed-inventories-potential-edge-case/6845

Problematic Code Snippets

I believe the problematic code that caused the URL to be built wrong and cause the 404 to happen is combination of the snippets below in awx/awx_collection/plugins/module_utils/controller_api.py

# awx/awx_collection/plugins/module_utils/controller_api.py
def create_if_needed(self, existing_item, new_item, endpoint, on_create=None, auto_exit=True, item_type='unknown', associations=None):

...

            if response['status_code'] in [200, 201]:
                self.json_output['name'] = 'unknown'
                for key in ('name', 'username', 'identifier', 'hostname'):
                    if key in response['json']:
                        self.json_output['name'] = response['json'][key]
                self.json_output['id'] = response['json']['id']
                self.json_output['changed'] = True
                item_url = response['json']['url']
            else:
                if 'json' in response and '__all__' in response['json']:
                    self.fail_json(msg="Unable to create {0} {1}: {2}".format(item_type, item_name, response['json']['__all__'][0]))
                elif 'json' in response:
                    self.fail_json(msg="Unable to create {0} {1}: {2}".format(item_type, item_name, response['json']))
                else:
                    self.fail_json(msg="Unable to create {0} {1}: {2}".format(item_type, item_name, response['status_code']))

        # Process any associations with this item
        if associations is not None:
            for association_type in associations:
                sub_endpoint = '{0}{1}/'.format(item_url, association_type)
                self.modify_associations(sub_endpoint, associations[association_type])

and

# awx/awx_collection/plugins/module_utils/controller_api.py
    def modify_associations(self, association_endpoint, new_association_list):
        # if we got None instead of [] we are not modifying the association_list
        if new_association_list is None:
            return

        # First get the existing associations
        response = self.get_all_endpoint(association_endpoint)
        existing_associated_ids = [association['id'] for association in response['json']['results']]

Explanation

In ControllerAPIModule.create_if_needed(self) (code ref link)

The url and the body for the POST call

'https://<REDACTED>.com/api/v2/inventories/'
'{"name": "REDACTED", "organization": 2, "kind": "constructed", "host_filter": null, "input_inventories": [2]}'

will yield the successful response

response['json']['url'] = /api/v2/constructed_inventories/<id>

this is then stored in item_url which used to build the association sub_endpoint (code ref link)

`sub_endpoint=/api/v2/constructed_inventories//input_inventories

        if associations is not None:
            for association_type in associations:
                sub_endpoint = '{0}{1}/'.format(item_url, association_type)
                self.modify_associations(sub_endpoint, associations[association_type])

then later on, when self.get_all_endpoint(association_endpoint) which calls response = self.get_endpoint(endpoint, *args, **kwargs) with this /api/v2/constructed_inventories/<id>/input_inventories it will cause the 404 as that enpoint isn't defined.

 def modify_associations(self, association_endpoint, new_association_list):
        # if we got None instead of [] we are not modifying the association_list
        if new_association_list is None:
            return

        # First get the existing associations
        response = self.get_all_endpoint(association_endpoint)
        existing_associated_ids = [association['id'] for association in response['json']['results']]

Hope this makes sense. Please let me know what the action items are from this, or suggested course of action I can take.

FYI @TheRealHaoLiu @relrod (@cidrblock fom AnsibleFest 2024 conference Denver, US )

AWX version

22.0.0

Select the relevant components

  • UI
  • UI (tech preview)
  • API
  • Docs
  • Collection
  • CLI
  • Other

Installation method

kubernetes

Modifications

no

Ansible version

2.17.1

Operating system

No response

Web browser

No response

Steps to reproduce

  • ANSIBLE_KEEP_REMOTE_FILES=1 ansible localhost -m awx.awx.inventory -a '<module_args>' -vvv
  • cd /path/to/temporary/file
  • python AnsiballZ_inventory.py explode
  • python AnsiballZ_inventory.py execute

this assumes an inventory already exists when added to the input_inventory field.
used arguments:

{
    "ANSIBLE_MODULE_ARGS": {
        "_ansible_check_mode": false,
        "_ansible_debug": false,
        "_ansible_diff": false,
        "_ansible_ignore_unknown_opts": false,
        "_ansible_keep_remote_files": true,
        "_ansible_module_name": "awx.awx.inventory",
        "_ansible_no_log": false,
        "_ansible_remote_tmp": "~/.ansible/tmp",
        "_ansible_selinux_special_fs": [
            "fuse",
            "nfs",
            "vboxsf",
            "ramfs",
            "9p",
            "vfat"
        ],
        "_ansible_shell_executable": "/bin/sh",
        "_ansible_socket": null,
        "_ansible_string_conversion_action": "warn",
        "_ansible_syslog_facility": "LOG_USER",
        "_ansible_target_log_info": null,
        "_ansible_tmpdir": "REDACTED",
        "_ansible_verbosity": 3,
        "_ansible_version": "2.17.1",
        "controller_host": "REDACTED",
        "input_inventories": [
            "REDACTED"
        ],
        "organization": "REDACTED",
        "kind": "constructed",
        "name": "REDACTED",        
        "controller_username": "REDACTED",        
        "controller_password": "REDACTED"
    }
}

Expected results

The built URL should be inventories/<id>/input_inventories when adding association of type input_inventories to a construced_inventory

Actual results

“msg”: “The requested object could not be found at /api/v2/constructed_inventories/24/input_inventories/”

Additional information

#13448
Commit: e22967d

@github-actions github-actions bot added component:awx_collection issues related to the collection for controlling AWX needs_triage type:bug community labels Jun 28, 2024
@Denney-tech
Copy link

I think this might actually be a duplicate of #13781 and resolved by #13797. Please upgrade to AWX >= 22.1.0 and test again.

@Denney-tech
Copy link

@cnfrancis confirmed upgrading resolved the issue. This issue can be closed.

@thedoubl3j
Copy link
Member

@cnfrancis we are going to close this per @Denney-tech comment (thank you). If this issue persists, please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community component:awx_collection issues related to the collection for controlling AWX needs_triage type:bug
Projects
None yet
Development

No branches or pull requests

3 participants