config-loader: remove support for conditionally reading secrets
This commit is contained in:
@@ -40,7 +40,6 @@ export async function loadBackendConfig(options: Options): Promise<Config> {
|
||||
env: process.env.APP_ENV ?? process.env.NODE_ENV ?? 'development',
|
||||
configRoot: paths.targetRoot,
|
||||
configPaths: configOpts.map(opt => resolvePath(opt)),
|
||||
shouldReadSecrets: true,
|
||||
});
|
||||
|
||||
options.logger.info(
|
||||
|
||||
@@ -18,14 +18,10 @@ import { loadConfig } from '@backstage/config-loader';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { paths } from './paths';
|
||||
|
||||
export async function loadCliConfig(
|
||||
configArgs: string[],
|
||||
shouldReadSecrets: boolean = false,
|
||||
) {
|
||||
export async function loadCliConfig(configArgs: string[]) {
|
||||
const configPaths = configArgs.map(arg => paths.resolveTarget(arg));
|
||||
|
||||
const appConfigs = await loadConfig({
|
||||
shouldReadSecrets,
|
||||
env: process.env.APP_ENV ?? process.env.NODE_ENV ?? 'production',
|
||||
configRoot: paths.targetRoot,
|
||||
configPaths,
|
||||
|
||||
@@ -28,7 +28,6 @@ function memoryFiles(files: { [path: string]: string }) {
|
||||
|
||||
const mockContext: ReaderContext = {
|
||||
env: {},
|
||||
skip: () => false,
|
||||
readFile: jest.fn(),
|
||||
readSecret: jest.fn(),
|
||||
};
|
||||
@@ -179,22 +178,4 @@ describe('readConfigFile', () => {
|
||||
|
||||
await expect(config).rejects.toThrow('Invalid secret at .app: NOPE');
|
||||
});
|
||||
|
||||
it('should omit skipped values', async () => {
|
||||
const readFile = memoryFiles({
|
||||
'./app-config.yaml': 'app: { title: skip, name: include }',
|
||||
});
|
||||
|
||||
const config = readConfigFile('./app-config.yaml', {
|
||||
...mockContext,
|
||||
readFile,
|
||||
skip: (path: string) => path === '.app.title',
|
||||
readSecret: jest.fn() as ReadSecretFunc,
|
||||
});
|
||||
|
||||
await expect(config).resolves.toEqual({
|
||||
context: 'app-config.yaml',
|
||||
data: { app: { name: 'include' } },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,10 +37,6 @@ export async function readConfigFile(
|
||||
obj: JsonValue,
|
||||
path: string,
|
||||
): Promise<JsonValue | undefined> {
|
||||
if (ctx.skip(path)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (typeof obj !== 'object') {
|
||||
return obj;
|
||||
} else if (obj === null) {
|
||||
|
||||
@@ -21,7 +21,6 @@ const ctx: ReaderContext = {
|
||||
env: {
|
||||
SECRET: 'my-secret',
|
||||
},
|
||||
skip: () => false,
|
||||
readSecret: jest.fn(),
|
||||
async readFile(path) {
|
||||
const content = ({
|
||||
|
||||
@@ -28,7 +28,6 @@ export type SkipFunc = (path: string) => boolean;
|
||||
*/
|
||||
export type ReaderContext = {
|
||||
env: { [name in string]?: string };
|
||||
skip: SkipFunc;
|
||||
readFile: ReadFileFunc;
|
||||
readSecret: ReadSecretFunc;
|
||||
};
|
||||
|
||||
@@ -44,47 +44,6 @@ describe('loadConfig', () => {
|
||||
configRoot: '/root',
|
||||
configPaths: [],
|
||||
env: 'production',
|
||||
shouldReadSecrets: false,
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('loads config without secrets', async () => {
|
||||
await expect(
|
||||
loadConfig({
|
||||
configRoot: '/root',
|
||||
configPaths: ['/root/app-config.yaml'],
|
||||
env: 'production',
|
||||
shouldReadSecrets: false,
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
context: 'app-config.yaml',
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('loads config with secrets', async () => {
|
||||
await expect(
|
||||
loadConfig({
|
||||
configRoot: '/root',
|
||||
configPaths: ['/root/app-config.yaml'],
|
||||
env: 'production',
|
||||
shouldReadSecrets: true,
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
@@ -99,16 +58,12 @@ describe('loadConfig', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('loads development config without secrets', async () => {
|
||||
it('loads config with secrets', async () => {
|
||||
await expect(
|
||||
loadConfig({
|
||||
configRoot: '/root',
|
||||
configPaths: [
|
||||
'/root/app-config.yaml',
|
||||
'/root/app-config.development.yaml',
|
||||
],
|
||||
env: 'development',
|
||||
shouldReadSecrets: false,
|
||||
configPaths: ['/root/app-config.yaml'],
|
||||
env: 'production',
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
@@ -116,15 +71,10 @@ describe('loadConfig', () => {
|
||||
data: {
|
||||
app: {
|
||||
title: 'Example App',
|
||||
sessionKey: 'abc123',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
context: 'app-config.development.yaml',
|
||||
data: {
|
||||
app: {},
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -137,7 +87,6 @@ describe('loadConfig', () => {
|
||||
'/root/app-config.development.yaml',
|
||||
],
|
||||
env: 'development',
|
||||
shouldReadSecrets: true,
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
|
||||
@@ -28,18 +28,13 @@ export type LoadConfigOptions = {
|
||||
|
||||
// TODO(Rugvip): This will be removed in the future, but for now we use it to warn about possible mistakes.
|
||||
env: string;
|
||||
|
||||
// Whether to read secrets or omit them, defaults to false.
|
||||
shouldReadSecrets?: boolean;
|
||||
};
|
||||
|
||||
class Context {
|
||||
constructor(
|
||||
private readonly options: {
|
||||
secretPaths: Set<string>;
|
||||
env: { [name in string]?: string };
|
||||
rootPath: string;
|
||||
shouldReadSecrets: boolean;
|
||||
},
|
||||
) {}
|
||||
|
||||
@@ -47,35 +42,21 @@ class Context {
|
||||
return this.options.env;
|
||||
}
|
||||
|
||||
skip(path: string): boolean {
|
||||
if (this.options.shouldReadSecrets) {
|
||||
return false;
|
||||
}
|
||||
return this.options.secretPaths.has(path);
|
||||
}
|
||||
|
||||
async readFile(path: string): Promise<string> {
|
||||
return fs.readFile(resolvePath(this.options.rootPath, path), 'utf8');
|
||||
}
|
||||
|
||||
async readSecret(
|
||||
path: string,
|
||||
_path: string,
|
||||
desc: JsonObject,
|
||||
): Promise<string | undefined> {
|
||||
this.options.secretPaths.add(path);
|
||||
if (!this.options.shouldReadSecrets) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return readSecret(desc, this);
|
||||
}
|
||||
}
|
||||
|
||||
type LoadedConfig = AppConfig[];
|
||||
|
||||
export async function loadConfig(
|
||||
options: LoadConfigOptions,
|
||||
): Promise<LoadedConfig> {
|
||||
): Promise<AppConfig[]> {
|
||||
const configs = [];
|
||||
const { configRoot } = options;
|
||||
const configPaths = options.configPaths.slice();
|
||||
@@ -102,8 +83,6 @@ export async function loadConfig(
|
||||
}
|
||||
|
||||
try {
|
||||
const secretPaths = new Set<string>();
|
||||
|
||||
for (const configPath of configPaths) {
|
||||
if (!isAbsolute(configPath)) {
|
||||
throw new Error(`Config load path is not absolute: '${configPath}'`);
|
||||
@@ -111,10 +90,8 @@ export async function loadConfig(
|
||||
const config = await readConfigFile(
|
||||
configPath,
|
||||
new Context({
|
||||
secretPaths,
|
||||
env: process.env,
|
||||
rootPath: dirname(configPath),
|
||||
shouldReadSecrets: Boolean(options.shouldReadSecrets),
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user