mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-05 17:53:12 +02:00
feat: rename :global: env to "default"
Our testing and internal validation has proven that the :global: environment concept confuses people more than the problems it solves. We have thus decided to group all configuration that was created before the environment concept was introdcued in to the "default environment. This would still make everything work as before in addition to introducing the env concept.
This commit is contained in:
parent
833ea32752
commit
99a80f1845
@ -9,6 +9,7 @@ import {
|
||||
IStrategyConfig,
|
||||
} from '../types/model';
|
||||
import { IFeatureToggleClientStore } from '../types/stores/feature-toggle-client-store';
|
||||
import { DEFAULT_ENV } from '../util/constants';
|
||||
|
||||
export interface FeaturesTable {
|
||||
name: string;
|
||||
@ -61,10 +62,7 @@ export default class FeatureToggleClientStore
|
||||
archived: boolean = false,
|
||||
isAdmin: boolean = true,
|
||||
): Promise<IFeatureToggleClient[]> {
|
||||
const environments = [':global:'];
|
||||
if (featureQuery?.environment) {
|
||||
environments.push(featureQuery.environment);
|
||||
}
|
||||
const environment = featureQuery?.environment || DEFAULT_ENV;
|
||||
const stopTimer = this.timer('getFeatureAdmin');
|
||||
let query = this.db('features')
|
||||
.select(
|
||||
@ -97,7 +95,7 @@ export default class FeatureToggleClientStore
|
||||
'feature_environments.environment',
|
||||
);
|
||||
})
|
||||
.whereIn('feature_environments.environment', environments)
|
||||
.where('feature_environments.environment', environment)
|
||||
.where({ archived });
|
||||
if (featureQuery) {
|
||||
if (featureQuery.tag) {
|
||||
@ -133,11 +131,7 @@ export default class FeatureToggleClientStore
|
||||
if (r.strategy_name) {
|
||||
feature.strategies.push(this.getAdminStrategy(r, isAdmin));
|
||||
}
|
||||
if (feature.enabled === undefined) {
|
||||
feature.enabled = r.enabled;
|
||||
} else {
|
||||
feature.enabled = feature.enabled && r.enabled;
|
||||
}
|
||||
feature.name = r.name;
|
||||
feature.description = r.description;
|
||||
feature.project = r.project;
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
IProjectInsert,
|
||||
IProjectStore,
|
||||
} from '../types/stores/project-store';
|
||||
import { DEFAULT_ENV } from '../util/constants';
|
||||
|
||||
const COLUMNS = ['id', 'name', 'description', 'created_at', 'health'];
|
||||
const TABLE = 'projects';
|
||||
@ -99,16 +100,16 @@ class ProjectStore implements IProjectStore {
|
||||
.onConflict('id')
|
||||
.ignore();
|
||||
if (rows.length > 0) {
|
||||
await this.addGlobalEnvironment(rows);
|
||||
await this.addDefaultEnvironment(rows);
|
||||
return rows.map(this.mapRow);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
async addGlobalEnvironment(projects: any[]): Promise<void> {
|
||||
async addDefaultEnvironment(projects: any[]): Promise<void> {
|
||||
const environments = projects.map((p) => ({
|
||||
project_id: p.id,
|
||||
environment_name: ':global:',
|
||||
environment_name: DEFAULT_ENV,
|
||||
}));
|
||||
await this.db('project_environments')
|
||||
.insert(environments)
|
||||
|
@ -16,8 +16,8 @@ import FeatureToggleServiceV2 from '../../services/feature-toggle-service-v2';
|
||||
import { featureSchema, querySchema } from '../../schema/feature-schema';
|
||||
import { IFeatureToggleQuery } from '../../types/model';
|
||||
import FeatureTagService from '../../services/feature-tag-service';
|
||||
import { GLOBAL_ENV } from '../../types/environment';
|
||||
import { IAuthRequest } from '../unleash-types';
|
||||
import { DEFAULT_ENV } from '../../util/constants';
|
||||
|
||||
const version = 1;
|
||||
|
||||
@ -110,11 +110,11 @@ class FeatureController extends Controller {
|
||||
|
||||
private async getLegacyFeatureToggle(name: string): Promise<any> {
|
||||
const feature = await this.featureService2.getFeatureToggle(name);
|
||||
const globalEnv = feature.environments.find(
|
||||
(e) => e.name === GLOBAL_ENV,
|
||||
const defaultEnv = feature.environments.find(
|
||||
(e) => e.name === DEFAULT_ENV,
|
||||
);
|
||||
const strategies = globalEnv?.strategies || [];
|
||||
const enabled = globalEnv?.enabled || false;
|
||||
const strategies = defaultEnv?.strategies || [];
|
||||
const enabled = defaultEnv?.enabled || false;
|
||||
delete feature.environments;
|
||||
|
||||
return { ...feature, enabled, strategies };
|
||||
@ -181,7 +181,7 @@ class FeatureController extends Controller {
|
||||
await this.featureService2.updateEnabled(
|
||||
createdFeature.project,
|
||||
createdFeature.name,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
enabled,
|
||||
userName,
|
||||
);
|
||||
@ -228,7 +228,7 @@ class FeatureController extends Controller {
|
||||
await this.featureService2.updateEnabled(
|
||||
projectId,
|
||||
updatedFeature.name,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
updatedFeature.enabled,
|
||||
userName,
|
||||
);
|
||||
@ -246,7 +246,7 @@ class FeatureController extends Controller {
|
||||
const feature = await this.featureService2.toggle(
|
||||
projectId,
|
||||
featureName,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
userName,
|
||||
);
|
||||
res.status(200).json(feature);
|
||||
@ -259,7 +259,7 @@ class FeatureController extends Controller {
|
||||
const feature = await this.featureService2.updateEnabled(
|
||||
projectId,
|
||||
featureName,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
true,
|
||||
userName,
|
||||
);
|
||||
@ -273,7 +273,7 @@ class FeatureController extends Controller {
|
||||
const feature = await this.featureService2.updateEnabled(
|
||||
projectId,
|
||||
featureName,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
false,
|
||||
userName,
|
||||
);
|
||||
|
@ -19,7 +19,6 @@ import {
|
||||
FEATURE_STRATEGY_UPDATE,
|
||||
FEATURE_UPDATED,
|
||||
} from '../types/events';
|
||||
import { GLOBAL_ENV } from '../types/environment';
|
||||
import NotFoundError from '../error/notfound-error';
|
||||
import {
|
||||
FeatureConfigurationClient,
|
||||
@ -42,6 +41,7 @@ import {
|
||||
} from '../types/model';
|
||||
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
|
||||
import { IFeatureToggleClientStore } from '../types/stores/feature-toggle-client-store';
|
||||
import { DEFAULT_ENV } from '../util/constants';
|
||||
|
||||
class FeatureToggleServiceV2 {
|
||||
private logger: Logger;
|
||||
@ -96,7 +96,7 @@ class FeatureToggleServiceV2 {
|
||||
projectId: string,
|
||||
featureName: string,
|
||||
userName: string,
|
||||
environment: string = GLOBAL_ENV,
|
||||
environment: string = DEFAULT_ENV,
|
||||
): Promise<IStrategyConfig> {
|
||||
try {
|
||||
const newFeatureStrategy =
|
||||
@ -226,7 +226,7 @@ class FeatureToggleServiceV2 {
|
||||
id: string,
|
||||
userName: string,
|
||||
project: string = 'default',
|
||||
environment: string = GLOBAL_ENV,
|
||||
environment: string = DEFAULT_ENV,
|
||||
): Promise<void> {
|
||||
await this.featureStrategiesStore.delete(id);
|
||||
await this.eventStore.store({
|
||||
@ -243,7 +243,7 @@ class FeatureToggleServiceV2 {
|
||||
async getStrategiesForEnvironment(
|
||||
project: string,
|
||||
featureName: string,
|
||||
environment: string = GLOBAL_ENV,
|
||||
environment: string = DEFAULT_ENV,
|
||||
): Promise<IStrategyConfig[]> {
|
||||
const hasEnv = await this.featureEnvironmentStore.featureHasEnvironment(
|
||||
environment,
|
||||
@ -405,7 +405,7 @@ class FeatureToggleServiceV2 {
|
||||
|
||||
async removeAllStrategiesForEnv(
|
||||
toggleName: string,
|
||||
environment: string = GLOBAL_ENV,
|
||||
environment: string = DEFAULT_ENV,
|
||||
): Promise<void> {
|
||||
await this.featureStrategiesStore.removeAllStrategiesForFeatureEnv(
|
||||
toggleName,
|
||||
@ -605,11 +605,11 @@ class FeatureToggleServiceV2 {
|
||||
await this.featureStrategiesStore.getFeatureToggleWithEnvs(
|
||||
featureName,
|
||||
);
|
||||
const globalEnv = feature.environments.find(
|
||||
(e) => e.name === GLOBAL_ENV,
|
||||
const defaultEnv = feature.environments.find(
|
||||
(e) => e.name === DEFAULT_ENV,
|
||||
);
|
||||
const strategies = globalEnv?.strategies || [];
|
||||
const enabled = globalEnv?.enabled || false;
|
||||
const strategies = defaultEnv?.strategies || [];
|
||||
const enabled = defaultEnv?.enabled || false;
|
||||
|
||||
return { ...feature, enabled, strategies };
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import {
|
||||
IUserWithRole,
|
||||
RoleName,
|
||||
} from '../types/model';
|
||||
import { GLOBAL_ENV } from '../types/environment';
|
||||
import { IEnvironmentStore } from '../types/stores/environment-store';
|
||||
import { IFeatureTypeStore } from '../types/stores/feature-type-store';
|
||||
import { IFeatureToggleStore } from '../types/stores/feature-toggle-store';
|
||||
@ -31,6 +30,7 @@ import { IEventStore } from '../types/stores/event-store';
|
||||
import FeatureToggleServiceV2 from './feature-toggle-service-v2';
|
||||
import { CREATE_FEATURE, UPDATE_FEATURE } from '../types/permissions';
|
||||
import NoAccessError from '../error/no-access-error';
|
||||
import { DEFAULT_ENV } from '../util/constants';
|
||||
|
||||
const getCreatedBy = (user: User) => user.email || user.username;
|
||||
|
||||
@ -123,7 +123,8 @@ export default class ProjectService {
|
||||
|
||||
await this.store.create(data);
|
||||
|
||||
await this.featureEnvironmentStore.connectProject(GLOBAL_ENV, data.id);
|
||||
// TODO: we should only connect to enabled environments
|
||||
await this.featureEnvironmentStore.connectProject(DEFAULT_ENV, data.id);
|
||||
|
||||
await this.accessService.createDefaultProjectRoles(user, data.id);
|
||||
|
||||
|
@ -26,7 +26,7 @@ export const featureEnvironmentsSchema = joi.object().keys({
|
||||
});
|
||||
|
||||
export const environmentSchema = joi.object().keys({
|
||||
name: nameType.allow(':global:'),
|
||||
name: nameType,
|
||||
displayName: joi.string().optional().allow(''),
|
||||
type: joi.string().required(),
|
||||
sortOrder: joi.number().optional(),
|
||||
|
@ -28,7 +28,6 @@ import {
|
||||
IProject,
|
||||
IStrategyConfig,
|
||||
} from '../types/model';
|
||||
import { GLOBAL_ENV } from '../types/environment';
|
||||
import { Logger } from '../logger';
|
||||
import {
|
||||
IFeatureTag,
|
||||
@ -44,6 +43,7 @@ import { IFeatureStrategiesStore } from '../types/stores/feature-strategies-stor
|
||||
import { IEnvironmentStore } from '../types/stores/environment-store';
|
||||
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
|
||||
import { IUnleashStores } from '../types/stores';
|
||||
import { DEFAULT_ENV } from '../util/constants';
|
||||
|
||||
export interface IBackupOption {
|
||||
includeFeatureToggles: boolean;
|
||||
@ -245,14 +245,14 @@ export default class StateService {
|
||||
projectId: f.project,
|
||||
constraints: strategy.constraints || [],
|
||||
parameters: strategy.parameters || {},
|
||||
environment: GLOBAL_ENV,
|
||||
environment: DEFAULT_ENV,
|
||||
strategyName: strategy.name,
|
||||
})),
|
||||
);
|
||||
const newFeatures = features;
|
||||
const featureEnvironments = features.map((feature) => ({
|
||||
featureName: feature.name,
|
||||
environment: GLOBAL_ENV,
|
||||
environment: DEFAULT_ENV,
|
||||
enabled: feature.enabled,
|
||||
}));
|
||||
return {
|
||||
|
@ -1,2 +1,3 @@
|
||||
export const MILLISECONDS_IN_DAY = 86400000;
|
||||
export const MILLISECONDS_IN_ONE_HOUR = 3600000;
|
||||
export const DEFAULT_ENV = 'default';
|
||||
|
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
exports.up = function (db, cb) {
|
||||
db.runSql(
|
||||
`
|
||||
INSERT INTO environments(name, display_name, protected, sort_order) VALUES ('default', 'Default Environment', true, 1);
|
||||
ALTER TABLE feature_strategies ALTER COLUMN environment SET DEFAULT 'default';
|
||||
ALTER TABLE feature_environments ALTER COLUMN environment SET DEFAULT 'default';
|
||||
UPDATE feature_strategies SET environment = 'default' WHERE environment = ':global:';
|
||||
UPDATE feature_environments SET environment = 'default' WHERE environment = ':global:';
|
||||
UPDATE project_environments SET environment_name = 'default' WHERE environment_name = ':global:';
|
||||
DELETE FROM environments WHERE name = ':global:';
|
||||
`,
|
||||
cb,
|
||||
);
|
||||
};
|
||||
|
||||
exports.down = function (db, cb) {
|
||||
db.runSql(
|
||||
`
|
||||
INSERT INTO environments(name, display_name, protected) VALUES (':global:', 'Across all environments', true);
|
||||
ALTER TABLE feature_strategies ALTER COLUMN environment SET DEFAULT ':global:';
|
||||
ALTER TABLE feature_environments ALTER COLUMN environment SET DEFAULT ':global:';
|
||||
UPDATE feature_strategies SET environment = ':global:' WHERE environment = 'default';
|
||||
UPDATE feature_environments SET environment = ':global:' WHERE environment = 'default';
|
||||
UPDATE project_environments SET environment_name = ':global:' WHERE environment_name = 'default';
|
||||
DELETE FROM environments WHERE name = 'default';
|
||||
`,
|
||||
cb,
|
||||
);
|
||||
};
|
@ -2,6 +2,7 @@ import { setupApp } from '../../helpers/test-helper';
|
||||
import dbInit from '../../helpers/database-init';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import { ALL, ApiTokenType } from '../../../../lib/types/models/api-token';
|
||||
import { DEFAULT_ENV } from '../../../../lib/util/constants';
|
||||
|
||||
let db;
|
||||
let app;
|
||||
@ -214,14 +215,14 @@ test('creates new client token with project & environment set', async () => {
|
||||
username: 'default-client',
|
||||
type: 'client',
|
||||
project: 'default',
|
||||
environment: ':global:',
|
||||
environment: DEFAULT_ENV,
|
||||
})
|
||||
.set('Content-Type', 'application/json')
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
expect(res.body.type).toBe('client');
|
||||
expect(res.body.secret.length > 16).toBe(true);
|
||||
expect(res.body.environment).toBe(':global:');
|
||||
expect(res.body.environment).toBe(DEFAULT_ENV);
|
||||
expect(res.body.project).toBe('default');
|
||||
});
|
||||
});
|
||||
@ -247,12 +248,12 @@ test('should prefix token with "project:environment."', async () => {
|
||||
username: 'default-client',
|
||||
type: 'client',
|
||||
project: 'default',
|
||||
environment: ':global:',
|
||||
environment: DEFAULT_ENV,
|
||||
})
|
||||
.set('Content-Type', 'application/json')
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
expect(res.body.secret).toMatch(/default::global:\..*/);
|
||||
expect(res.body.secret).toMatch(/default:default\..*/);
|
||||
});
|
||||
});
|
||||
|
||||
@ -323,7 +324,7 @@ test('admin token only supports ALL environments', async () => {
|
||||
username: 'default-admin',
|
||||
type: 'admin',
|
||||
project: '*',
|
||||
environment: ':global:',
|
||||
environment: DEFAULT_ENV,
|
||||
})
|
||||
.set('Content-Type', 'application/json')
|
||||
.expect(400);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import dbInit, { ITestDb } from '../../helpers/database-init';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import { IUnleashTest, setupApp } from '../../helpers/test-helper';
|
||||
import { DEFAULT_ENV } from '../../../../lib/util/constants';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
@ -23,8 +24,8 @@ test('Can list all existing environments', async () => {
|
||||
.expect((res) => {
|
||||
expect(res.body.version).toBe(1);
|
||||
expect(res.body.environments[0]).toStrictEqual({
|
||||
displayName: 'Across all environments',
|
||||
name: ':global:',
|
||||
displayName: 'Default Environment',
|
||||
name: DEFAULT_ENV,
|
||||
enabled: true,
|
||||
sortOrder: 1,
|
||||
type: 'production',
|
||||
@ -43,7 +44,7 @@ test('Can update sort order', async () => {
|
||||
await app.request
|
||||
.put('/api/admin/environments/sort-order')
|
||||
.send({
|
||||
':global:': 2,
|
||||
[DEFAULT_ENV]: 2,
|
||||
[envName]: 1,
|
||||
})
|
||||
.expect(200);
|
||||
@ -56,11 +57,11 @@ test('Can update sort order', async () => {
|
||||
const updatedSort = res.body.environments.find(
|
||||
(t) => t.name === envName,
|
||||
);
|
||||
const global = res.body.environments.find(
|
||||
(t) => t.name === ':global:',
|
||||
const defaultEnv = res.body.environments.find(
|
||||
(t) => t.name === DEFAULT_ENV,
|
||||
);
|
||||
expect(updatedSort.sortOrder).toBe(1);
|
||||
expect(global.sortOrder).toBe(2);
|
||||
expect(defaultEnv.sortOrder).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
@ -70,7 +71,7 @@ test('Sort order will fail on wrong data format', async () => {
|
||||
await app.request
|
||||
.put('/api/admin/environments/sort-order')
|
||||
.send({
|
||||
':global:': 'test',
|
||||
[DEFAULT_ENV]: 'test',
|
||||
[envName]: 1,
|
||||
})
|
||||
.expect(400);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import dbInit, { ITestDb } from '../../../helpers/database-init';
|
||||
import { IUnleashTest, setupApp } from '../../../helpers/test-helper';
|
||||
import getLogger from '../../../../fixtures/no-logger';
|
||||
import { DEFAULT_ENV } from '../../../../../lib/util/constants';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
@ -16,7 +17,7 @@ afterEach(async () => {
|
||||
);
|
||||
await Promise.all(
|
||||
all
|
||||
.filter((env) => env !== ':global:')
|
||||
.filter((env) => env !== DEFAULT_ENV)
|
||||
.map(async (env) =>
|
||||
db.stores.projectStore.deleteEnvironmentForProject(
|
||||
'default',
|
||||
|
@ -2,6 +2,7 @@ import dbInit, { ITestDb } from '../../../helpers/database-init';
|
||||
import { IUnleashTest, setupApp } from '../../../helpers/test-helper';
|
||||
import getLogger from '../../../../fixtures/no-logger';
|
||||
import { GLOBAL_ENV } from '../../../../../lib/types/environment';
|
||||
import { DEFAULT_ENV } from '../../../../../lib/util/constants';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
@ -20,7 +21,7 @@ afterEach(async () => {
|
||||
);
|
||||
await Promise.all(
|
||||
all
|
||||
.filter((env) => env !== ':global:')
|
||||
.filter((env) => env !== DEFAULT_ENV)
|
||||
.map(async (env) =>
|
||||
db.stores.projectStore.deleteEnvironmentForProject(
|
||||
'default',
|
||||
@ -181,7 +182,7 @@ test('Project overview includes environment connected to feature', async () => {
|
||||
.get('/api/admin/projects/default')
|
||||
.expect(200)
|
||||
.expect((r) => {
|
||||
expect(r.body.features[0].environments[0].name).toBe(':global:');
|
||||
expect(r.body.features[0].environments[0].name).toBe(DEFAULT_ENV);
|
||||
expect(r.body.features[0].environments[1].name).toBe(
|
||||
'project-overview',
|
||||
);
|
||||
@ -540,8 +541,8 @@ test('Should archive feature toggle', async () => {
|
||||
expect(toggle).toBeDefined();
|
||||
});
|
||||
|
||||
test('Can add strategy to feature toggle to default env', async () => {
|
||||
const envName = 'default';
|
||||
test('Can add strategy to feature toggle to a "some-env-2"', async () => {
|
||||
const envName = 'some-env-2';
|
||||
const featureName = 'feature.strategy.toggle';
|
||||
// Create environment
|
||||
await db.stores.environmentStore.create({
|
||||
|
@ -1,7 +1,7 @@
|
||||
import dbInit, { ITestDb } from '../../helpers/database-init';
|
||||
import { IUnleashTest, setupApp } from '../../helpers/test-helper';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import { GLOBAL_ENV } from '../../../../lib/types/environment';
|
||||
import { DEFAULT_ENV } from '../../../../lib/util/constants';
|
||||
|
||||
const importData = require('../../../examples/import.json');
|
||||
|
||||
@ -265,7 +265,7 @@ test('Roundtrip with strategies in multiple environments works', async () => {
|
||||
projectId,
|
||||
);
|
||||
await app.services.environmentService.addEnvironmentToProject(
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
projectId,
|
||||
);
|
||||
await app.services.featureToggleServiceV2.createFeatureToggle(
|
||||
@ -299,7 +299,7 @@ test('Roundtrip with strategies in multiple environments works', async () => {
|
||||
},
|
||||
projectId,
|
||||
featureName,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
);
|
||||
const data = await app.services.stateService.export({});
|
||||
await app.services.stateService.import({
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { IUnleashTest, setupApp } from '../../helpers/test-helper';
|
||||
import dbInit, { ITestDb } from '../../helpers/database-init';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import { DEFAULT_ENV } from '../../../../lib/util/constants';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
@ -153,6 +154,7 @@ test('Can filter features by namePrefix', async () => {
|
||||
|
||||
test('Can get strategies for specific environment', async () => {
|
||||
const featureName = 'test.feature.with.env';
|
||||
const env = DEFAULT_ENV;
|
||||
|
||||
// Create feature toggle
|
||||
await app.request.post('/api/admin/projects/default/features').send({
|
||||
@ -163,7 +165,7 @@ test('Can get strategies for specific environment', async () => {
|
||||
// Add global strategy
|
||||
await app.request
|
||||
.post(
|
||||
`/api/admin/projects/default/features/${featureName}/environments/:global:/strategies`,
|
||||
`/api/admin/projects/default/features/${featureName}/environments/${env}/strategies`,
|
||||
)
|
||||
.send({
|
||||
name: 'default',
|
||||
@ -198,7 +200,7 @@ test('Can get strategies for specific environment', async () => {
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
expect(res.body.name).toBe(featureName);
|
||||
expect(res.body.strategies).toHaveLength(2);
|
||||
expect(res.body.strategies).toHaveLength(1);
|
||||
expect(
|
||||
res.body.strategies.find((s) => s.name === 'custom1'),
|
||||
).toBeDefined();
|
||||
|
@ -3,6 +3,7 @@ import dbInit, { ITestDb } from '../../helpers/database-init';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import { ApiTokenService } from '../../../../lib/services/api-token-service';
|
||||
import { ApiTokenType } from '../../../../lib/types/models/api-token';
|
||||
import { DEFAULT_ENV } from '../../../../lib/util/constants';
|
||||
|
||||
let app: IUnleashTest;
|
||||
let db: ITestDb;
|
||||
@ -117,11 +118,11 @@ afterAll(async () => {
|
||||
await db.destroy();
|
||||
});
|
||||
|
||||
test('returns feature toggle with :global: config', async () => {
|
||||
test('returns feature toggle with "default" config', async () => {
|
||||
const token = await apiTokenService.createApiToken({
|
||||
type: ApiTokenType.CLIENT,
|
||||
username,
|
||||
environment: ':global:',
|
||||
environment: DEFAULT_ENV,
|
||||
project,
|
||||
});
|
||||
await app.request
|
||||
@ -157,7 +158,8 @@ test('returns feature toggle with testing environment config', async () => {
|
||||
const f2 = features.find((f) => f.name === feature2);
|
||||
|
||||
expect(features).toHaveLength(2);
|
||||
expect(f1.strategies).toHaveLength(2);
|
||||
expect(f1.strategies).toHaveLength(1);
|
||||
expect(f1.strategies[0].name).toBe('custom-testing');
|
||||
expect(f2.strategies).toHaveLength(1);
|
||||
expect(query.project[0]).toBe(project);
|
||||
expect(query.environment).toBe(environment);
|
||||
|
@ -10,6 +10,7 @@ import noLoggerProvider from '../../fixtures/no-logger';
|
||||
import EnvironmentStore from '../../../lib/db/environment-store';
|
||||
import { IUnleashStores } from '../../../lib/types';
|
||||
import { IFeatureEnvironmentStore } from '../../../lib/types/stores/feature-environment-store';
|
||||
import { DEFAULT_ENV } from '../../../lib/util/constants';
|
||||
|
||||
// require('db-migrate-shared').log.silence(false);
|
||||
|
||||
@ -54,7 +55,7 @@ function createTagTypes(store) {
|
||||
}
|
||||
|
||||
async function connectProject(store: IFeatureEnvironmentStore): Promise<void> {
|
||||
await store.connectProject(':global:', 'default');
|
||||
await store.connectProject(DEFAULT_ENV, 'default');
|
||||
}
|
||||
|
||||
async function createEnvironments(store: EnvironmentStore): Promise<void> {
|
||||
|
@ -29,8 +29,8 @@
|
||||
],
|
||||
"environments": [
|
||||
{
|
||||
"name": ":global:",
|
||||
"displayName": "Across all environments",
|
||||
"name": "default",
|
||||
"displayName": "Default Environment",
|
||||
"type": "production",
|
||||
"sortOrder": 1,
|
||||
"enabled": true,
|
||||
|
@ -38,7 +38,7 @@ test('Can get all', async () => {
|
||||
});
|
||||
|
||||
const environments = await service.getAll();
|
||||
expect(environments).toHaveLength(3); // the one we created plus ':global:'
|
||||
expect(environments).toHaveLength(3); // the one we created plus 'default'
|
||||
});
|
||||
|
||||
test('Can connect environment to project', async () => {
|
||||
|
@ -4,7 +4,7 @@ import FeatureToggleServiceV2 from '../../../lib/services/feature-toggle-service
|
||||
import { IStrategyConfig } from '../../../lib/types/model';
|
||||
import { createTestConfig } from '../../config/test-config';
|
||||
import dbInit from '../helpers/database-init';
|
||||
import { GLOBAL_ENV } from '../../../lib/types/environment';
|
||||
import { DEFAULT_ENV } from '../../../lib/util/constants';
|
||||
|
||||
let stores;
|
||||
let db;
|
||||
@ -80,7 +80,7 @@ test('Should be able to update existing strategy configuration', async () => {
|
||||
expect(createdConfig.name).toEqual('default');
|
||||
const updatedConfig = await service.updateStrategy(
|
||||
createdConfig.id,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
projectId,
|
||||
username,
|
||||
{
|
||||
@ -112,7 +112,7 @@ test('Should include legacy props in event log when updating strategy configurat
|
||||
await service.updateEnabled(
|
||||
'default',
|
||||
featureName,
|
||||
GLOBAL_ENV,
|
||||
DEFAULT_ENV,
|
||||
true,
|
||||
userName,
|
||||
);
|
||||
|
@ -1 +1,126 @@
|
||||
{"version":1,"features":[{"name":"in-another-project","description":"","type":"release","project":"someother","enabled":true,"stale":false,"strategies":[{"name":"gradualRolloutRandom","parameters":{"percentage":"29"},"constraints":[{"contextName":"environment","operator":"IN","values":["dev"]},{"contextName":"environment","operator":"IN","values":["prod"]}]}],"variants":[],"createdAt":"2021-09-17T07:14:03.718Z","lastSeenAt":null},{"name":"this-is-fun","description":"","type":"release","project":"default","enabled":true,"stale":false,"strategies":[{"name":"gradualRolloutRandom","parameters":{"percentage":"100"}}],"variants":[],"createdAt":"2021-09-17T07:06:40.925Z","lastSeenAt":null},{"name":"version.three.seventeen","description":"","type":"operational","project":"default","enabled":true,"stale":false,"strategies":[{"name":"default","parameters":{}}],"variants":[],"createdAt":"2021-09-17T07:06:56.421Z","lastSeenAt":null},{"name":"with-constraints","description":"","type":"release","project":"default","enabled":true,"stale":false,"strategies":[{"name":"default","parameters":{},"constraints":[{"contextName":"userId","operator":"IN","values":["123456"]}]}],"variants":[],"createdAt":"2021-09-17T07:14:39.509Z","lastSeenAt":null}],"strategies":[],"projects":[{"id":"default","name":"Default","description":"Default project","createdAt":"2021-09-17T05:06:16.299Z"},{"id":"someother","name":"Some other project","description":"","createdAt":"2021-09-17T05:13:45.011Z"}],"tagTypes":[{"name":"simple","description":"Used to simplify filtering of features","icon":"#"}],"tags":[],"featureTags":[]}
|
||||
{
|
||||
"version": 1,
|
||||
"features": [
|
||||
{
|
||||
"name": "in-another-project",
|
||||
"description": "",
|
||||
"type": "release",
|
||||
"project": "someother",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "29"
|
||||
},
|
||||
"constraints": [
|
||||
{
|
||||
"contextName": "environment",
|
||||
"operator": "IN",
|
||||
"values": [
|
||||
"dev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"contextName": "environment",
|
||||
"operator": "IN",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:14:03.718Z",
|
||||
"lastSeenAt": null
|
||||
},
|
||||
{
|
||||
"name": "this-is-fun",
|
||||
"description": "",
|
||||
"type": "release",
|
||||
"project": "default",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "100"
|
||||
}
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:06:40.925Z",
|
||||
"lastSeenAt": null
|
||||
},
|
||||
{
|
||||
"name": "version.three.seventeen",
|
||||
"description": "",
|
||||
"type": "operational",
|
||||
"project": "default",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "default",
|
||||
"parameters": {}
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:06:56.421Z",
|
||||
"lastSeenAt": null
|
||||
},
|
||||
{
|
||||
"name": "with-constraints",
|
||||
"description": "",
|
||||
"type": "release",
|
||||
"project": "default",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "default",
|
||||
"parameters": {},
|
||||
"constraints": [
|
||||
{
|
||||
"contextName": "userId",
|
||||
"operator": "IN",
|
||||
"values": [
|
||||
"123456"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:14:39.509Z",
|
||||
"lastSeenAt": null
|
||||
}
|
||||
],
|
||||
"strategies": [],
|
||||
"projects": [
|
||||
{
|
||||
"id": "default",
|
||||
"name": "Default",
|
||||
"description": "Default project",
|
||||
"createdAt": "2021-09-17T05:06:16.299Z"
|
||||
},
|
||||
{
|
||||
"id": "someother",
|
||||
"name": "Some other project",
|
||||
"description": "",
|
||||
"createdAt": "2021-09-17T05:13:45.011Z"
|
||||
}
|
||||
],
|
||||
"tagTypes": [
|
||||
{
|
||||
"name": "simple",
|
||||
"description": "Used to simplify filtering of features",
|
||||
"icon": "#"
|
||||
}
|
||||
],
|
||||
"tags": [],
|
||||
"featureTags": []
|
||||
}
|
@ -1 +1,198 @@
|
||||
{"version":1,"features":[{"name":"another-toggle","description":"","type":"release","project":"someother","enabled":true,"stale":false,"strategies":[{"name":"userWithId","parameters":{"userIds":"12541,123"},"constraints":[]}],"variants":[],"createdAt":"2021-09-17T07:22:16.404Z","lastSeenAt":null},{"name":"in-another-project","description":"","type":"release","project":"someother","enabled":true,"stale":false,"strategies":[{"name":"gradualRolloutRandom","parameters":{"percentage":"29"},"constraints":[{"contextName":"environment","operator":"IN","values":["dev"]},{"contextName":"environment","operator":"IN","values":["prod"]}]}],"variants":[],"createdAt":"2021-09-17T07:14:03.718Z","lastSeenAt":null},{"name":"this-is-fun","description":"","type":"release","project":"default","enabled":true,"stale":false,"strategies":[{"name":"gradualRolloutRandom","parameters":{"percentage":"100"}}],"variants":[],"createdAt":"2021-09-17T07:06:40.925Z","lastSeenAt":null},{"name":"version.three.seventeen","description":"","type":"operational","project":"default","enabled":true,"stale":false,"strategies":[{"name":"default","parameters":{}}],"variants":[],"createdAt":"2021-09-17T07:06:56.421Z","lastSeenAt":null},{"name":"with-constraints","description":"","type":"release","project":"default","enabled":true,"stale":false,"strategies":[{"name":"default","parameters":{},"constraints":[{"contextName":"userId","operator":"IN","values":["123456"]}]}],"variants":[],"createdAt":"2021-09-17T07:14:39.509Z","lastSeenAt":null}],"strategies":[{"name":"gradualRolloutRandom","description":"Randomly activate the feature toggle. No stickiness.","parameters":[{"name":"percentage","type":"percentage","description":"","required":false}],"deprecated":true},{"name":"gradualRolloutSessionId","description":"Gradually activate feature toggle. Stickiness based on session id.","parameters":[{"name":"percentage","type":"percentage","description":"","required":false},{"name":"groupId","type":"string","description":"Used to define a activation groups, which allows you to correlate across feature toggles.","required":true}],"deprecated":true},{"name":"gradualRolloutUserId","description":"Gradually activate feature toggle for logged in users. Stickiness based on user id.","parameters":[{"name":"percentage","type":"percentage","description":"","required":false},{"name":"groupId","type":"string","description":"Used to define a activation groups, which allows you to correlate across feature toggles.","required":true}],"deprecated":true}],"projects":[{"id":"default","name":"Default","description":"Default project","createdAt":"2021-09-17T05:06:16.299Z"},{"id":"someother","name":"Some other project","description":"","createdAt":"2021-09-17T05:13:45.011Z"}],"tagTypes":[{"name":"simple","description":"Used to simplify filtering of features","icon":"#"}],"tags":[],"featureTags":[]}
|
||||
{
|
||||
"version": 1,
|
||||
"features": [
|
||||
{
|
||||
"name": "another-toggle",
|
||||
"description": "",
|
||||
"type": "release",
|
||||
"project": "someother",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "userWithId",
|
||||
"parameters": {
|
||||
"userIds": "12541,123"
|
||||
},
|
||||
"constraints": []
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:22:16.404Z",
|
||||
"lastSeenAt": null
|
||||
},
|
||||
{
|
||||
"name": "in-another-project",
|
||||
"description": "",
|
||||
"type": "release",
|
||||
"project": "someother",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "29"
|
||||
},
|
||||
"constraints": [
|
||||
{
|
||||
"contextName": "environment",
|
||||
"operator": "IN",
|
||||
"values": [
|
||||
"dev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"contextName": "environment",
|
||||
"operator": "IN",
|
||||
"values": [
|
||||
"prod"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:14:03.718Z",
|
||||
"lastSeenAt": null
|
||||
},
|
||||
{
|
||||
"name": "this-is-fun",
|
||||
"description": "",
|
||||
"type": "release",
|
||||
"project": "default",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "100"
|
||||
}
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:06:40.925Z",
|
||||
"lastSeenAt": null
|
||||
},
|
||||
{
|
||||
"name": "version.three.seventeen",
|
||||
"description": "",
|
||||
"type": "operational",
|
||||
"project": "default",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "default",
|
||||
"parameters": {}
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:06:56.421Z",
|
||||
"lastSeenAt": null
|
||||
},
|
||||
{
|
||||
"name": "with-constraints",
|
||||
"description": "",
|
||||
"type": "release",
|
||||
"project": "default",
|
||||
"enabled": true,
|
||||
"stale": false,
|
||||
"strategies": [
|
||||
{
|
||||
"name": "default",
|
||||
"parameters": {},
|
||||
"constraints": [
|
||||
{
|
||||
"contextName": "userId",
|
||||
"operator": "IN",
|
||||
"values": [
|
||||
"123456"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"variants": [],
|
||||
"createdAt": "2021-09-17T07:14:39.509Z",
|
||||
"lastSeenAt": null
|
||||
}
|
||||
],
|
||||
"strategies": [
|
||||
{
|
||||
"name": "gradualRolloutRandom",
|
||||
"description": "Randomly activate the feature toggle. No stickiness.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "percentage",
|
||||
"type": "percentage",
|
||||
"description": "",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"deprecated": true
|
||||
},
|
||||
{
|
||||
"name": "gradualRolloutSessionId",
|
||||
"description": "Gradually activate feature toggle. Stickiness based on session id.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "percentage",
|
||||
"type": "percentage",
|
||||
"description": "",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "groupId",
|
||||
"type": "string",
|
||||
"description": "Used to define a activation groups, which allows you to correlate across feature toggles.",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"deprecated": true
|
||||
},
|
||||
{
|
||||
"name": "gradualRolloutUserId",
|
||||
"description": "Gradually activate feature toggle for logged in users. Stickiness based on user id.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "percentage",
|
||||
"type": "percentage",
|
||||
"description": "",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "groupId",
|
||||
"type": "string",
|
||||
"description": "Used to define a activation groups, which allows you to correlate across feature toggles.",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"deprecated": true
|
||||
}
|
||||
],
|
||||
"projects": [
|
||||
{
|
||||
"id": "default",
|
||||
"name": "Default",
|
||||
"description": "Default project",
|
||||
"createdAt": "2021-09-17T05:06:16.299Z"
|
||||
},
|
||||
{
|
||||
"id": "someother",
|
||||
"name": "Some other project",
|
||||
"description": "",
|
||||
"createdAt": "2021-09-17T05:13:45.011Z"
|
||||
}
|
||||
],
|
||||
"tagTypes": [
|
||||
{
|
||||
"name": "simple",
|
||||
"description": "Used to simplify filtering of features",
|
||||
"icon": "#"
|
||||
}
|
||||
],
|
||||
"tags": [],
|
||||
"featureTags": []
|
||||
}
|
@ -145,7 +145,7 @@
|
||||
"id": "2ea91298-4565-4db2-8a23-50757001a076",
|
||||
"featureName": "this-is-fun",
|
||||
"projectId": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "100"
|
||||
@ -157,7 +157,7 @@
|
||||
"id": "edaffaee-cf6e-473f-b137-ae15fb88ff53",
|
||||
"featureName": "version.three.seventeen",
|
||||
"projectId": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "default",
|
||||
"parameters": {},
|
||||
"constraints": [],
|
||||
@ -167,7 +167,7 @@
|
||||
"id": "e6eaede4-027a-41a9-8e80-0e0fc0a5d7af",
|
||||
"featureName": "in-another-project",
|
||||
"projectId": "someother",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "29"
|
||||
@ -194,7 +194,7 @@
|
||||
"id": "da60e934-246c-4b3e-b314-f2fd1828dd51",
|
||||
"featureName": "with-constraints",
|
||||
"projectId": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "default",
|
||||
"parameters": {},
|
||||
"constraints": [
|
||||
@ -212,7 +212,7 @@
|
||||
"id": "162058f5-3600-4299-97df-d543a0301bdd",
|
||||
"featureName": "another-toggle",
|
||||
"projectId": "someother",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "userWithId",
|
||||
"parameters": {
|
||||
"userIds": "12541,123"
|
||||
@ -224,7 +224,7 @@
|
||||
"id": "5630e0fb-ebc1-4313-b6df-06b0a563c7b4",
|
||||
"featureName": "toggle-created-in-4-1",
|
||||
"projectId": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "applicationHostname",
|
||||
"parameters": {
|
||||
"hostNames": "vg.no"
|
||||
@ -235,7 +235,7 @@
|
||||
],
|
||||
"environments": [
|
||||
{
|
||||
"name": ":global:",
|
||||
"name": "default",
|
||||
"displayName": "Across all environments",
|
||||
"type": "production"
|
||||
}
|
||||
@ -244,32 +244,32 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "this-is-fun",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "version.three.seventeen",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "in-another-project",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "with-constraints",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "another-toggle",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "toggle-created-in-4-1",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ exported412-enterprise.json{
|
||||
"id": "2ea91298-4565-4db2-8a23-50757001a076",
|
||||
"featureName": "this-is-fun",
|
||||
"projectName": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "100"
|
||||
@ -157,7 +157,7 @@ exported412-enterprise.json{
|
||||
"id": "edaffaee-cf6e-473f-b137-ae15fb88ff53",
|
||||
"featureName": "version.three.seventeen",
|
||||
"projectName": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "default",
|
||||
"parameters": {},
|
||||
"constraints": [],
|
||||
@ -167,7 +167,7 @@ exported412-enterprise.json{
|
||||
"id": "e6eaede4-027a-41a9-8e80-0e0fc0a5d7af",
|
||||
"featureName": "in-another-project",
|
||||
"projectName": "someother",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "gradualRolloutRandom",
|
||||
"parameters": {
|
||||
"percentage": "29"
|
||||
@ -194,7 +194,7 @@ exported412-enterprise.json{
|
||||
"id": "da60e934-246c-4b3e-b314-f2fd1828dd51",
|
||||
"featureName": "with-constraints",
|
||||
"projectName": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "default",
|
||||
"parameters": {},
|
||||
"constraints": [
|
||||
@ -212,7 +212,7 @@ exported412-enterprise.json{
|
||||
"id": "162058f5-3600-4299-97df-d543a0301bdd",
|
||||
"featureName": "another-toggle",
|
||||
"projectName": "someother",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "userWithId",
|
||||
"parameters": {
|
||||
"userIds": "12541,123"
|
||||
@ -224,7 +224,7 @@ exported412-enterprise.json{
|
||||
"id": "5630e0fb-ebc1-4313-b6df-06b0a563c7b4",
|
||||
"featureName": "toggle-created-in-4-1",
|
||||
"projectName": "default",
|
||||
"environment": ":global:",
|
||||
"environment": "default",
|
||||
"strategyName": "applicationHostname",
|
||||
"parameters": {
|
||||
"hostNames": "vg.no"
|
||||
@ -235,7 +235,7 @@ exported412-enterprise.json{
|
||||
],
|
||||
"environments": [
|
||||
{
|
||||
"name": ":global:",
|
||||
"name": "default",
|
||||
"displayName": "Across all environments"
|
||||
}
|
||||
],
|
||||
@ -243,32 +243,32 @@ exported412-enterprise.json{
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "this-is-fun",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "version.three.seventeen",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "in-another-project",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "with-constraints",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "another-toggle",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"featureName": "toggle-created-in-4-1",
|
||||
"environment": ":global:"
|
||||
"environment": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ In this document we will guide you on how you can work with feature toggles and
|
||||
- A feature toggle can take different configuration, activation strategies, per environment.
|
||||
|
||||
TODO: Need to explain the following in a bit more details:
|
||||
- The _:global:: environment
|
||||
- The _default_ environment
|
||||
|
||||
|
||||
> We will in this guide use [HTTPie](https://httpie.io) commands to show examples on how to interact with the API.
|
||||
|
Loading…
Reference in New Issue
Block a user