Skip to content

Commit

Permalink
feat: only display oss included projects/environments when install is…
Browse files Browse the repository at this point in the history
… oss (#8896)

Trying again, now with a tested function for resolvingIsOss.

Still want to test this on a pro instance in sandbox before we deploy
this to our customers to avoid what happened Friday.

---------

Co-authored-by: Gastón Fournier <[email protected]>
  • Loading branch information
chriswk and gastonfournier authored Dec 19, 2024
1 parent b701fec commit 66907bf
Show file tree
Hide file tree
Showing 22 changed files with 252 additions and 91 deletions.
1 change: 1 addition & 0 deletions src/lib/__snapshots__/create-config.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ exports[`should create default config 1`] = `
},
"inlineSegmentConstraints": true,
"isEnterprise": false,
"isOss": false,
"listen": {
"host": undefined,
"port": 4242,
Expand Down
35 changes: 34 additions & 1 deletion src/lib/create-config.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createConfig } from './create-config';
import { createConfig, resolveIsOss } from './create-config';
import { ApiTokenType } from './types/models/api-token';

test('should create default config', async () => {
Expand Down Expand Up @@ -498,3 +498,36 @@ test('Config with enterpriseVersion set and not pro environment should set isEnt
});
expect(config.isEnterprise).toBe(true);
});

describe('isOSS', () => {
test('Config with pro environment should set isOss to false regardless of pro casing', async () => {
const isOss = resolveIsOss(false, false, 'Pro');
expect(isOss).toBe(false);
const lowerCase = resolveIsOss(false, false, 'pro');
expect(lowerCase).toBe(false);
const strangeCase = resolveIsOss(false, false, 'PrO');
expect(strangeCase).toBe(false);
});
test('Config with enterpriseVersion set should set isOss to false', async () => {
const isOss = resolveIsOss(true, false, 'Enterprise');
expect(isOss).toBe(false);
});
test('Config with no enterprise version and any other environment than pro should have isOss as true', async () => {
const isOss = resolveIsOss(false, false, 'my oss environment');
expect(isOss).toBe(true);
});
test('Config with enterprise false and isOss option set to false should return false in test mode', async () => {
const isOss = resolveIsOss(false, false, 'my environment', true);
expect(isOss).toBe(false);
});
test('Config with isOss option set to true should return true when test environment is active', async () => {
let isOss = resolveIsOss(false, true, 'Pro', true);
expect(isOss).toBe(true);

isOss = resolveIsOss(true, true, 'Pro', true);
expect(isOss).toBe(true);

isOss = resolveIsOss(false, true, 'some environment', true);
expect(isOss).toBe(true);
});
});
20 changes: 20 additions & 0 deletions src/lib/create-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,17 @@ const parseFrontendApiOrigins = (options: IUnleashOptions): string[] => {
return frontendApiOrigins;
};

export function resolveIsOss(
isEnterprise: boolean,
isOssOption?: boolean,
uiEnvironment?: string,
testEnvironmentActive: boolean = false,
): boolean {
return testEnvironmentActive
? (isOssOption ?? false)
: !isEnterprise && uiEnvironment?.toLowerCase() !== 'pro';
}

export function createConfig(options: IUnleashOptions): IUnleashConfig {
let extraDbOptions = {};

Expand Down Expand Up @@ -620,6 +631,13 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
Boolean(options.enterpriseVersion) &&
ui.environment?.toLowerCase() !== 'pro';

const isTest = process.env.NODE_ENV === 'test';
const isOss = resolveIsOss(
isEnterprise,
options.isOss,
ui.environment,
isTest,
);
const metricsRateLimiting = loadMetricsRateLimitingConfig(options);

const rateLimiting = loadRateLimitingConfig(options);
Expand Down Expand Up @@ -760,6 +778,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
publicFolder: options.publicFolder,
disableScheduler: options.disableScheduler,
isEnterprise: isEnterprise,
isOss: isOss,
metricsRateLimiting,
rateLimiting,
feedbackUriPath,
Expand All @@ -771,5 +790,6 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {

module.exports = {
createConfig,
resolveIsOss,
authTypeFromString,
};
31 changes: 29 additions & 2 deletions src/lib/db/feature-environment-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import type {
FeatureEnvironmentKey,
IFeatureEnvironmentStore,
} from '../types/stores/feature-environment-store';
import type { Logger, LogProvider } from '../logger';
import type { Logger } from '../logger';
import metricsHelper from '../util/metrics-helper';
import { DB_TIME } from '../metric-events';
import type { IFeatureEnvironment, IVariant } from '../types/model';
import NotFoundError from '../error/notfound-error';
import { v4 as uuidv4 } from 'uuid';
import type { Db } from './db';
import type { IUnleashConfig } from '../types';

const T = {
featureEnvs: 'feature_environments',
Expand All @@ -36,14 +37,20 @@ export class FeatureEnvironmentStore implements IFeatureEnvironmentStore {

private readonly timer: Function;

constructor(db: Db, eventBus: EventEmitter, getLogger: LogProvider) {
private readonly isOss: boolean;
constructor(
db: Db,
eventBus: EventEmitter,
{ getLogger, isOss }: Pick<IUnleashConfig, 'getLogger' | 'isOss'>,
) {
this.db = db;
this.logger = getLogger('feature-environment-store.ts');
this.timer = (action) =>
metricsHelper.wrapTimer(eventBus, DB_TIME, {
store: 'feature-environments',
action,
});
this.isOss = isOss;
}

async delete({
Expand Down Expand Up @@ -96,11 +103,30 @@ export class FeatureEnvironmentStore implements IFeatureEnvironmentStore {
);
}

addOssFilterIfNeeded(queryBuilder) {
if (this.isOss) {
return queryBuilder
.join(
'environments',
'environments.name',
'=',
`${T.featureEnvs}.environment`,
)
.whereIn('environments.name', [
'default',
'development',
'production',
]);
}
return queryBuilder;
}

async getAll(query?: Object): Promise<IFeatureEnvironment[]> {
let rows = this.db(T.featureEnvs);
if (query) {
rows = rows.where(query);
}
this.addOssFilterIfNeeded(rows);
return (await rows).map((r) => ({
enabled: r.enabled,
featureName: r.feature_name,
Expand All @@ -119,6 +145,7 @@ export class FeatureEnvironmentStore implements IFeatureEnvironmentStore {
if (environment) {
rows = rows.where({ environment });
}
this.addOssFilterIfNeeded(rows);
return (await rows).map((r) => ({
enabled: r.enabled,
featureName: r.feature_name,
Expand Down
14 changes: 4 additions & 10 deletions src/lib/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,7 @@ export const createStores = (
settingStore: new SettingStore(db, getLogger),
userStore: new UserStore(db, getLogger, config.flagResolver),
accountStore: new AccountStore(db, getLogger),
projectStore: new ProjectStore(
db,
eventBus,
getLogger,
config.flagResolver,
),
projectStore: new ProjectStore(db, eventBus, config),
tagStore: new TagStore(db, eventBus, getLogger),
tagTypeStore: new TagTypeStore(db, eventBus, getLogger),
addonStore: new AddonStore(db, eventBus, getLogger),
Expand All @@ -122,15 +117,14 @@ export const createStores = (
clientFeatureToggleStore: new FeatureToggleClientStore(
db,
eventBus,
getLogger,
config.flagResolver,
config,
),
environmentStore: new EnvironmentStore(db, eventBus, getLogger),
environmentStore: new EnvironmentStore(db, eventBus, config),
featureTagStore: new FeatureTagStore(db, eventBus, getLogger),
featureEnvironmentStore: new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
),
userSplashStore: new UserSplashStore(db, eventBus, getLogger),
roleStore: new RoleStore(db, eventBus, getLogger),
Expand Down
2 changes: 1 addition & 1 deletion src/lib/features/access/createAccessService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const createAccessService = (
const groupStore = new GroupStore(db);
const accountStore = new AccountStore(db, getLogger);
const roleStore = new RoleStore(db, eventBus, getLogger);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const environmentStore = new EnvironmentStore(db, eventBus, config);
const accessStore = new AccessStore(db, eventBus, getLogger);
const eventService = createEventsService(db, config);
const groupService = new GroupService(
Expand Down
2 changes: 1 addition & 1 deletion src/lib/features/api-tokens/createApiTokenService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const createApiTokenService = (
getLogger,
config.flagResolver,
);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const environmentStore = new EnvironmentStore(db, eventBus, config);
const eventService = createEventsService(db, config);

return new ApiTokenService(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Knex } from 'knex';
import metricsHelper from '../../util/metrics-helper';
import { DB_TIME } from '../../metric-events';
import type { Logger, LogProvider } from '../../logger';
import type { Logger } from '../../logger';
import type {
IFeatureToggleClient,
IFeatureToggleClientStore,
IFeatureToggleQuery,
IFlagResolver,
IStrategyConfig,
ITag,
IUnleashConfig,
PartialDeep,
} from '../../types';
import {
Expand Down Expand Up @@ -49,8 +50,10 @@ export default class FeatureToggleClientStore
constructor(
db: Db,
eventBus: EventEmitter,
getLogger: LogProvider,
flagResolver: IFlagResolver,
{
getLogger,
flagResolver,
}: Pick<IUnleashConfig, 'getLogger' | 'flagResolver'>,
) {
this.db = db;
this.logger = getLogger('feature-toggle-client-store.ts');
Expand All @@ -72,7 +75,6 @@ export default class FeatureToggleClientStore
const isPlayground = requestType === 'playground';
const environment = featureQuery?.environment || DEFAULT_ENV;
const stopTimer = this.timer(`getAllBy${requestType}`);

let selectColumns = [
'features.name as name',
'features.description as description',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@ export const createClientFeatureToggleService = (
db: Db,
config: IUnleashConfig,
): ClientFeatureToggleService => {
const { getLogger, eventBus, flagResolver } = config;

const featureToggleClientStore = new FeatureToggleClientStore(
db,
eventBus,
getLogger,
flagResolver,
config.eventBus,
config,
);

const segmentReadModel = new SegmentReadModel(db);
Expand All @@ -30,7 +27,7 @@ export const createClientFeatureToggleService = (
},
segmentReadModel,
clientFeatureToggleCache,
{ getLogger, flagResolver },
config,
);

return clientFeatureToggleService;
Expand All @@ -39,8 +36,6 @@ export const createClientFeatureToggleService = (
export const createFakeClientFeatureToggleService = (
config: IUnleashConfig,
): ClientFeatureToggleService => {
const { getLogger, flagResolver } = config;

const fakeClientFeatureToggleStore = new FakeClientFeatureToggleStore();

const fakeSegmentReadModel = new FakeSegmentReadModel();
Expand All @@ -51,7 +46,7 @@ export const createFakeClientFeatureToggleService = (
},
fakeSegmentReadModel,
null,
{ getLogger, flagResolver },
config,
);

return clientFeatureToggleService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,7 @@ export const deferredExportImportTogglesService = (
);
const tagStore = new TagStore(db, eventBus, getLogger);
const tagTypeStore = new TagTypeStore(db, eventBus, getLogger);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
);
const projectStore = new ProjectStore(db, eventBus, config);
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
const strategyStore = new StrategyStore(db, getLogger);
const contextFieldStore = new ContextFieldStore(
Expand All @@ -172,7 +167,7 @@ export const deferredExportImportTogglesService = (
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
);
const eventStore = new EventStore(db, getLogger);
const accessService = createAccessService(db, config);
Expand Down
4 changes: 2 additions & 2 deletions src/lib/features/feature-lifecycle/createFeatureLifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export const createFeatureLifecycleService =
const { eventBus, getLogger } = config;
const eventStore = new EventStore(db, getLogger);
const featureLifecycleStore = new FeatureLifecycleStore(db);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const environmentStore = new EnvironmentStore(db, eventBus, config);
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
);
const eventService = createEventsService(db, config);
const featureLifecycleService = new FeatureLifecycleService(
Expand Down
14 changes: 4 additions & 10 deletions src/lib/features/feature-toggle/createFeatureToggleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,13 @@ export const createFeatureToggleService = (
const featureToggleClientStore = new FeatureToggleClientStore(
db,
eventBus,
getLogger,
flagResolver,
);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
config,
);
const projectStore = new ProjectStore(db, eventBus, config);
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
);
const contextFieldStore = new ContextFieldStore(
db,
Expand All @@ -105,7 +99,7 @@ export const createFeatureToggleService = (
const accessStore = new AccessStore(db, eventBus, getLogger);
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
const roleStore = new RoleStore(db, eventBus, getLogger);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const environmentStore = new EnvironmentStore(db, eventBus, config);
const eventService = createEventsService(db, config);
const groupService = new GroupService(
{ groupStore, accountStore },
Expand Down
9 changes: 2 additions & 7 deletions src/lib/features/instance-stats/createInstanceStatsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,8 @@ export const createInstanceStatsService = (db: Db, config: IUnleashConfig) => {
flagResolver,
);
const userStore = new UserStore(db, getLogger, flagResolver);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
);
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
const projectStore = new ProjectStore(db, eventBus, config);
const environmentStore = new EnvironmentStore(db, eventBus, config);
const strategyStore = new StrategyStore(db, getLogger);
const contextFieldStore = new ContextFieldStore(
db,
Expand Down
Loading

0 comments on commit 66907bf

Please sign in to comment.