[HTTP] Add build number to headers so that we can identify UIs (#163577)

Close https://github.com/elastic/kibana/issues/162332

### List

- [x] Add E2E test

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Jean-Louis Leysens 2023-08-16 16:05:57 +02:00 committed by GitHub
parent 1efec8e0d0
commit a00c2401e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 1 deletions

View file

@ -29,6 +29,7 @@ describe('Fetch', () => {
const fetchInstance = new Fetch({
basePath: new BasePath(BASE_PATH),
kibanaVersion: 'VERSION',
buildNumber: 1234,
executionContext: executionContextMock,
});
afterEach(() => {
@ -160,6 +161,7 @@ describe('Fetch', () => {
expect(fetchMock.lastOptions()!.headers).toMatchObject({
'content-type': 'application/json',
'kbn-version': 'VERSION',
'kbn-build-number': '1234',
'x-elastic-internal-origin': 'Kibana',
myheader: 'foo',
});
@ -178,6 +180,19 @@ describe('Fetch', () => {
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-version]"`
);
});
it('should not allow overwriting of kbn-build-number header', async () => {
fetchMock.get('*', {});
await expect(
fetchInstance.fetch('/my/path', {
headers: {
myHeader: 'foo',
'kbn-build-number': 4321,
},
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-build-number]"`
);
});
it('should not allow overwriting of x-elastic-internal-origin header', async () => {
fetchMock.get('*', {});

View file

@ -31,6 +31,7 @@ import { HttpInterceptHaltError } from './http_intercept_halt_error';
interface Params {
basePath: IBasePath;
kibanaVersion: string;
buildNumber: number;
executionContext: ExecutionContextSetup;
}
@ -135,6 +136,7 @@ export class Fetch {
'Content-Type': 'application/json',
...options.headers,
'kbn-version': this.params.kibanaVersion,
'kbn-build-number': this.params.buildNumber,
[ELASTIC_HTTP_VERSION_HEADER]: version,
[X_ELASTIC_INTERNAL_ORIGIN_REQUEST]: 'Kibana',
...(!isEmpty(context) ? new ExecutionContextContainer(context).toHeader() : {}),

View file

@ -31,13 +31,14 @@ export class HttpService implements CoreService<HttpSetup, HttpStart> {
public setup({ injectedMetadata, fatalErrors, executionContext }: HttpDeps): HttpSetup {
const kibanaVersion = injectedMetadata.getKibanaVersion();
const buildNumber = injectedMetadata.getKibanaBuildNumber();
const basePath = new BasePath(
injectedMetadata.getBasePath(),
injectedMetadata.getServerBasePath(),
injectedMetadata.getPublicBaseUrl()
);
const fetchService = new Fetch({ basePath, kibanaVersion, executionContext });
const fetchService = new Fetch({ basePath, kibanaVersion, buildNumber, executionContext });
const loadingCount = this.loadingCount.setup({ fatalErrors });
loadingCount.addLoadingCountSource(fetchService.getRequestCount$());

View file

@ -22,6 +22,15 @@ export class CoreHttpPlugin implements Plugin {
return res.ok();
}
);
router.get(
{
path: '/api/core_http/headers',
validate: false,
},
async (ctx, req, res) => {
return res.ok({ body: req.headers });
}
);
}
public start() {}

View file

@ -7,6 +7,7 @@
*/
import expect from '@kbn/expect';
import SemVer from 'semver';
import { PluginFunctionalProviderContext } from '../../services';
export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) {
@ -29,5 +30,22 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
const canceledErrorName = await getCancelationErrorName();
expect(canceledErrorName).to.eql('AbortError');
});
it('sets the expected headers', async () => {
const headers = await browser.executeAsync<Record<string, string>>(async (cb) => {
cb(await window._coreProvider.setup.core.http.get('/api/core_http/headers'));
});
expect(headers).to.have.property('kbn-version');
expect(!!SemVer.valid(headers['kbn-version'])).to.be(true);
expect(headers).to.have.property('kbn-build-number');
expect(headers['kbn-build-number']).to.match(/^\d+$/);
expect(headers).to.have.property('x-elastic-internal-origin');
expect(headers['x-elastic-internal-origin']).to.be.a('string');
expect(headers).to.have.property('x-kbn-context');
expect(headers['x-kbn-context']).to.be.a('string');
});
});
}