UNPKG

realm-object-server-enterprise

Version:

Realm Object Server Enterprise

174 lines 8.05 kB
"use strict"; 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