kibana/x-pack/test/monitoring_api_integration/packages.ts
Cristina Amico 966736e4b4
[Fleet] Add rate limiting to install by upload endpoint (#184036)
Fixes https://github.com/elastic/ingest-dev/issues/3217

## Summary

Add rate limiting to "install by upload" endpoint. 
Implemented with a cache that is set with the timestamp of each install
by upload, independently from the package name/version. If the time
elapsed since the last timestamp it's less than retry time (10s), the
endpoint will return `429 Too many requests`.

### Testing
- Upload a package with 
```
curl -XPOST -H 'content-type: application/zip' -H 'kbn-xsrf: true' http://localhost:5601/YOUR_PATH/api/fleet/epm/packages -u elastic:changeme --data-binary @PACKAGE_NAME.zip
```
- Upload another package shortly after. It can be the same one or
another one, as the rate limiting is applied across all uploads, no
matter the package name.
- If the second upload happens <10s after the first one, should return
error `429 Too Many Requests. Please wait 10s before uploading again.`

### Checklist

- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2024-06-06 17:13:52 +02:00

53 lines
1.8 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import path from 'path';
import { createReadStream } from 'fs';
import type SuperTest from 'supertest';
type SupportedPackage = 'beat' | 'elasticsearch' | 'enterprisesearch' | 'logstash' | 'kibana';
const PACKAGES = [
{ name: 'beat', version: '0.1.3' },
{ name: 'elasticsearch', version: '1.4.1' },
{ name: 'enterprisesearch', version: '1.0.0' },
{ name: 'logstash', version: '2.2.2-preview1' },
{ name: 'kibana', version: '2.3.0-preview1' },
];
export const getPackagesArgs = (): string[] => {
return PACKAGES.flatMap((pkg, i) => {
return [
`--xpack.fleet.packages.${i}.name=${pkg.name}`,
`--xpack.fleet.packages.${i}.version=${pkg.version}`,
];
});
};
export const bundledPackagesLocation = path.join(path.dirname(__filename), '/fixtures/packages');
export async function installPackage(supertest: SuperTest.Agent, packageName: SupportedPackage) {
const pkg = PACKAGES.find(({ name }) => name === packageName);
const request = supertest
.post('/api/fleet/epm/packages')
.set('kbn-xsrf', 'xxx')
.set('content-type', 'application/zip');
// wait 10s before uploading again to avoid getting 429 from upload endpoint
await new Promise((resolve) => setTimeout(resolve, 10000));
return new Promise<void>((resolve, reject) => {
createReadStream(path.join(bundledPackagesLocation, `${pkg!.name}-${pkg!.version}.zip`))
.on('data', (chunk) => request.write(chunk))
.on('end', () => {
request
.send()
.expect(200)
.then(() => resolve())
.catch(reject);
});
});
}