Use the API task URI directly for polling collection imports (#85419)

pull/85496/head
Matt Martz 5 months ago committed by GitHub
parent 319dca2ea8
commit ee96f8e912
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,2 @@
bugfixes:
- ansible-galaxy - Use the provided import task url, instead of parsing to get the task id and reconstructing the URL

@ -689,10 +689,10 @@ class GalaxyAPI:
error_context_msg='Error when publishing collection to %s (%s)' error_context_msg='Error when publishing collection to %s (%s)'
% (self.name, self.api_server)) % (self.name, self.api_server))
return resp['task'] return urljoin(self.api_server, resp['task'])
@g_connect(['v2', 'v3']) @g_connect(['v2', 'v3'])
def wait_import_task(self, task_id, timeout=0): def wait_import_task(self, task_url, timeout=0):
""" """
Waits until the import process on the Galaxy server has completed or the timeout is reached. Waits until the import process on the Galaxy server has completed or the timeout is reached.
@ -703,22 +703,14 @@ class GalaxyAPI:
state = 'waiting' state = 'waiting'
data = None data = None
# Construct the appropriate URL per version display.display("Waiting until Galaxy import task %s has completed" % task_url)
if 'v3' in self.available_api_versions:
full_url = _urljoin(self.api_server, self.available_api_versions['v3'],
'imports/collections', task_id, '/')
else:
full_url = _urljoin(self.api_server, self.available_api_versions['v2'],
'collection-imports', task_id, '/')
display.display("Waiting until Galaxy import task %s has completed" % full_url)
start = time.time() start = time.time()
wait = C.GALAXY_COLLECTION_IMPORT_POLL_INTERVAL wait = C.GALAXY_COLLECTION_IMPORT_POLL_INTERVAL
while timeout == 0 or (time.time() - start) < timeout: while timeout == 0 or (time.time() - start) < timeout:
try: try:
data = self._call_galaxy(full_url, method='GET', auth_required=True, data = self._call_galaxy(task_url, method='GET', auth_required=True,
error_context_msg='Error when getting import task results at %s' % full_url) error_context_msg='Error when getting import task results at %s' % task_url)
except GalaxyError as e: except GalaxyError as e:
if e.http_code != 404: if e.http_code != 404:
raise raise
@ -740,7 +732,7 @@ class GalaxyAPI:
wait = min(30, wait * C.GALAXY_COLLECTION_IMPORT_POLL_FACTOR) wait = min(30, wait * C.GALAXY_COLLECTION_IMPORT_POLL_FACTOR)
if state == 'waiting': if state == 'waiting':
raise AnsibleError("Timeout while waiting for the Galaxy import process to finish, check progress at '%s'" raise AnsibleError("Timeout while waiting for the Galaxy import process to finish, check progress at '%s'"
% to_native(full_url)) % to_native(task_url))
for message in data.get('messages', []): for message in data.get('messages', []):
level = message['level'] level = message['level']
@ -754,7 +746,7 @@ class GalaxyAPI:
if state == 'failed': if state == 'failed':
code = to_native(data['error'].get('code', 'UNKNOWN')) code = to_native(data['error'].get('code', 'UNKNOWN'))
description = to_native( description = to_native(
data['error'].get('description', "Unknown error, see %s for more details" % full_url)) data['error'].get('description', "Unknown error, see %s for more details" % task_url))
raise AnsibleError("Galaxy import process failed: %s (Code: %s)" % (description, code)) raise AnsibleError("Galaxy import process failed: %s (Code: %s)" % (description, code))
@g_connect(['v2', 'v3']) @g_connect(['v2', 'v3'])

@ -623,24 +623,11 @@ def publish_collection(collection_path, api, wait, timeout):
import_uri = api.publish_collection(collection_path) import_uri = api.publish_collection(collection_path)
if wait: if wait:
# Galaxy returns a url fragment which differs between v2 and v3. The second to last entry is
# always the task_id, though.
# v2: {"task": "https://galaxy-dev.ansible.com/api/v2/collection-imports/35573/"}
# v3: {"task": "/api/automation-hub/v3/imports/collections/838d1308-a8f4-402c-95cb-7823f3806cd8/"}
task_id = None
for path_segment in reversed(import_uri.split('/')):
if path_segment:
task_id = path_segment
break
if not task_id:
raise AnsibleError("Publishing the collection did not return valid task info. Cannot wait for task status. Returned task info: '%s'" % import_uri)
with _display_progress( with _display_progress(
"Collection has been published to the Galaxy server " "Collection has been published to the Galaxy server "
"{api.name!s} {api.api_server!s}".format(api=api), "{api.name!s} {api.api_server!s}".format(api=api),
): ):
api.wait_import_task(task_id, timeout) api.wait_import_task(import_uri, timeout)
display.display("Collection has been successfully published and imported to the Galaxy server %s %s" display.display("Collection has been successfully published and imported to the Galaxy server %s %s"
% (api.name, api.api_server)) % (api.name, api.api_server))
else: else:

@ -451,15 +451,13 @@ def test_publish_failure(api_version, collection_url, response, expected, collec
api.publish_collection(collection_artifact) api.publish_collection(collection_artifact)
@pytest.mark.parametrize('server_url, api_version, token_type, token_ins, import_uri, full_import_uri', [ @pytest.mark.parametrize('server_url, api_version, token_type, token_ins, full_import_uri', [
('https://galaxy.server.com/api', 'v2', 'Token', GalaxyToken('my token'), ('https://galaxy.server.com/api', 'v2', 'Token', GalaxyToken('my token'),
'1234',
'https://galaxy.server.com/api/v2/collection-imports/1234/'), 'https://galaxy.server.com/api/v2/collection-imports/1234/'),
('https://galaxy.server.com/api/automation-hub/', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'), ('https://galaxy.server.com/api/automation-hub/', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'),
'1234',
'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'), 'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'),
]) ])
def test_wait_import_task(server_url, api_version, token_type, token_ins, import_uri, full_import_uri, monkeypatch): def test_wait_import_task(server_url, api_version, token_type, token_ins, full_import_uri, monkeypatch):
api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins) api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins)
mock_token_get = MagicMock() mock_token_get = MagicMock()
@ -473,7 +471,7 @@ def test_wait_import_task(server_url, api_version, token_type, token_ins, import
mock_display = MagicMock() mock_display = MagicMock()
monkeypatch.setattr(Display, 'display', mock_display) monkeypatch.setattr(Display, 'display', mock_display)
api.wait_import_task(import_uri) api.wait_import_task(full_import_uri)
assert mock_open.call_count == 1 assert mock_open.call_count == 1
assert mock_open.mock_calls[0][1][0] == full_import_uri assert mock_open.mock_calls[0][1][0] == full_import_uri
@ -483,15 +481,13 @@ def test_wait_import_task(server_url, api_version, token_type, token_ins, import
assert mock_display.mock_calls[0][1][0] == 'Waiting until Galaxy import task %s has completed' % full_import_uri assert mock_display.mock_calls[0][1][0] == 'Waiting until Galaxy import task %s has completed' % full_import_uri
@pytest.mark.parametrize('server_url, api_version, token_type, token_ins, import_uri, full_import_uri', [ @pytest.mark.parametrize('server_url, api_version, token_type, token_ins, full_import_uri', [
('https://galaxy.server.com/api/', 'v2', 'Token', GalaxyToken('my token'), ('https://galaxy.server.com/api/', 'v2', 'Token', GalaxyToken('my token'),
'1234',
'https://galaxy.server.com/api/v2/collection-imports/1234/'), 'https://galaxy.server.com/api/v2/collection-imports/1234/'),
('https://galaxy.server.com/api/automation-hub', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'), ('https://galaxy.server.com/api/automation-hub', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'),
'1234',
'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'), 'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'),
]) ])
def test_wait_import_task_multiple_requests(server_url, api_version, token_type, token_ins, import_uri, full_import_uri, monkeypatch): def test_wait_import_task_multiple_requests(server_url, api_version, token_type, token_ins, full_import_uri, monkeypatch):
api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins) api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins)
mock_token_get = MagicMock() mock_token_get = MagicMock()
@ -513,7 +509,7 @@ def test_wait_import_task_multiple_requests(server_url, api_version, token_type,
monkeypatch.setattr(time, 'sleep', MagicMock()) monkeypatch.setattr(time, 'sleep', MagicMock())
api.wait_import_task(import_uri) api.wait_import_task(full_import_uri)
assert mock_open.call_count == 2 assert mock_open.call_count == 2
assert mock_open.mock_calls[0][1][0] == full_import_uri assert mock_open.mock_calls[0][1][0] == full_import_uri
@ -529,15 +525,13 @@ def test_wait_import_task_multiple_requests(server_url, api_version, token_type,
'Galaxy import process has a status of test, wait 2 seconds before trying again' 'Galaxy import process has a status of test, wait 2 seconds before trying again'
@pytest.mark.parametrize('server_url, api_version, token_type, token_ins, import_uri, full_import_uri,', [ @pytest.mark.parametrize('server_url, api_version, token_type, token_ins, full_import_uri,', [
('https://galaxy.server.com/api/', 'v2', 'Token', GalaxyToken('my token'), ('https://galaxy.server.com/api/', 'v2', 'Token', GalaxyToken('my token'),
'1234',
'https://galaxy.server.com/api/v2/collection-imports/1234/'), 'https://galaxy.server.com/api/v2/collection-imports/1234/'),
('https://galaxy.server.com/api/automation-hub/', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'), ('https://galaxy.server.com/api/automation-hub/', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'),
'1234',
'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'), 'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'),
]) ])
def test_wait_import_task_with_failure(server_url, api_version, token_type, token_ins, import_uri, full_import_uri, monkeypatch): def test_wait_import_task_with_failure(server_url, api_version, token_type, token_ins, full_import_uri, monkeypatch):
api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins) api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins)
mock_token_get = MagicMock() mock_token_get = MagicMock()
@ -586,7 +580,7 @@ def test_wait_import_task_with_failure(server_url, api_version, token_type, toke
expected = to_native(u'Galaxy import process failed: Becäuse I said so! (Code: GW001)') expected = to_native(u'Galaxy import process failed: Becäuse I said so! (Code: GW001)')
with pytest.raises(AnsibleError, match=re.escape(expected)): with pytest.raises(AnsibleError, match=re.escape(expected)):
api.wait_import_task(import_uri) api.wait_import_task(full_import_uri)
assert mock_open.call_count == 1 assert mock_open.call_count == 1
assert mock_open.mock_calls[0][1][0] == full_import_uri assert mock_open.mock_calls[0][1][0] == full_import_uri
@ -605,15 +599,13 @@ def test_wait_import_task_with_failure(server_url, api_version, token_type, toke
assert mock_err.mock_calls[0][1][0] == u'Galaxy import error message: Somé error' assert mock_err.mock_calls[0][1][0] == u'Galaxy import error message: Somé error'
@pytest.mark.parametrize('server_url, api_version, token_type, token_ins, import_uri, full_import_uri', [ @pytest.mark.parametrize('server_url, api_version, token_type, token_ins, full_import_uri', [
('https://galaxy.server.com/api/', 'v2', 'Token', GalaxyToken('my_token'), ('https://galaxy.server.com/api/', 'v2', 'Token', GalaxyToken('my_token'),
'1234',
'https://galaxy.server.com/api/v2/collection-imports/1234/'), 'https://galaxy.server.com/api/v2/collection-imports/1234/'),
('https://galaxy.server.com/api/automation-hub/', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'), ('https://galaxy.server.com/api/automation-hub/', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'),
'1234',
'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'), 'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'),
]) ])
def test_wait_import_task_with_failure_no_error(server_url, api_version, token_type, token_ins, import_uri, full_import_uri, monkeypatch): def test_wait_import_task_with_failure_no_error(server_url, api_version, token_type, token_ins, full_import_uri, monkeypatch):
api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins) api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins)
mock_token_get = MagicMock() mock_token_get = MagicMock()
@ -658,7 +650,7 @@ def test_wait_import_task_with_failure_no_error(server_url, api_version, token_t
expected = 'Galaxy import process failed: Unknown error, see %s for more details \\(Code: UNKNOWN\\)' % full_import_uri expected = 'Galaxy import process failed: Unknown error, see %s for more details \\(Code: UNKNOWN\\)' % full_import_uri
with pytest.raises(AnsibleError, match=expected): with pytest.raises(AnsibleError, match=expected):
api.wait_import_task(import_uri) api.wait_import_task(full_import_uri)
assert mock_open.call_count == 1 assert mock_open.call_count == 1
assert mock_open.mock_calls[0][1][0] == full_import_uri assert mock_open.mock_calls[0][1][0] == full_import_uri
@ -677,15 +669,13 @@ def test_wait_import_task_with_failure_no_error(server_url, api_version, token_t
assert mock_err.mock_calls[0][1][0] == u'Galaxy import error message: Somé error' assert mock_err.mock_calls[0][1][0] == u'Galaxy import error message: Somé error'
@pytest.mark.parametrize('server_url, api_version, token_type, token_ins, import_uri, full_import_uri', [ @pytest.mark.parametrize('server_url, api_version, token_type, token_ins, full_import_uri', [
('https://galaxy.server.com/api', 'v2', 'Token', GalaxyToken('my token'), ('https://galaxy.server.com/api', 'v2', 'Token', GalaxyToken('my token'),
'1234',
'https://galaxy.server.com/api/v2/collection-imports/1234/'), 'https://galaxy.server.com/api/v2/collection-imports/1234/'),
('https://galaxy.server.com/api/automation-hub', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'), ('https://galaxy.server.com/api/automation-hub', 'v3', 'Bearer', KeycloakToken(auth_url='https://api.test/'),
'1234',
'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'), 'https://galaxy.server.com/api/automation-hub/v3/imports/collections/1234/'),
]) ])
def test_wait_import_task_timeout(server_url, api_version, token_type, token_ins, import_uri, full_import_uri, monkeypatch): def test_wait_import_task_timeout(server_url, api_version, token_type, token_ins, full_import_uri, monkeypatch):
api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins) api = get_test_galaxy_api(server_url, api_version, token_ins=token_ins)
mock_token_get = MagicMock() mock_token_get = MagicMock()
@ -709,7 +699,7 @@ def test_wait_import_task_timeout(server_url, api_version, token_type, token_ins
expected = "Timeout while waiting for the Galaxy import process to finish, check progress at '%s'" % full_import_uri expected = "Timeout while waiting for the Galaxy import process to finish, check progress at '%s'" % full_import_uri
with pytest.raises(AnsibleError, match=expected): with pytest.raises(AnsibleError, match=expected):
api.wait_import_task(import_uri, 1) api.wait_import_task(full_import_uri, 1)
assert mock_open.call_count > 1 assert mock_open.call_count > 1
assert mock_open.mock_calls[0][1][0] == full_import_uri assert mock_open.mock_calls[0][1][0] == full_import_uri

@ -884,7 +884,7 @@ def test_publish_with_wait(galaxy_server, collection_artifact, monkeypatch):
assert mock_publish.mock_calls[0][1][0] == artifact_path assert mock_publish.mock_calls[0][1][0] == artifact_path
assert mock_wait.call_count == 1 assert mock_wait.call_count == 1
assert mock_wait.mock_calls[0][1][0] == '1234' assert mock_wait.mock_calls[0][1][0] == fake_import_uri
assert mock_display.mock_calls[0][1][0] == "Collection has been published to the Galaxy server test_server %s" \ assert mock_display.mock_calls[0][1][0] == "Collection has been published to the Galaxy server test_server %s" \
% galaxy_server.api_server % galaxy_server.api_server

Loading…
Cancel
Save