UNPKG

sardines-built-in-services

Version:
186 lines (168 loc) 5.38 kB
/** * @author Robin Sun * @email robin@naturewake.com * @create date 2020-06-15 14:42:59 * @modify date 2020-06-15 14:42:59 * @desc config nginx server to be a reverse proxy server * @desc nginx doc: https://nginx.org/en/docs/ */ import { exec } from 'child_process' import * as fs from 'fs' // import * as path from 'path' // import { Http } from 'sardines-core' const execCmd = async (cmd: string) => { return new Promise((res, rej) => { exec(cmd, (error, stdout, stderr) => { if (error) { const errMsg = `error while executing shell command [${cmd}]: ${error.message}; stdout: ${stdout}, stderr: ${stderr}` rej(errMsg); } if (stderr) { const errMsg = `stderr output of shell command [${cmd}]: ${stderr}` rej(errMsg) } res(stdout) }); }) } export interface ServiceRuntimeIdentityInHttpReverseProxy { application: string, module: string, name: string, version: string, method?: string, tags?: string[], source: { server: string port: number } priority?: number, target: { server: string port: number } } export interface NginxConfig { user?: string worker_processes?: number worker_connections?: number default_type?: string sendfile?: string keepalive_timeout?: number pid?: string types?: string tcp_nopush?: string gzip?: string servers?: string error_log?: string access_log?: string log_format?: string[] } export const defaultNginxConfig: NginxConfig = { user: 'nginx', worker_processes: 1, error_log: '/var/log/nginx/error.log', pid: '/var/run/nginx.pid', worker_connections: 1024, types: '/etc/nginx/mime.types', default_type: 'application/octet-stream', log_format: [ '\'$remote_addr - $remote_user [$time_local] "$request"\'', '\'$status $body_bytes_sent "$http_referer"\'', '\'"$http_user_agent" "$http_x_forwarded_for"\'' ], access_log: '/var/log/nginx/access.log', sendfile: 'on', tcp_nopush: 'off', keepalive_timeout: 65, gzip: 'on', servers: '/etc/nginx/conf.d/*.conf' } const generateNginxConfigFile = async (configFilePath: string = '/etc/nginx/nginx.conf', configSettings: NginxConfig = defaultNginxConfig) => { const config: NginxConfig = Object.assign({}, defaultNginxConfig, configSettings) if (!fs.existsSync(configFilePath)) { throw `Can not access nginx config file [${configFilePath}]` } let content: string = ` user ${config.user}; worker_processes ${config.worker_processes}; error_log ${config.error_log} warn; pid ${config.pid}; events { worker_connections ${config.worker_connections}; } http { include ${config.types}; default_type ${config.default_type}; log_format main ${config.log_format!.join('\n\t\t')}; access_log ${config.access_log} main; sendfile ${config.sendfile}; tcp_nopush ${config.tcp_nopush}; gzip ${config.gzip}; include ${config.servers}; } ` fs.writeFileSync(configFilePath, content, {encoding: 'utf8'}) } export class NginxReverseProxy { private nginxConfigFilePath: string private nginxConfigDir: string private nginxConfig: NginxConfig public sslCrt: string public sslKey: string constructor( nginxConfigSettings: NginxConfig = defaultNginxConfig, nginxConfigFilePath:string = '/etc/nginx/nginx.conf', nginxConfigDir: string = '/etc/nginx/conf.d/', sslCrtLines: string[], sslKeyLines: string[] ) { this.nginxConfigFilePath = nginxConfigFilePath this.nginxConfigDir = nginxConfigDir this.nginxConfig = Object.assign({}, defaultNginxConfig, nginxConfigSettings) if (sslCrtLines && sslCrtLines.length) { this.sslCrt = sslCrtLines.join('\n') } else { this.sslCrt = '' } if (sslKeyLines && sslKeyLines.length) { this.sslKey = sslKeyLines.join('\n') } else { this.sslKey = '' } } public async exec(cmd:string) { return await execCmd(cmd) } public async start(option: {initalizeConfigFile: boolean} = {initalizeConfigFile: false}) { // check the nginx config file if (!fs.existsSync(this.nginxConfigFilePath)) { throw (`Nginx configuration file [${this.nginxConfigFilePath}] does not exist`) } if (!fs.existsSync(this.nginxConfigDir)) { // throw (`Nginx configuration directory [${this.nginxConfigDir}] does not exist`) await execCmd(`mkdir -p ${this.nginxConfigDir}`) } await execCmd('/usr/sbin/service nginx stop') // generate the config file using the initialization parameters if (option.initalizeConfigFile) { await generateNginxConfigFile(this.nginxConfigFilePath, this.nginxConfig) } // restart nginx service let restartResult: any = '' try { restartResult = await execCmd(`/usr/sbin/service nginx start`) } catch(e) { restartResult = await execCmd('/usr/sbin/service nginx status') if (restartResult === 'nginx is running.\n') { return true } } throw `nginx is not started` } // private getPathForServiceRuntime(sr: ServiceRuntimeIdentityInReverseProxy) { // return `/${this.root}/${sr.application}/${sr.module}/${sr.name}`.replace(/\/\//g, '/') // } // public loadServiceRuntimes(arrayOfServiceRuntimes: ServiceRuntimeIdentityInReverseProxy[], auth: any) { // } }