mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
NP Licensing service info endpoint (#51188)
* add NP licensing service info endpoint * call licensing/info and mark it as system to prevent session update * add integration api test for licensing/info endpoint * readonly for static data!
This commit is contained in:
parent
e16e3e3f63
commit
d61cef41bb
8 changed files with 110 additions and 17 deletions
|
@ -38,6 +38,25 @@ describe('licensing plugin', () => {
|
|||
|
||||
expect(license.uid).toBe('fetched');
|
||||
});
|
||||
|
||||
it('data re-fetch call marked as a system api', async () => {
|
||||
const sessionStorage = coreMock.createStorage();
|
||||
plugin = new LicensingPlugin(coreMock.createPluginInitializerContext(), sessionStorage);
|
||||
|
||||
const coreSetup = coreMock.createSetup();
|
||||
const fetchedLicense = licenseMock.create();
|
||||
coreSetup.http.get.mockResolvedValue(fetchedLicense);
|
||||
|
||||
const { refresh } = await plugin.setup(coreSetup);
|
||||
|
||||
refresh();
|
||||
|
||||
expect(coreSetup.http.get.mock.calls[0][1]).toMatchObject({
|
||||
headers: {
|
||||
'kbn-system-api': 'true',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#license$', () => {
|
||||
|
@ -238,7 +257,7 @@ describe('licensing plugin', () => {
|
|||
},
|
||||
},
|
||||
request: {
|
||||
url: 'http://10.10.10.10:5601/api/xpack/v1/info',
|
||||
url: 'http://10.10.10.10:5601/api/licensing/info',
|
||||
},
|
||||
};
|
||||
expect(coreSetup.http.get).toHaveBeenCalledTimes(0);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { Subject, Subscription, merge } from 'rxjs';
|
||||
import { takeUntil, tap } from 'rxjs/operators';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public';
|
||||
|
||||
|
@ -31,8 +31,9 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup> {
|
|||
*/
|
||||
private removeInterceptor?: () => void;
|
||||
private licenseFetchSubscription?: Subscription;
|
||||
private storageSubscription?: Subscription;
|
||||
|
||||
private infoEndpoint = '/api/xpack/v1/info';
|
||||
private readonly infoEndpoint = '/api/licensing/info';
|
||||
private prevSignature?: string;
|
||||
|
||||
constructor(
|
||||
|
@ -76,18 +77,16 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup> {
|
|||
);
|
||||
this.licenseFetchSubscription = fetchSubscription;
|
||||
|
||||
const license$ = update$.pipe(
|
||||
tap(license => {
|
||||
if (license.error) {
|
||||
this.prevSignature = undefined;
|
||||
// Prevent reusing stale license if the fetch operation fails
|
||||
this.removeSaved();
|
||||
} else {
|
||||
this.prevSignature = license.signature;
|
||||
this.save(license);
|
||||
}
|
||||
})
|
||||
);
|
||||
this.storageSubscription = update$.subscribe(license => {
|
||||
if (license.isAvailable) {
|
||||
this.prevSignature = license.signature;
|
||||
this.save(license);
|
||||
} else {
|
||||
this.prevSignature = undefined;
|
||||
// Prevent reusing stale license if the fetch operation fails
|
||||
this.removeSaved();
|
||||
}
|
||||
});
|
||||
|
||||
this.removeInterceptor = core.http.intercept({
|
||||
response: async httpResponse => {
|
||||
|
@ -107,7 +106,7 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup> {
|
|||
refresh: () => {
|
||||
manualRefresh$.next();
|
||||
},
|
||||
license$,
|
||||
license$: update$,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -124,11 +123,20 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup> {
|
|||
this.licenseFetchSubscription.unsubscribe();
|
||||
this.licenseFetchSubscription = undefined;
|
||||
}
|
||||
if (this.storageSubscription !== undefined) {
|
||||
this.storageSubscription.unsubscribe();
|
||||
this.storageSubscription = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private fetchLicense = async (core: CoreSetup): Promise<ILicense> => {
|
||||
try {
|
||||
const response = await core.http.get(this.infoEndpoint);
|
||||
const response = await core.http.get(this.infoEndpoint, {
|
||||
headers: {
|
||||
'kbn-system-api': 'true',
|
||||
},
|
||||
});
|
||||
|
||||
return new License({
|
||||
license: response.license,
|
||||
features: response.features,
|
||||
|
|
|
@ -24,6 +24,8 @@ import { License } from '../common/license';
|
|||
import { createLicenseUpdate } from '../common/license_update';
|
||||
|
||||
import { ElasticsearchError, RawLicense, RawFeatures } from './types';
|
||||
import { registerRoutes } from './routes';
|
||||
|
||||
import { LicenseConfigType } from './licensing_config';
|
||||
import { createRouteHandlerContext } from './licensing_route_handler_context';
|
||||
|
||||
|
@ -92,6 +94,7 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup> {
|
|||
const { refresh, license$ } = this.createLicensePoller(dataClient, config.pollingFrequency);
|
||||
|
||||
core.http.registerRouteHandlerContext('licensing', createRouteHandlerContext(license$));
|
||||
registerRoutes(core.http.createRouter());
|
||||
|
||||
return {
|
||||
refresh,
|
||||
|
|
11
x-pack/plugins/licensing/server/routes/index.ts
Normal file
11
x-pack/plugins/licensing/server/routes/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { IRouter } from 'src/core/server';
|
||||
import { registerInfoRoute } from './info';
|
||||
|
||||
export function registerRoutes(router: IRouter) {
|
||||
registerInfoRoute(router);
|
||||
}
|
14
x-pack/plugins/licensing/server/routes/info.ts
Normal file
14
x-pack/plugins/licensing/server/routes/info.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { IRouter } from 'src/core/server';
|
||||
|
||||
export function registerInfoRoute(router: IRouter) {
|
||||
router.get({ path: '/api/licensing/info', validate: false }, (context, request, response) => {
|
||||
return response.ok({
|
||||
body: context.licensing.license,
|
||||
});
|
||||
});
|
||||
}
|
|
@ -27,5 +27,6 @@ export default function ({ loadTestFile }) {
|
|||
loadTestFile(require.resolve('./siem'));
|
||||
loadTestFile(require.resolve('./short_urls'));
|
||||
loadTestFile(require.resolve('./lens'));
|
||||
loadTestFile(require.resolve('./licensing'));
|
||||
});
|
||||
}
|
||||
|
|
13
x-pack/test/api_integration/apis/licensing/index.ts
Normal file
13
x-pack/test/api_integration/apis/licensing/index.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function licensingIntegrationTests({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Licensing', () => {
|
||||
loadTestFile(require.resolve('./info'));
|
||||
});
|
||||
}
|
24
x-pack/test/api_integration/apis/licensing/info.ts
Normal file
24
x-pack/test/api_integration/apis/licensing/info.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('Info', () => {
|
||||
describe('GET /api/licensing/info', () => {
|
||||
it('returns licensing information', async () => {
|
||||
const response = await supertest.get('/api/licensing/info').expect(200);
|
||||
|
||||
expect(response.body).property('features');
|
||||
expect(response.body).property('license');
|
||||
expect(response.body).property('signature');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue