138 lines
4.5 KiB
TypeScript
138 lines
4.5 KiB
TypeScript
import * as plugins from './smartnginx.plugins';
|
|
import * as paths from './smartnginx.paths';
|
|
import * as snippets from './smartnginx.snippets';
|
|
import { NginxHost } from './smartnginx.classes.nginxhost';
|
|
import { NginxProcess } from './smartnginx.classes.nginxprocess';
|
|
import { IHostConfig } from './interfaces/hostconfig';
|
|
|
|
export interface ISmartNginxContructorOptions {
|
|
logger?: plugins.smartlog.Smartlog;
|
|
defaultProxyUrl: string;
|
|
}
|
|
|
|
/**
|
|
* main class that manages a NginxInstance
|
|
*/
|
|
export class SmartNginx {
|
|
public options: ISmartNginxContructorOptions;
|
|
public logger: plugins.smartlog.Smartlog;
|
|
|
|
// the objectmaps
|
|
private deployedHosts = new plugins.lik.Objectmap<NginxHost>();
|
|
private hostCandidates = new plugins.lik.Objectmap<NginxHost>();
|
|
|
|
public nginxProcess: NginxProcess = new NginxProcess(this);
|
|
constructor(optionsArg: ISmartNginxContructorOptions) {
|
|
this.options = optionsArg;
|
|
this.options.logger
|
|
? (this.logger = this.options.logger)
|
|
: (this.logger = plugins.smartlog.defaultLogger);
|
|
}
|
|
|
|
// ===================
|
|
// interact with Hosts
|
|
// ===================
|
|
|
|
/**
|
|
* add a host
|
|
* @param nginxHostArg
|
|
*/
|
|
public addHostCandidate(optionsArg: IHostConfig): NginxHost {
|
|
const nginxHost = new NginxHost(this, optionsArg);
|
|
this.hostCandidates.add(nginxHost);
|
|
return nginxHost;
|
|
}
|
|
|
|
/**
|
|
* Gets a NginxHost by hostname
|
|
* @param hostNameArg
|
|
*/
|
|
public getDeployedNginxHostByHostName(hostNameArg: string): NginxHost {
|
|
return this.deployedHosts.find(nginxHost => {
|
|
return nginxHost.hostName === hostNameArg;
|
|
});
|
|
}
|
|
/**
|
|
* listHosts
|
|
*/
|
|
public async listDeployedHosts(): Promise<NginxHost[]> {
|
|
return this.deployedHosts.getArray();
|
|
}
|
|
|
|
/**
|
|
* remove a Host
|
|
* @param nginxHostArg
|
|
*/
|
|
public async removeDeployedHost(nginxHostArg: NginxHost) {
|
|
if (this.hostCandidates.isEmpty()) {
|
|
this.deployedHosts.forEach(hostArg => {
|
|
this.hostCandidates.add(hostArg);
|
|
});
|
|
}
|
|
this.hostCandidates.remove(nginxHostArg);
|
|
this.deploy();
|
|
}
|
|
|
|
/**
|
|
* check wether there has been a diverging host configuration
|
|
* this function will only redeploy the nginx configuration in case there has been a change
|
|
*/
|
|
private async areHostsDiverged(): Promise<boolean> {
|
|
let hostCounter = 0;
|
|
let unfoundHosts = 0;
|
|
await this.hostCandidates.forEach(async hostCandidateArg => {
|
|
let foundHost = false;
|
|
await this.deployedHosts.forEach(async deployedHostArg => {
|
|
if (
|
|
hostCandidateArg.hostName === deployedHostArg.hostName &&
|
|
hostCandidateArg.destination === deployedHostArg.destination &&
|
|
hostCandidateArg.destinationPort === deployedHostArg.destinationPort
|
|
) {
|
|
hostCounter++;
|
|
foundHost = true;
|
|
}
|
|
});
|
|
if (!foundHost) {
|
|
unfoundHosts++;
|
|
}
|
|
});
|
|
return (
|
|
this.deployedHosts.getArray().length !== this.hostCandidates.getArray().length ||
|
|
hostCounter !== this.deployedHosts.getArray().length ||
|
|
unfoundHosts !== 0
|
|
);
|
|
}
|
|
|
|
/**
|
|
* deploy the current stack and restart nginx
|
|
*/
|
|
public async deploy() {
|
|
if (await this.areHostsDiverged()) {
|
|
this.logger.log('ok', `hosts have diverged, trigger config deployment and nginx reload!`);
|
|
this.deployedHosts.wipe();
|
|
this.deployedHosts.addArray(this.hostCandidates.getArray());
|
|
this.hostCandidates.wipe();
|
|
|
|
// write base config
|
|
plugins.smartfile.fs.ensureDirSync(paths.nginxConfigDirPath);
|
|
plugins.smartfile.memory.toFsSync(snippets.getBaseConfigString(this.options.defaultProxyUrl), paths.nginxConfFile);
|
|
|
|
// write standard self signed certificate
|
|
const selfsignedCert = plugins.selfsigned.generate([{ name: 'commonName', value: 'selfsigned.git.zone' }], { days: 365});
|
|
plugins.smartfile.memory.toFsSync(selfsignedCert.private, plugins.path.join(paths.nginxConfigDirPath, './default.private.pem'));
|
|
plugins.smartfile.memory.toFsSync(selfsignedCert.public, plugins.path.join(paths.nginxConfigDirPath, './default.public.pem'));
|
|
|
|
// deploy hosts
|
|
plugins.smartfile.fs.ensureEmptyDirSync(paths.nginxHostDirPath);
|
|
for (const host of this.deployedHosts.getArray()) {
|
|
await host.deploy();
|
|
this.logger.log('info', `Host ${host.hostName} deployed!`);
|
|
}
|
|
this.nginxProcess.reloadConfig();
|
|
} else {
|
|
this.logger.log('info', `hosts have not diverged, skipping nginx reload`);
|
|
this.hostCandidates.wipe();
|
|
}
|
|
}
|
|
}
|