mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: file import (#7219)
This commit is contained in:
parent
6340ecd6bf
commit
80ba3647a6
@ -164,9 +164,9 @@ exports[`should create default config 1`] = `
|
|||||||
],
|
],
|
||||||
"getLogger": [Function],
|
"getLogger": [Function],
|
||||||
"import": {
|
"import": {
|
||||||
"dropBeforeImport": false,
|
"environment": "development",
|
||||||
"file": undefined,
|
"file": undefined,
|
||||||
"keepExisting": false,
|
"project": "default",
|
||||||
},
|
},
|
||||||
"inlineSegmentConstraints": true,
|
"inlineSegmentConstraints": true,
|
||||||
"isEnterprise": false,
|
"isEnterprise": false,
|
||||||
|
@ -333,11 +333,8 @@ const defaultAuthentication: IAuthOption = {
|
|||||||
|
|
||||||
const defaultImport: WithOptional<IImportOption, 'file'> = {
|
const defaultImport: WithOptional<IImportOption, 'file'> = {
|
||||||
file: process.env.IMPORT_FILE,
|
file: process.env.IMPORT_FILE,
|
||||||
dropBeforeImport: parseEnvVarBoolean(
|
project: process.env.IMPORT_PROJECT ?? 'default',
|
||||||
process.env.IMPORT_DROP_BEFORE_IMPORT,
|
environment: process.env.IMPORT_ENVIRONMENT ?? 'development',
|
||||||
false,
|
|
||||||
),
|
|
||||||
keepExisting: parseEnvVarBoolean(process.env.IMPORT_KEEP_EXISTING, false),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultEmail: IEmailOption = {
|
const defaultEmail: IEmailOption = {
|
||||||
|
@ -5,6 +5,8 @@ import type { IFeatureStrategiesStore } from '../feature-toggle/types/feature-to
|
|||||||
import {
|
import {
|
||||||
FeaturesExportedEvent,
|
FeaturesExportedEvent,
|
||||||
FeaturesImportedEvent,
|
FeaturesImportedEvent,
|
||||||
|
SYSTEM_USER,
|
||||||
|
SYSTEM_USER_AUDIT,
|
||||||
type FeatureToggleDTO,
|
type FeatureToggleDTO,
|
||||||
type IAuditUser,
|
type IAuditUser,
|
||||||
type IContextFieldStore,
|
type IContextFieldStore,
|
||||||
@ -55,6 +57,7 @@ import type { IDependentFeaturesReadModel } from '../dependent-features/dependen
|
|||||||
import groupBy from 'lodash.groupby';
|
import groupBy from 'lodash.groupby';
|
||||||
import { allSettledWithRejection } from '../../util/allSettledWithRejection';
|
import { allSettledWithRejection } from '../../util/allSettledWithRejection';
|
||||||
import type { ISegmentReadModel } from '../segment/segment-read-model-type';
|
import type { ISegmentReadModel } from '../segment/segment-read-model-type';
|
||||||
|
import { readFile } from './import-file-reader';
|
||||||
|
|
||||||
export type IImportService = {
|
export type IImportService = {
|
||||||
validate(
|
validate(
|
||||||
@ -67,6 +70,12 @@ export type IImportService = {
|
|||||||
user: IUser,
|
user: IUser,
|
||||||
auditUser: IAuditUser,
|
auditUser: IAuditUser,
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
|
importFromFile(
|
||||||
|
file: string,
|
||||||
|
project: string,
|
||||||
|
environment: string,
|
||||||
|
): Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IExportService = {
|
export type IExportService = {
|
||||||
@ -264,6 +273,16 @@ export default class ExportImportService
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fileImportVerify(dto: ImportTogglesSchema): Promise<void> {
|
||||||
|
await allSettledWithRejection([
|
||||||
|
this.verifyStrategies(dto),
|
||||||
|
this.verifyContextFields(dto),
|
||||||
|
this.verifyFeatures(dto),
|
||||||
|
this.verifySegments(dto),
|
||||||
|
this.verifyDependencies(dto),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
async importFeatureData(
|
async importFeatureData(
|
||||||
dto: ImportTogglesSchema,
|
dto: ImportTogglesSchema,
|
||||||
auditUser: IAuditUser,
|
auditUser: IAuditUser,
|
||||||
@ -281,16 +300,40 @@ export default class ExportImportService
|
|||||||
auditUser: IAuditUser,
|
auditUser: IAuditUser,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const cleanedDto = await this.cleanData(dto);
|
const cleanedDto = await this.cleanData(dto);
|
||||||
|
|
||||||
await this.importVerify(cleanedDto, user);
|
await this.importVerify(cleanedDto, user);
|
||||||
|
await this.processImport(cleanedDto, user, auditUser);
|
||||||
|
}
|
||||||
|
|
||||||
await this.importFeatureData(cleanedDto, auditUser);
|
async importFromFile(
|
||||||
|
file: string,
|
||||||
|
project: string,
|
||||||
|
environment: string,
|
||||||
|
): Promise<void> {
|
||||||
|
const content = await readFile(file);
|
||||||
|
const data = JSON.parse(content);
|
||||||
|
const dto = {
|
||||||
|
project,
|
||||||
|
environment,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
const cleanedDto = await this.cleanData(dto);
|
||||||
|
|
||||||
await this.importEnvironmentData(cleanedDto, user, auditUser);
|
await this.fileImportVerify(cleanedDto);
|
||||||
|
await this.processImport(cleanedDto, SYSTEM_USER, SYSTEM_USER_AUDIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async processImport(
|
||||||
|
dto: ImportTogglesSchema,
|
||||||
|
user: IUser,
|
||||||
|
auditUser: IAuditUser,
|
||||||
|
) {
|
||||||
|
await this.importFeatureData(dto, auditUser);
|
||||||
|
|
||||||
|
await this.importEnvironmentData(dto, user, auditUser);
|
||||||
await this.eventService.storeEvent(
|
await this.eventService.storeEvent(
|
||||||
new FeaturesImportedEvent({
|
new FeaturesImportedEvent({
|
||||||
project: cleanedDto.project,
|
project: dto.project,
|
||||||
environment: cleanedDto.environment,
|
environment: dto.environment,
|
||||||
auditUser,
|
auditUser,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
export const readFile: (file: string) => Promise<string> = async (file) =>
|
||||||
|
new Promise((resolve, reject) =>
|
||||||
|
fs.readFile(file, (err, v) =>
|
||||||
|
err ? reject(err) : resolve(v.toString('utf-8')),
|
||||||
|
),
|
||||||
|
);
|
@ -97,7 +97,11 @@ async function createApp(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (config.import.file) {
|
if (config.import.file) {
|
||||||
// TODO: stateservice was here
|
await services.importService.importFromFile(
|
||||||
|
config.import.file,
|
||||||
|
config.import.project,
|
||||||
|
config.import.environment,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -81,8 +81,8 @@ export interface IAuthOption {
|
|||||||
|
|
||||||
export interface IImportOption {
|
export interface IImportOption {
|
||||||
file: string;
|
file: string;
|
||||||
keepExisting: boolean;
|
project: string;
|
||||||
dropBeforeImport: boolean;
|
environment: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IServerOption {
|
export interface IServerOption {
|
||||||
|
Loading…
Reference in New Issue
Block a user