feat(database): support read ssl file in database config (#2689)

This commit is contained in:
ChengLei Shao 2023-09-21 11:55:18 +08:00 committed by GitHub
parent 10e46b21f0
commit de849b267c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 63 deletions

View File

@ -6,7 +6,9 @@
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"dependencies": {
"@nocobase/preset-nocobase": "0.14.0-alpha.3"
"@nocobase/preset-nocobase": "0.14.0-alpha.3",
"@nocobase/server": "0.14.0-alpha.3",
"@nocobase/database": "0.14.0-alpha.3"
},
"devDependencies": {
"@nocobase/client": "0.14.0-alpha.3"

View File

@ -1,52 +1,5 @@
import { IDatabaseOptions } from '@nocobase/database';
import { parseDatabaseOptionsFromEnv } from '@nocobase/database';
function getEnvValue(key, defaultValue?) {
return process.env[key] || defaultValue;
}
function extractSSLOptionsFromEnv() {
const sslOptions = {};
const ca = getEnvValue('DB_DIALECT_OPTIONS_SSL_CA');
const key = getEnvValue('DB_DIALECT_OPTIONS_SSL_KEY');
const cert = getEnvValue('DB_DIALECT_OPTIONS_SSL_CERT');
const rejectUnauthorized = getEnvValue('DB_DIALECT_OPTIONS_SSL_REJECT_UNAUTHORIZED');
if (ca) sslOptions['ca'] = ca;
if (key) sslOptions['key'] = key;
if (cert) sslOptions['cert'] = cert;
if (rejectUnauthorized) sslOptions['rejectUnauthorized'] = rejectUnauthorized === 'true';
return sslOptions;
}
const databaseOptions = {
logging: process.env.DB_LOGGING == 'on' ? customLogger : false,
dialect: process.env.DB_DIALECT as any,
storage: process.env.DB_STORAGE,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
host: process.env.DB_HOST,
port: process.env.DB_PORT as any,
timezone: process.env.DB_TIMEZONE,
tablePrefix: process.env.DB_TABLE_PREFIX,
schema: process.env.DB_SCHEMA,
underscored: process.env.DB_UNDERSCORED === 'true',
} as IDatabaseOptions;
const sslOptions = extractSSLOptionsFromEnv();
if (Object.keys(sslOptions).length) {
databaseOptions.dialectOptions = databaseOptions.dialectOptions || {};
databaseOptions.dialectOptions['ssl'] = sslOptions;
}
export default databaseOptions;
function customLogger(queryString, queryObject) {
console.log(queryString); // outputs a string
if (queryObject?.bind) {
console.log(queryObject.bind); // outputs an array
}
export async function parseDatabaseOptions() {
return await parseDatabaseOptionsFromEnv();
}

View File

@ -1,13 +1,15 @@
import cache from './cache';
import database from './database';
import { parseDatabaseOptions } from './database';
import logger from './logger';
import plugins from './plugins';
import resourcer from './resourcer';
export default {
database,
resourcer,
plugins,
cache,
logger,
};
export async function getConfig() {
return {
database: await parseDatabaseOptions(),
resourcer,
plugins,
cache,
logger,
};
}

View File

@ -1,6 +1,12 @@
import { Gateway } from '@nocobase/server';
import config from './config';
import { getConfig } from './config';
Gateway.getInstance().run({
mainAppOptions: config,
});
getConfig()
.then((config) => {
return Gateway.getInstance().run({
mainAppOptions: config,
});
})
.catch((e) => {
console.error(e);
});

View File

@ -0,0 +1,92 @@
import { IDatabaseOptions } from './database';
import fs from 'fs';
function getEnvValue(key, defaultValue?) {
return process.env[key] || defaultValue;
}
function isFilePath(value) {
return fs.promises
.stat(value)
.then((stats) => stats.isFile())
.catch((err) => {
if (err.code === 'ENOENT') {
return false;
}
throw err;
});
}
function getValueOrFileContent(envVarName) {
const value = getEnvValue(envVarName);
if (!value) {
return Promise.resolve(null);
}
return isFilePath(value)
.then((isFile) => {
if (isFile) {
return fs.promises.readFile(value, 'utf8');
}
return value;
})
.catch((error) => {
console.error(`Failed to read file content for environment variable ${envVarName}.`);
throw error;
});
}
function extractSSLOptionsFromEnv() {
return Promise.all([
getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_MODE'),
getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_CA'),
getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_KEY'),
getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_CERT'),
getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_REJECT_UNAUTHORIZED'),
]).then(([mode, ca, key, cert, rejectUnauthorized]) => {
const sslOptions = {};
if (mode) sslOptions['mode'] = mode;
if (ca) sslOptions['ca'] = ca;
if (key) sslOptions['key'] = key;
if (cert) sslOptions['cert'] = cert;
if (rejectUnauthorized) sslOptions['rejectUnauthorized'] = rejectUnauthorized === 'true';
return sslOptions;
});
}
export async function parseDatabaseOptionsFromEnv(): Promise<IDatabaseOptions> {
const databaseOptions: IDatabaseOptions = {
logging: process.env.DB_LOGGING == 'on' ? customLogger : false,
dialect: process.env.DB_DIALECT as any,
storage: process.env.DB_STORAGE,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
host: process.env.DB_HOST,
port: process.env.DB_PORT as any,
timezone: process.env.DB_TIMEZONE,
tablePrefix: process.env.DB_TABLE_PREFIX,
schema: process.env.DB_SCHEMA,
underscored: process.env.DB_UNDERSCORED === 'true',
};
const sslOptions = await extractSSLOptionsFromEnv();
if (Object.keys(sslOptions).length) {
databaseOptions.dialectOptions = databaseOptions.dialectOptions || {};
databaseOptions.dialectOptions['ssl'] = sslOptions;
}
return databaseOptions;
}
function customLogger(queryString, queryObject) {
console.log(queryString);
if (queryObject?.bind) {
console.log(queryObject.bind);
}
}

View File

@ -41,3 +41,4 @@ export { snakeCase } from './utils';
export * from './value-parsers';
export * from './view-collection';
export * from './view/view-inference';
export * from './helpers';