feat(backend-common): Pass the redaction map from the backend config-loader to the logger

Signed-off-by: Harry Hogg <hhogg@spotify.com>
This commit is contained in:
Harry Hogg
2021-09-29 12:00:25 +01:00
parent a2b66f2f4d
commit 94929707e9
3 changed files with 43 additions and 8 deletions
+1
View File
@@ -36,6 +36,7 @@
"@backstage/integration": "^0.6.7",
"@backstage/types": "^0.1.1",
"@google-cloud/storage": "^5.8.0",
"@lerna/project": "^4.0.0",
"@octokit/rest": "^18.5.3",
"@types/cors": "^2.8.6",
"@types/dockerode": "^3.2.1",
+41 -6
View File
@@ -18,10 +18,40 @@ import { resolve as resolvePath } from 'path';
import parseArgs from 'minimist';
import { Logger } from 'winston';
import { findPaths } from '@backstage/cli-common';
import { Config, ConfigReader } from '@backstage/config';
import { JsonValue } from '@backstage/types';
import { loadConfig } from '@backstage/config-loader';
import { setRootLoggerFilteredKeys } from './logging';
import { loadConfigSchema, loadConfig } from '@backstage/config-loader';
import { AppConfig, Config, ConfigReader, JsonValue } from '@backstage/config';
import { setRedactionMap } from './logging';
// Fetch the schema and get all the secrets to pass to the rootLogger for redaction
const updateRedactionMap = async (configs: AppConfig[], logger: Logger) => {
// Consider all packages in the monorepo when loading in config
const { Project } = require('@lerna/project');
const project = new Project();
const packages = await project.getPackages();
const localPackageNames = packages.map((p: any) => p.name);
const schema = await loadConfigSchema({ dependencies: localPackageNames });
const secretAppConfigs = schema.process(configs, { visibility: ['secret'] });
const secretConfig = ConfigReader.fromConfigs(secretAppConfigs);
const configMap = secretConfig.getMap();
logger.info(
`${
Object.keys(configMap).length
} secrets found in the config which will be redacted`,
);
setRedactionMap(
Object.entries(configMap).reduce<Record<any, string>>(
(map, [key, value]) => {
map[value] = key;
return map;
},
{},
),
);
};
export class ObservableConfigProxy implements Config {
private config: Config = new ConfigReader({});
@@ -90,6 +120,9 @@ export class ObservableConfigProxy implements Config {
get<T = JsonValue>(key?: string): T {
return this.select(true).get(key);
}
getMap() {
return this.config.getMap();
}
getOptional<T = JsonValue>(key?: string): T | undefined {
return this.select(false)?.getOptional(key);
}
@@ -161,12 +194,13 @@ export async function loadBackendConfig(options: {
configRoot: paths.targetRoot,
configPaths: configPaths.map(opt => resolvePath(opt)),
watch: {
onChange(newConfigs) {
async onChange(newConfigs) {
options.logger.info(
`Reloaded config from ${newConfigs.map(c => c.context).join(', ')}`,
);
config.setConfig(ConfigReader.fromConfigs(newConfigs));
await updateRedactionMap(configs, options.logger);
},
stopSignal: new Promise(resolve => {
if (currentCancelFunc) {
@@ -187,6 +221,7 @@ export async function loadBackendConfig(options: {
);
config.setConfig(ConfigReader.fromConfigs(configs));
setRootLoggerFilteredKeys({ 'secret-1': 'GOATS', 'secret-2': 'SHARKS' });
await updateRedactionMap(configs, options.logger);
return config;
}
+1 -2
View File
@@ -86,9 +86,8 @@ async function main() {
argv: process.argv,
logger,
});
const createEnv = makeCreateEnv(config);
logger.info('hiiiii secret-1');
const createEnv = makeCreateEnv(config);
const healthcheckEnv = useHotMemoize(module, () => createEnv('healthcheck'));
const catalogEnv = useHotMemoize(module, () => createEnv('catalog'));