From 1f06d1bb9adbb77a5f4fe579abcc33cd7fb95773 Mon Sep 17 00:00:00 2001 From: Andrea Restle-Lay Date: Mon, 22 Sep 2025 15:27:47 -0400 Subject: [PATCH] [AAP-44277] License module now validates API responses for subscription IDs. (Moved from Tower) (#16096) * resolve bug and add simple unit tests * Update awx_collection/plugins/modules/license.py Co-authored-by: Andrew Potozniak --------- Co-authored-by: Andrew Potozniak --- awx_collection/plugins/modules/license.py | 13 ++++++-- .../test/awx/test_license_subscription.py | 32 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 awx_collection/test/awx/test_license_subscription.py diff --git a/awx_collection/plugins/modules/license.py b/awx_collection/plugins/modules/license.py index 5885e3f5de..69341e5bb3 100644 --- a/awx_collection/plugins/modules/license.py +++ b/awx_collection/plugins/modules/license.py @@ -67,6 +67,7 @@ EXAMPLES = ''' ''' import base64 + from ..module_utils.controller_api import ControllerAPIModule @@ -120,11 +121,17 @@ def main(): # Do the actual install, if we need to if perform_install: - json_output['changed'] = True if module.params.get('manifest', None): - module.post_endpoint('config', data={'manifest': manifest.decode()}) + response = module.post_endpoint('config', data={'manifest': manifest.decode()}) else: - module.post_endpoint('config/attach', data={'subscription_id': module.params.get('subscription_id')}) + response = module.post_endpoint('config/attach', data={'subscription_id': module.params.get('subscription_id')}) + + # Check API response for errors (AAP-44277 fix) + if response and response.get('status_code') and response.get('status_code') != 200: + error_msg = response.get('json', {}).get('error', 'License operation failed') + module.fail_json(msg=error_msg) + + json_output['changed'] = True module.exit_json(**json_output) diff --git a/awx_collection/test/awx/test_license_subscription.py b/awx_collection/test/awx/test_license_subscription.py new file mode 100644 index 0000000000..8e95d8846e --- /dev/null +++ b/awx_collection/test/awx/test_license_subscription.py @@ -0,0 +1,32 @@ +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import pytest + + +@pytest.mark.django_db +def test_license_invalid_subscription_id_should_fail(run_module, admin_user): + """Test invalid subscription ID returns failure.""" + result = run_module('license', {'subscription_id': 'invalid-test-12345', 'state': 'present'}, admin_user) + + assert result.get('failed', False) + assert 'msg' in result + assert 'subscription' in result['msg'].lower() + + +@pytest.mark.django_db +def test_license_invalid_manifest_should_fail(run_module, admin_user): + """Test invalid manifest returns failure.""" + result = run_module('license', {'manifest': '/nonexistent/test.zip', 'state': 'present'}, admin_user) + + assert result.get('failed', False) + assert 'msg' in result + + +@pytest.mark.django_db +def test_license_state_absent_works(run_module, admin_user): + """Test license removal works.""" + result = run_module('license', {'state': 'absent'}, admin_user) + + assert not result.get('failed', False)