mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[8.12] [Fleet] Fix 500 in Fleet API when request to product versions endpoint throws ECONNREFUSED (#172850) (#172865)
# Backport This will backport the following commits from `main` to `8.12`: - [[Fleet] Fix 500 in Fleet API when request to product versions endpoint throws ECONNREFUSED (#172850)](https://github.com/elastic/kibana/pull/172850) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Kyle Pollich","email":"kyle.pollich@elastic.co"},"sourceCommit":{"committedDate":"2023-12-07T18:14:35Z","message":"[Fleet] Fix 500 in Fleet API when request to product versions endpoint throws ECONNREFUSED (#172850)\n\n## Summary\r\n\r\nNetwork-level errors will cause `fetch` to `throw` rather than resolving\r\nwith a status code. This PR updates our logic to handle this case for\r\nairgapped environments where `ECONNREFUSED` style errors squash HTTP\r\nrequests at the DNS level.","sha":"be6fbc4dcc8fff7e7419cf3fa9b05a6b13e3edba","branchLabelMapping":{"^v8.13.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Fleet","backport:prev-minor","v8.12.0","v8.13.0","v8.11.3"],"number":172850,"url":"https://github.com/elastic/kibana/pull/172850","mergeCommit":{"message":"[Fleet] Fix 500 in Fleet API when request to product versions endpoint throws ECONNREFUSED (#172850)\n\n## Summary\r\n\r\nNetwork-level errors will cause `fetch` to `throw` rather than resolving\r\nwith a status code. This PR updates our logic to handle this case for\r\nairgapped environments where `ECONNREFUSED` style errors squash HTTP\r\nrequests at the DNS level.","sha":"be6fbc4dcc8fff7e7419cf3fa9b05a6b13e3edba"}},"sourceBranch":"main","suggestedTargetBranches":["8.12","8.11"],"targetPullRequestStates":[{"branch":"8.12","label":"v8.12.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.13.0","labelRegex":"^v8.13.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/172850","number":172850,"mergeCommit":{"message":"[Fleet] Fix 500 in Fleet API when request to product versions endpoint throws ECONNREFUSED (#172850)\n\n## Summary\r\n\r\nNetwork-level errors will cause `fetch` to `throw` rather than resolving\r\nwith a status code. This PR updates our logic to handle this case for\r\nairgapped environments where `ECONNREFUSED` style errors squash HTTP\r\nrequests at the DNS level.","sha":"be6fbc4dcc8fff7e7419cf3fa9b05a6b13e3edba"}},{"branch":"8.11","label":"v8.11.3","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Kyle Pollich <kyle.pollich@elastic.co>
This commit is contained in:
parent
e5bcd5f9a6
commit
c360cc9cb7
2 changed files with 48 additions and 14 deletions
|
@ -179,4 +179,29 @@ describe('getAvailableVersions', () => {
|
|||
expect(mockedFetch).toBeCalledTimes(1);
|
||||
expect(res2).not.toContain('300.0.0');
|
||||
});
|
||||
|
||||
it('should gracefully handle 400 errors when fetching from product versions API', async () => {
|
||||
mockKibanaVersion = '300.0.0';
|
||||
mockedReadFile.mockResolvedValue(`["8.1.0", "8.0.0", "7.17.0", "7.16.0"]`);
|
||||
mockedFetch.mockResolvedValue({
|
||||
status: 400,
|
||||
text: 'Bad request',
|
||||
} as any);
|
||||
|
||||
const res = await getAvailableVersions({ ignoreCache: true });
|
||||
|
||||
// Should sort, uniquify and filter out versions < 7.17
|
||||
expect(res).toEqual(['8.1.0', '8.0.0', '7.17.0']);
|
||||
});
|
||||
|
||||
it('should gracefully handle network errors when fetching from product versions API', async () => {
|
||||
mockKibanaVersion = '300.0.0';
|
||||
mockedReadFile.mockResolvedValue(`["8.1.0", "8.0.0", "7.17.0", "7.16.0"]`);
|
||||
mockedFetch.mockRejectedValue('ECONNREFUSED');
|
||||
|
||||
const res = await getAvailableVersions({ ignoreCache: true });
|
||||
|
||||
// Should sort, uniquify and filter out versions < 7.17
|
||||
expect(res).toEqual(['8.1.0', '8.0.0', '7.17.0']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ const AGENT_VERSION_BUILD_FILE = 'x-pack/plugins/fleet/target/agent_versions_lis
|
|||
|
||||
// Endpoint maintained by the web-team and hosted on the elastic website
|
||||
const PRODUCT_VERSIONS_URL = 'https://www.elastic.co/api/product_versions';
|
||||
const MAX_REQUEST_TIMEOUT = 60 * 1000; // Only attempt to fetch product versions for one minute total
|
||||
|
||||
// Cache available versions in memory for 1 hour
|
||||
const CACHE_DURATION = 1000 * 60 * 60;
|
||||
|
@ -118,21 +119,29 @@ async function fetchAgentVersionsFromApi() {
|
|||
},
|
||||
};
|
||||
|
||||
const response = await pRetry(() => fetch(PRODUCT_VERSIONS_URL, options), { retries: 1 });
|
||||
const rawBody = await response.text();
|
||||
try {
|
||||
const response = await pRetry(() => fetch(PRODUCT_VERSIONS_URL, options), {
|
||||
retries: 1,
|
||||
maxRetryTime: MAX_REQUEST_TIMEOUT,
|
||||
});
|
||||
const rawBody = await response.text();
|
||||
|
||||
// We need to handle non-200 responses gracefully here to support airgapped environments where
|
||||
// Kibana doesn't have internet access to query this API
|
||||
if (response.status >= 400) {
|
||||
logger.debug(`Status code ${response.status} received from versions API: ${rawBody}`);
|
||||
// We need to handle non-200 responses gracefully here to support airgapped environments where
|
||||
// Kibana doesn't have internet access to query this API
|
||||
if (response.status >= 400) {
|
||||
logger.debug(`Status code ${response.status} received from versions API: ${rawBody}`);
|
||||
return [];
|
||||
}
|
||||
|
||||
const jsonBody = JSON.parse(rawBody);
|
||||
|
||||
const versions: string[] = (jsonBody.length ? jsonBody[0] : [])
|
||||
.filter((item: any) => item?.title?.includes('Elastic Agent'))
|
||||
.map((item: any) => item?.version_number);
|
||||
|
||||
return versions;
|
||||
} catch (error) {
|
||||
logger.debug(`Error fetching available versions from API: ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
|
||||
const jsonBody = JSON.parse(rawBody);
|
||||
|
||||
const versions: string[] = (jsonBody.length ? jsonBody[0] : [])
|
||||
.filter((item: any) => item?.title?.includes('Elastic Agent'))
|
||||
.map((item: any) => item?.version_number);
|
||||
|
||||
return versions;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue