Skip to content

Commit

Permalink
Spaces - migrate default space and enter space view to KP (elastic#66098
Browse files Browse the repository at this point in the history
  • Loading branch information
legrego authored May 13, 2020
1 parent f830ec2 commit 1091aa7
Show file tree
Hide file tree
Showing 14 changed files with 601 additions and 70 deletions.
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 @@
/*
* 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

0 comments on commit 1091aa7

Please sign in to comment.