diff --git a/changelogs/fragments/77424-fix-False-ansible-galaxy-server-config-options.yaml b/changelogs/fragments/77424-fix-False-ansible-galaxy-server-config-options.yaml new file mode 100644 index 00000000000..15addbf9ce2 --- /dev/null +++ b/changelogs/fragments/77424-fix-False-ansible-galaxy-server-config-options.yaml @@ -0,0 +1,2 @@ +bugfixes: + - ansible-galaxy - Fix loading boolean server options so False doesn't become a truthy string (https://github.com/ansible/ansible/issues/77416). diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py index 8067dd9bb77..95f1230551a 100755 --- a/lib/ansible/cli/galaxy.py +++ b/lib/ansible/cli/galaxy.py @@ -62,14 +62,14 @@ display = Display() urlparse = six.moves.urllib.parse.urlparse SERVER_DEF = [ - ('url', True), - ('username', False), - ('password', False), - ('token', False), - ('auth_url', False), - ('v3', False), - ('validate_certs', False), - ('client_id', False), + ('url', True, 'str'), + ('username', False, 'str'), + ('password', False, 'str'), + ('token', False, 'str'), + ('auth_url', False, 'str'), + ('v3', False, 'bool'), + ('validate_certs', False, 'bool'), + ('client_id', False, 'str'), ] @@ -541,7 +541,7 @@ class GalaxyCLI(CLI): self.galaxy = Galaxy() - def server_config_def(section, key, required): + def server_config_def(section, key, required, option_type): return { 'description': 'The %s of the %s Galaxy server' % (key, section), 'ini': [ @@ -554,6 +554,7 @@ class GalaxyCLI(CLI): {'name': 'ANSIBLE_GALAXY_SERVER_%s_%s' % (section.upper(), key.upper())}, ], 'required': required, + 'type': option_type, } validate_certs_fallback = not context.CLIARGS['ignore_certs'] @@ -569,7 +570,7 @@ class GalaxyCLI(CLI): for server_priority, server_key in enumerate(server_list, start=1): # Config definitions are looked up dynamically based on the C.GALAXY_SERVER_LIST entry. We look up the # section [galaxy_server.] for the values url, username, password, and token. - config_dict = dict((k, server_config_def(server_key, k, req)) for k, req in SERVER_DEF) + config_dict = dict((k, server_config_def(server_key, k, req, ensure_type)) for k, req, ensure_type in SERVER_DEF) defs = AnsibleLoader(yaml_dump(config_dict)).get_single_data() C.config.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs) diff --git a/test/units/galaxy/test_collection.py b/test/units/galaxy/test_collection.py index 53d042fe602..6e87ed8c442 100644 --- a/test/units/galaxy/test_collection.py +++ b/test/units/galaxy/test_collection.py @@ -11,6 +11,7 @@ import os import pytest import re import tarfile +import tempfile import uuid from hashlib import sha256 @@ -203,7 +204,7 @@ def manifest(manifest_info): def server_config(monkeypatch): monkeypatch.setattr(C, 'GALAXY_SERVER_LIST', ['server1', 'server2', 'server3']) - default_options = dict((k, None) for k, v in SERVER_DEF) + default_options = dict((k, None) for k, v, t in SERVER_DEF) server1 = dict(default_options) server1.update({'url': 'https://galaxy.ansible.com/api/', 'validate_certs': False}) @@ -253,6 +254,71 @@ def test_cli_options(required_signature_count, valid, monkeypatch): galaxy_cli.run() +@pytest.mark.parametrize( + "config,server", + [ + ( + # Options to create ini config + { + 'url': 'https://galaxy.ansible.com', + 'validate_certs': 'False', + 'v3': 'False', + }, + # Expected server attributes + { + 'validate_certs': False, + '_available_api_versions': {}, + }, + ), + ( + { + 'url': 'https://galaxy.ansible.com', + 'validate_certs': 'True', + 'v3': 'True', + }, + { + 'validate_certs': True, + '_available_api_versions': {'v3': '/v3'}, + }, + ), + ], +) +def test_bool_type_server_config_options(config, server, monkeypatch): + cli_args = [ + 'ansible-galaxy', + 'collection', + 'install', + 'namespace.collection:1.0.0', + ] + + config_lines = [ + "[galaxy]", + "server_list=server1\n", + "[galaxy_server.server1]", + "url=%s" % config['url'], + "v3=%s" % config['v3'], + "validate_certs=%s\n" % config['validate_certs'], + ] + + with tempfile.NamedTemporaryFile(suffix='.cfg') as tmp_file: + tmp_file.write( + to_bytes('\n'.join(config_lines)) + ) + tmp_file.flush() + + with patch.object(C, 'GALAXY_SERVER_LIST', ['server1']): + with patch.object(C.config, '_config_file', tmp_file.name): + C.config._parse_config_file() + galaxy_cli = GalaxyCLI(args=cli_args) + mock_execute_install = MagicMock() + monkeypatch.setattr(galaxy_cli, '_execute_install_collection', mock_execute_install) + galaxy_cli.run() + + assert galaxy_cli.api_servers[0].name == 'server1' + assert galaxy_cli.api_servers[0].validate_certs == server['validate_certs'] + assert galaxy_cli.api_servers[0]._available_api_versions == server['_available_api_versions'] + + @pytest.mark.parametrize('global_ignore_certs', [True, False]) def test_validate_certs(global_ignore_certs, monkeypatch): cli_args = [