ansible-galaxy - expand User-Agent string for Galaxy endpoints (#65578)

This commit is contained in:
Jordan Borean 2019-12-06 10:34:14 +10:00 committed by GitHub
parent fcdebe41e9
commit eaba5572cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 63 additions and 10 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- ansible-galaxy - Expand the ``User-Agent`` to include more information and add it to more calls to Galaxy endpoints.

View file

@ -13,7 +13,7 @@ import time
from ansible import context
from ansible.errors import AnsibleError
from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.galaxy.user_agent import user_agent
from ansible.module_utils.six import string_types
from ansible.module_utils.six.moves.urllib.error import HTTPError
from ansible.module_utils.six.moves.urllib.parse import quote as urlquote, urlencode, urlparse
@ -185,7 +185,7 @@ class GalaxyAPI:
try:
display.vvvv("Calling Galaxy at %s" % url)
resp = open_url(to_native(url), data=args, validate_certs=self.validate_certs, headers=headers,
method=method, timeout=20, http_agent='ansible-galaxy/%s' % ansible_version)
method=method, timeout=20, http_agent=user_agent())
except HTTPError as e:
raise GalaxyError(e, error_context_msg)
except Exception as e:
@ -219,7 +219,7 @@ class GalaxyAPI:
"""
url = _urljoin(self.api_server, self.available_api_versions['v1'], "tokens") + '/'
args = urlencode({"github_token": github_token})
resp = open_url(url, data=args, validate_certs=self.validate_certs, method="POST")
resp = open_url(url, data=args, validate_certs=self.validate_certs, method="POST", http_agent=user_agent())
data = json.loads(to_text(resp.read(), errors='surrogate_or_strict'))
return data

View file

@ -31,9 +31,9 @@ import ansible.constants as C
from ansible.errors import AnsibleError
from ansible.galaxy import get_collections_galaxy_meta_info
from ansible.galaxy.api import CollectionVersionMetadata, GalaxyError
from ansible.galaxy.user_agent import user_agent
from ansible.module_utils import six
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.utils.collection_loader import AnsibleCollectionRef
from ansible.utils.display import Display
from ansible.utils.hashing import secure_hash, secure_hash_s
@ -877,7 +877,7 @@ def _download_file(url, b_path, expected_hash, validate_certs, headers=None):
display.vvv("Downloading %s to %s" % (url, to_text(b_path)))
# Galaxy redirs downloads to S3 which reject the request if an Authorization header is attached so don't redir that
resp = open_url(to_native(url, errors='surrogate_or_strict'), validate_certs=validate_certs, headers=headers,
unredirected_headers=['Authorization'], http_agent='ansible-galaxy/%s' % ansible_version)
unredirected_headers=['Authorization'], http_agent=user_agent())
with open(b_file_path, 'wb') as download_file:
data = resp.read(bufsize)

View file

@ -27,6 +27,7 @@ import json
from ansible import context
from ansible.errors import AnsibleError
from ansible.galaxy.user_agent import user_agent
from ansible.module_utils.six.moves import input
from ansible.module_utils.six.moves.urllib.error import HTTPError
from ansible.module_utils.urls import open_url
@ -80,7 +81,7 @@ class GalaxyLogin(object):
try:
tokens = json.load(open_url(self.GITHUB_AUTH, url_username=self.github_username,
url_password=self.github_password, force_basic_auth=True,
validate_certs=self._validate_certs))
validate_certs=self._validate_certs, http_agent=user_agent()))
except HTTPError as e:
res = json.load(e)
raise AnsibleError(res['message'])
@ -91,7 +92,7 @@ class GalaxyLogin(object):
try:
open_url('https://api.github.com/authorizations/%d' % token['id'],
url_username=self.github_username, url_password=self.github_password, method='DELETE',
force_basic_auth=True, validate_certs=self._validate_certs)
force_basic_auth=True, validate_certs=self._validate_certs, http_agent=user_agent())
except HTTPError as e:
res = json.load(e)
raise AnsibleError(res['message'])
@ -105,7 +106,7 @@ class GalaxyLogin(object):
try:
data = json.load(open_url(self.GITHUB_AUTH, url_username=self.github_username,
url_password=self.github_password, force_basic_auth=True, data=args,
validate_certs=self._validate_certs))
validate_certs=self._validate_certs, http_agent=user_agent()))
except HTTPError as e:
res = json.load(e)
raise AnsibleError(res['message'])

View file

@ -33,6 +33,7 @@ from shutil import rmtree
from ansible import context
from ansible.errors import AnsibleError
from ansible.galaxy.user_agent import user_agent
from ansible.module_utils._text import to_native, to_text
from ansible.module_utils.urls import open_url
from ansible.playbook.role.requirement import RoleRequirement
@ -179,7 +180,7 @@ class GalaxyRole(object):
display.display("- downloading role from %s" % archive_url)
try:
url_file = open_url(archive_url, validate_certs=self._validate_certs)
url_file = open_url(archive_url, validate_certs=self._validate_certs, http_agent=user_agent())
temp_file = tempfile.NamedTemporaryFile(delete=False)
data = url_file.read()
while data:

View file

@ -29,6 +29,7 @@ from stat import S_IRUSR, S_IWUSR
import yaml
from ansible import constants as C
from ansible.galaxy.user_agent import user_agent
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils.urls import open_url
from ansible.utils.display import Display
@ -76,7 +77,8 @@ class KeycloakToken(object):
resp = open_url(to_native(self.auth_url),
data=payload,
validate_certs=self.validate_certs,
method='POST')
method='POST',
http_agent=user_agent())
# TODO: handle auth errors

View file

@ -0,0 +1,23 @@
# Copyright: (c) 2019, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import platform
import sys
from ansible.module_utils.ansible_release import __version__ as ansible_version
def user_agent():
"""Returns a user agent used by ansible-galaxy to include the Ansible version, platform and python version."""
python_version = sys.version_info
return u"ansible-galaxy/{ansible_version} ({platform}; python:{py_major}.{py_minor}.{py_micro})".format(
ansible_version=ansible_version,
platform=platform.system(),
py_major=python_version.major,
py_minor=python_version.minor,
py_micro=python_version.micro,
)

View file

@ -158,7 +158,9 @@ def test_initialise_galaxy(monkeypatch):
assert actual == {u'token': u'my token'}
assert mock_open.call_count == 2
assert mock_open.mock_calls[0][1][0] == 'https://galaxy.ansible.com/api/'
assert 'ansible-galaxy' in mock_open.mock_calls[0][2]['http_agent']
assert mock_open.mock_calls[1][1][0] == 'https://galaxy.ansible.com/api/v1/tokens/'
assert 'ansible-galaxy' in mock_open.mock_calls[1][2]['http_agent']
assert mock_open.mock_calls[1][2]['data'] == 'github_token=github_token'
@ -179,7 +181,9 @@ def test_initialise_galaxy_with_auth(monkeypatch):
assert actual == {u'token': u'my token'}
assert mock_open.call_count == 2
assert mock_open.mock_calls[0][1][0] == 'https://galaxy.ansible.com/api/'
assert 'ansible-galaxy' in mock_open.mock_calls[0][2]['http_agent']
assert mock_open.mock_calls[1][1][0] == 'https://galaxy.ansible.com/api/v1/tokens/'
assert 'ansible-galaxy' in mock_open.mock_calls[1][2]['http_agent']
assert mock_open.mock_calls[1][2]['data'] == 'github_token=github_token'
@ -201,6 +205,7 @@ def test_initialise_automation_hub(monkeypatch):
assert api.available_api_versions['v3'] == u'v3/'
assert mock_open.mock_calls[0][1][0] == 'https://galaxy.ansible.com/api/'
assert 'ansible-galaxy' in mock_open.mock_calls[0][2]['http_agent']
assert mock_open.mock_calls[0][2]['headers'] == {'Authorization': 'Bearer my_token'}
@ -235,6 +240,7 @@ def test_get_available_api_versions(monkeypatch):
assert mock_open.call_count == 1
assert mock_open.mock_calls[0][1][0] == 'https://galaxy.ansible.com/api/'
assert 'ansible-galaxy' in mock_open.mock_calls[0][2]['http_agent']
def test_publish_collection_missing_file():

View file

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import platform
from ansible.galaxy import user_agent
from ansible.module_utils.ansible_release import __version__ as ansible_version
def test_user_agent():
res = user_agent.user_agent()
assert res.startswith('ansible-galaxy/%s' % ansible_version)
assert platform.system() in res
assert 'python:' in res