Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions x-pack/legacy/plugins/spaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import { SpacesPluginSetup } from '../../../plugins/spaces/server';
// @ts-ignore
import { AuditLogger } from '../../server/lib/audit_logger';
import { wrapError } from './server/lib/errors';
// @ts-ignore
import { watchStatusAndLicenseToInitialize } from '../../server/lib/watch_status_and_license_to_initialize';
import { initEnterSpaceView } from './server/routes/views';

export interface LegacySpacesPlugin {
getSpaceId: (request: Legacy.Request) => ReturnType<SpacesServiceSetup['getSpaceId']>;
Expand Down Expand Up @@ -51,7 +48,7 @@ export const spaces = (kibana: Record<string, any>) =>
) {
// NOTICE: use of `activeSpace` is deprecated and will not be made available in the New Platform.
// Known usages:
// - x-pack/legacy/plugins/infra/public/utils/use_kibana_space_id.ts
// - x-pack/plugins/infra/public/utils/use_kibana_space_id.ts
const spacesPlugin = server.newPlatform.setup.plugins.spaces as SpacesPluginSetup;
if (!spacesPlugin) {
throw new Error('New Platform XPack Spaces plugin is not available.');
Expand Down Expand Up @@ -83,7 +80,7 @@ export const spaces = (kibana: Record<string, any>) =>
throw new Error('New Platform XPack Spaces plugin is not available.');
}

const { registerLegacyAPI, createDefaultSpace } = spacesPlugin.__legacyCompat;
const { registerLegacyAPI } = spacesPlugin.__legacyCompat;

registerLegacyAPI({
auditLogger: {
Expand All @@ -92,12 +89,6 @@ export const spaces = (kibana: Record<string, any>) =>
},
});

initEnterSpaceView(server);

watchStatusAndLicenseToInitialize(server.plugins.xpack_main, this, async () => {
await createDefaultSpace();
});

server.expose('getSpaceId', (request: Legacy.Request) =>
spacesPlugin.spacesService.getSpaceId(request)
);
Expand Down
30 changes: 0 additions & 30 deletions x-pack/legacy/plugins/spaces/server/routes/views/enter_space.ts

This file was deleted.

13 changes: 13 additions & 0 deletions x-pack/plugins/spaces/common/licensing/index.mock.ts
Original file line number Diff line number Diff line change
@@ -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 { SpacesLicense } from '.';

export const licenseMock = {
create: (): jest.Mocked<SpacesLicense> => ({
isEnabled: jest.fn().mockReturnValue(true),
}),
};
7 changes: 7 additions & 0 deletions x-pack/plugins/spaces/common/licensing/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export { SpacesLicenseService, SpacesLicense } from './license_service';
46 changes: 46 additions & 0 deletions x-pack/plugins/spaces/common/licensing/license_service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 { of } from 'rxjs';
import { licensingMock } from '../../../licensing/public/mocks';
import { SpacesLicenseService } from './license_service';
import { LICENSE_TYPE, LicenseType } from '../../../licensing/common/types';

describe('license#isEnabled', function() {
it('should indicate that Spaces is disabled when there is no license information', () => {
const serviceSetup = new SpacesLicenseService().setup({
license$: of(undefined as any),
});
expect(serviceSetup.license.isEnabled()).toEqual(false);
});

it('should indicate that Spaces is disabled when xpack is unavailable', () => {
const rawLicenseMock = licensingMock.createLicenseMock();
rawLicenseMock.isAvailable = false;
const serviceSetup = new SpacesLicenseService().setup({
license$: of(rawLicenseMock),
});
expect(serviceSetup.license.isEnabled()).toEqual(false);
});

for (const level in LICENSE_TYPE) {
if (isNaN(level as any)) {
it(`should indicate that Spaces is enabled with a ${level} license`, () => {
const rawLicense = licensingMock.createLicense({
license: {
status: 'active',
type: level as LicenseType,
},
});

const serviceSetup = new SpacesLicenseService().setup({
license$: of(rawLicense),
});
expect(serviceSetup.license.isEnabled()).toEqual(true);
});
}
}
});
50 changes: 50 additions & 0 deletions x-pack/plugins/spaces/common/licensing/license_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is likely overkill for the needs of this PR, but I wanted to set up Spaces to have a similar license service as Security, for consistency. If Spaces ever gets more complex, we'll already be setup to support it.

* 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 { Observable, Subscription } from 'rxjs';
import { ILicense } from '../../../licensing/common/types';

export interface SpacesLicense {
isEnabled(): boolean;
}

interface SetupDeps {
license$: Observable<ILicense>;
}

export class SpacesLicenseService {
private licenseSubscription?: Subscription;

public setup({ license$ }: SetupDeps) {
let rawLicense: Readonly<ILicense> | undefined;

this.licenseSubscription = license$.subscribe(nextRawLicense => {
rawLicense = nextRawLicense;
});

return {
license: Object.freeze({
isEnabled: () => this.isSpacesEnabledFromRawLicense(rawLicense),
}),
};
}

public stop() {
if (this.licenseSubscription) {
this.licenseSubscription.unsubscribe();
this.licenseSubscription = undefined;
}
}

private isSpacesEnabledFromRawLicense(rawLicense: Readonly<ILicense> | undefined) {
if (!rawLicense || !rawLicense.isAvailable) {
return false;
}

const licenseCheck = rawLicense.check('spaces', 'basic');
return licenseCheck.state !== 'unavailable' && licenseCheck.state !== 'invalid';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import { createDefaultSpace } from './create_default_space';
import { SavedObjectsErrorHelpers } from 'src/core/server';
import { loggingServiceMock } from '../../../../../src/core/server/mocks';

interface MockServerSettings {
defaultExists?: boolean;
Expand Down Expand Up @@ -47,14 +48,16 @@ const createMockDeps = (settings: MockServerSettings = {}) => {
});

return {
savedObjects: {
createInternalRepository: jest.fn().mockImplementation(() => {
return {
get: mockGet,
create: mockCreate,
};
getSavedObjects: () =>
Promise.resolve({
createInternalRepository: jest.fn().mockImplementation(() => {
return {
get: mockGet,
create: mockCreate,
};
}),
}),
},
logger: loggingServiceMock.createLogger(),
};
};

Expand All @@ -65,7 +68,7 @@ test(`it creates the default space when one does not exist`, async () => {

await createDefaultSpace(deps);

const repository = deps.savedObjects.createInternalRepository();
const repository = (await deps.getSavedObjects()).createInternalRepository();

expect(repository.get).toHaveBeenCalledTimes(1);
expect(repository.create).toHaveBeenCalledTimes(1);
Expand All @@ -89,7 +92,7 @@ test(`it does not attempt to recreate the default space if it already exists`, a

await createDefaultSpace(deps);

const repository = deps.savedObjects.createInternalRepository();
const repository = (await deps.getSavedObjects()).createInternalRepository();

expect(repository.get).toHaveBeenCalledTimes(1);
expect(repository.create).toHaveBeenCalledTimes(0);
Expand All @@ -114,7 +117,7 @@ test(`it ignores conflict errors if the default space already exists`, async ()

await createDefaultSpace(deps);

const repository = deps.savedObjects.createInternalRepository();
const repository = (await deps.getSavedObjects()).createInternalRepository();

expect(repository.get).toHaveBeenCalledTimes(1);
expect(repository.create).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,34 @@
*/

import { i18n } from '@kbn/i18n';
import { SavedObjectsServiceStart, SavedObjectsRepository } from 'src/core/server';
import { SavedObjectsServiceStart, SavedObjectsRepository, Logger } from 'src/core/server';
import { SavedObjectsErrorHelpers } from '../../../../../src/core/server';
import { DEFAULT_SPACE_ID } from '../../common/constants';

interface Deps {
savedObjects: Pick<SavedObjectsServiceStart, 'createInternalRepository'>;
getSavedObjects: () => Promise<Pick<SavedObjectsServiceStart, 'createInternalRepository'>>;
logger: Logger;
}

export async function createDefaultSpace({ savedObjects }: Deps) {
const { createInternalRepository } = savedObjects;
export async function createDefaultSpace({ getSavedObjects, logger }: Deps) {
const { createInternalRepository } = await getSavedObjects();

const savedObjectsRepository = createInternalRepository(['space']);

logger.debug('Checking for existing default space');

const defaultSpaceExists = await doesDefaultSpaceExist(savedObjectsRepository);

if (defaultSpaceExists) {
logger.debug('Default space already exists');
return;
}

const options = {
id: DEFAULT_SPACE_ID,
};

logger.debug('Creating the default space');
try {
await savedObjectsRepository.create(
'space',
Expand All @@ -53,6 +58,8 @@ export async function createDefaultSpace({ savedObjects }: Deps) {
}
throw error;
}

logger.debug('Default space created');
}

async function doesDefaultSpaceExist(savedObjectsRepository: Pick<SavedObjectsRepository, 'get'>) {
Expand Down
Loading