mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Specifying valid licenses for the Graph feature (#55911)
* Specifying valid licenses for the Graph feature * Adding option to /api/features to ignore valid licenses This allow us to take advantage of the /api/featues endpoint within our tests to disable all features, including those which are disabled by the current license. The ui capabilities don't take into considerating the license at the moment, so they're separate entirely separeate mechanisms at this point in time. * Addressing PR comments Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
b2c9beb00f
commit
02f309c206
7 changed files with 80 additions and 9 deletions
|
@ -61,6 +61,7 @@ export const graph: LegacyPluginInitializer = kibana => {
|
|||
navLinkId: 'graph',
|
||||
app: ['graph', 'kibana'],
|
||||
catalogue: ['graph'],
|
||||
validLicenses: ['platinum', 'enterprise', 'trial'],
|
||||
privileges: {
|
||||
all: {
|
||||
savedObject: {
|
||||
|
|
|
@ -43,7 +43,7 @@ export interface Feature<
|
|||
* This does not restrict access to your feature based on license.
|
||||
* Its only purpose is to inform the space and roles UIs on which features to display.
|
||||
*/
|
||||
validLicenses?: Array<'basic' | 'standard' | 'gold' | 'platinum' | 'enterprise'>;
|
||||
validLicenses?: Array<'basic' | 'standard' | 'gold' | 'platinum' | 'enterprise' | 'trial'>;
|
||||
|
||||
/**
|
||||
* An optional EUI Icon to be used when displaying your feature.
|
||||
|
|
|
@ -51,7 +51,7 @@ const schema = Joi.object({
|
|||
name: Joi.string().required(),
|
||||
excludeFromBasePrivileges: Joi.boolean(),
|
||||
validLicenses: Joi.array().items(
|
||||
Joi.string().valid('basic', 'standard', 'gold', 'platinum', 'enterprise')
|
||||
Joi.string().valid('basic', 'standard', 'gold', 'platinum', 'enterprise', 'trial')
|
||||
),
|
||||
icon: Joi.string(),
|
||||
description: Joi.string(),
|
||||
|
|
|
@ -53,7 +53,7 @@ describe('GET /api/features', () => {
|
|||
|
||||
it('returns a list of available features', async () => {
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
routeHandler(undefined as any, undefined as any, mockResponse);
|
||||
routeHandler(undefined as any, { query: {} } as any, mockResponse);
|
||||
|
||||
expect(mockResponse.ok.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
|
@ -84,11 +84,11 @@ describe('GET /api/features', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it(`does not return features that arent allowed by current license`, async () => {
|
||||
it(`by default does not return features that arent allowed by current license`, async () => {
|
||||
currentLicenseLevel = 'basic';
|
||||
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
routeHandler(undefined as any, undefined as any, mockResponse);
|
||||
routeHandler(undefined as any, { query: {} } as any, mockResponse);
|
||||
|
||||
expect(mockResponse.ok.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
|
@ -107,4 +107,63 @@ describe('GET /api/features', () => {
|
|||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it(`ignoreValidLicenses=false does not return features that arent allowed by current license`, async () => {
|
||||
currentLicenseLevel = 'basic';
|
||||
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
routeHandler(undefined as any, { query: { ignoreValidLicenses: false } } as any, mockResponse);
|
||||
|
||||
expect(mockResponse.ok.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"body": Array [
|
||||
Object {
|
||||
"app": Array [],
|
||||
"id": "feature_1",
|
||||
"name": "Feature 1",
|
||||
"privileges": Object {},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it(`ignoreValidLicenses=true returns features that arent allowed by current license`, async () => {
|
||||
currentLicenseLevel = 'basic';
|
||||
|
||||
const mockResponse = httpServerMock.createResponseFactory();
|
||||
routeHandler(undefined as any, { query: { ignoreValidLicenses: true } } as any, mockResponse);
|
||||
|
||||
expect(mockResponse.ok.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"body": Array [
|
||||
Object {
|
||||
"app": Array [],
|
||||
"id": "feature_1",
|
||||
"name": "Feature 1",
|
||||
"privileges": Object {},
|
||||
},
|
||||
Object {
|
||||
"app": Array [
|
||||
"bar-app",
|
||||
],
|
||||
"id": "licensed_feature",
|
||||
"name": "Licensed Feature",
|
||||
"privileges": Object {},
|
||||
"validLicenses": Array [
|
||||
"gold",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from '../../../../../src/core/server';
|
||||
import { LegacyAPI } from '../plugin';
|
||||
import { FeatureRegistry } from '../feature_registry';
|
||||
|
@ -19,13 +20,20 @@ export interface RouteDefinitionParams {
|
|||
|
||||
export function defineRoutes({ router, featureRegistry, getLegacyAPI }: RouteDefinitionParams) {
|
||||
router.get(
|
||||
{ path: '/api/features', options: { tags: ['access:features'] }, validate: false },
|
||||
{
|
||||
path: '/api/features',
|
||||
options: { tags: ['access:features'] },
|
||||
validate: {
|
||||
query: schema.object({ ignoreValidLicenses: schema.boolean({ defaultValue: false }) }),
|
||||
},
|
||||
},
|
||||
(context, request, response) => {
|
||||
const allFeatures = featureRegistry.getAll();
|
||||
|
||||
return response.ok({
|
||||
body: allFeatures.filter(
|
||||
feature =>
|
||||
request.query.ignoreValidLicenses ||
|
||||
!feature.validLicenses ||
|
||||
!feature.validLicenses.length ||
|
||||
getLegacyAPI().xpackInfo.license.isOneOf(feature.validLicenses)
|
||||
|
|
|
@ -22,9 +22,11 @@ export class FeaturesService {
|
|||
});
|
||||
}
|
||||
|
||||
public async get(): Promise<Features> {
|
||||
public async get({ ignoreValidLicenses } = { ignoreValidLicenses: false }): Promise<Features> {
|
||||
this.log.debug('requesting /api/features to get the features');
|
||||
const response = await this.axios.get('/api/features');
|
||||
const response = await this.axios.get(
|
||||
`/api/features?ignoreValidLicenses=${ignoreValidLicenses}`
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error(
|
||||
|
|
|
@ -16,7 +16,8 @@ export default function uiCapabilitesTests({ loadTestFile, getService }: FtrProv
|
|||
this.tags('ciGroup9');
|
||||
|
||||
before(async () => {
|
||||
const features = await featuresService.get();
|
||||
// we're using a basic license, so if we want to disable all features, we have to ignore the valid licenses
|
||||
const features = await featuresService.get({ ignoreValidLicenses: true });
|
||||
for (const space of SpaceScenarios) {
|
||||
const disabledFeatures =
|
||||
space.disabledFeatures === '*' ? Object.keys(features) : space.disabledFeatures;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue