realm-object-server-enterprise
Version:
Realm Object Server Enterprise
174 lines • 8.05 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const consul = require("consul");
const path = require("path");
const os = require("os");
const ros = require("realm-object-server");
const LogSender_1 = require("./LogSender");
const ConsulDiscovery_1 = require("./ConsulDiscovery");
const ReplicatedSyncService_1 = require("./ReplicatedSyncService");
const RemoteLogService_1 = require("./services/RemoteLogService");
const services = require("./services");
function checkEnv(...names) {
for (const name of names) {
if (process.env[name] == null) {
throw new Error(`${name} environment variable not defined`);
}
}
}
function list(val) {
return val.split(",");
}
class EnterpriseServer extends ros.BasicServer {
constructor() {
super();
this["commander"].command("run <service>")
.description("Run a single ROS service (Enterprise Edition)")
.option("-p, --port <port>", "Specify the port to listen on", 9080)
.option("-a, --address <address>", "Specify the address or interface to listen on", "0.0.0.0")
.option("-d, --data <path>", "Specify the data path to use", "./data")
.option("--loglevel <level>", "Specify the log level", "info")
.option("-l, --log <path>", "Specify the log file path")
.option("--remotelog <address:port>[,...]", "Specify where to send the logs, comma separated list", list)
.option("--advertise-address <address>", "Specify the address or interface to advertise in discovery")
.action((serviceName, command) => __awaiter(this, void 0, void 0, function* () {
command.parent.handler = this.runService(serviceName, command);
}));
}
getAdvertiseAddress(addressOrInterface) {
const netmaskToCidr = (mask) => {
const maskNodes = mask.match(/(\d+)/g).map((s) => parseInt(s, 10));
let cidr = 0;
for (const i in maskNodes) {
if (maskNodes[i]) {
cidr += (((maskNodes[i] >>> 0).toString(2)).match(/1/g) || []).length;
}
}
return cidr;
};
if (addressOrInterface === undefined) {
return;
}
const matches = addressOrInterface.match(/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/);
if (matches) {
return addressOrInterface;
}
if (addressOrInterface !== "") {
const ifaces = os.networkInterfaces();
const iface = ifaces[addressOrInterface];
if (iface) {
let smallest = 33;
let found;
for (const address of iface) {
if ("IPv4" === address.family) {
const size = netmaskToCidr(address.netmask);
if (size < smallest) {
smallest = size;
found = address.address;
}
}
}
return found;
}
}
}
runService(serviceName, command) {
return __awaiter(this, void 0, void 0, function* () {
let logger;
if (command.remotelog) {
logger = new LogSender_1.LogSender(command.remotelog, command.loglevel);
}
else if (command.log) {
logger = new ros.FileConsoleLogger(command.log, command.loglevel);
}
else {
logger = new ros.ConsoleLogger(command.loglevel);
}
const listenAddress = command.address || "0.0.0.0";
this.advertiseAddress = this.getAdvertiseAddress(command.advertiseAddress) || listenAddress;
const config = {
address: listenAddress,
autoKeyGen: false,
dataPath: path.resolve(command.data),
discovery: new ConsulDiscovery_1.ConsulDiscovery({
logger,
advertiseAddress: this.advertiseAddress,
namespace: process.env.CONSUL_NAMESPACE,
}),
logger,
logLevel: command.loglevel,
port: command.port,
privateKeyPath: process.env.PRIVATE_KEY_PATH,
publicKeyPath: process.env.PUBLIC_KEY_PATH,
services: [new services.HealthService()],
};
switch (serviceName) {
case "auth": {
if (process.env.LOG_RECV_PORT) {
config.services.push(new RemoteLogService_1.RemoteLogService({
host: this.advertiseAddress,
port: Number(process.env.LOG_RECV_PORT),
}));
}
config.services.push(new ros.RealmDirectoryService());
config.services.push(new ros.SyncProxyService());
config.services.push(new ros.LogService());
const authService = new ros.AuthService();
authService.addProvider(new ros.auth.PasswordAuthProvider({ autoCreateAdminUser: true }));
config.services.push(authService);
config.services.push(new ros.PermissionsService());
config.services.push(new ros.WelcomeService());
break;
}
case "sync": {
config.services.push(new ros.SyncService({
label: process.env.SYNC_LABEL,
listenAddress: "0.0.0.0",
listenPort: 7800,
}));
break;
}
case "resync":
checkEnv("SYNC_ID", "SYNC_LABEL", "PUBLIC_KEY_PATH");
config.logger = config.logger.withContext({
id: process.env.SYNC_ID,
label: process.env.SYNC_LABEL,
});
config.services.push(new ReplicatedSyncService_1.ReplicatedSyncService({
consul: consul({
host: process.env.CONSUL_HOST,
promisify: true,
}),
dataPath: config.dataPath,
featureToken: process.env.FEATURE_TOKEN,
id: process.env.SYNC_ID,
label: process.env.SYNC_LABEL,
listenAddress: this.advertiseAddress,
listenPort: Number(process.env.SYNC_PORT || 7800),
logLevel: command.loglevel,
namespace: process.env.CONSUL_NAMESPACE,
publicKeyPath: config.publicKeyPath,
}));
break;
default:
throw new Error(`Unknown service: ${serviceName}`);
}
this.start(config).catch((err) => {
logger.fatal("Startup failed:", err, err.stack);
return this.shutdown().then(() => {
process.exit(1);
});
});
});
}
}
exports.EnterpriseServer = EnterpriseServer;
//# sourceMappingURL=EnterpriseServer.js.map