mirror of
https://github.com/PretendoNetwork/account.git
synced 2026-03-21 17:44:49 -05:00
Merge pull request #312 from PretendoNetwork/feat/server-config
Server provisioning
This commit is contained in:
commit
2f5a4b95db
3
SETUP.md
3
SETUP.md
|
|
@ -95,4 +95,5 @@ Configurations are loaded through environment variables. `.env` files are suppor
|
|||
| `PN_ACT_CONFIG_DISCOURSE_API_USERNAME` | Used for anonymizing user accounts on Discourse during account deletion. Forum anonymization skipped if not set | Yes |
|
||||
| `PN_ACT_CONFIG_GRPC_MIIVERSE_HOST` | Used to remove Miiverse user data during account deletion | No |
|
||||
| `PN_ACT_CONFIG_GRPC_MIIVERSE_PORT` | Used to remove Miiverse user data during account deletion | No |
|
||||
| `PN_ACT_CONFIG_GRPC_MIIVERSE_KEY_API` | Used to remove Miiverse user data during account deletion | No |
|
||||
| `PN_ACT_CONFIG_GRPC_MIIVERSE_KEY_API` | Used to remove Miiverse user data during account deletion | No |
|
||||
| `PN_ACT_PROVISIONING_SERVER_CONFIG` | Specify a path to a JSON file containing a list of servers to provision automatically to the DB | Yes |
|
||||
|
|
@ -13,7 +13,8 @@ export const disabledFeatures = {
|
|||
email: false,
|
||||
captcha: false,
|
||||
s3: false,
|
||||
datastore: false
|
||||
datastore: false,
|
||||
serverProvisioning: false
|
||||
};
|
||||
|
||||
const hexadecimalStringRegex = /^[0-9a-f]+$/i;
|
||||
|
|
@ -41,6 +42,9 @@ export const config: Config = {
|
|||
connection_string: process.env.PN_ACT_CONFIG_MONGO_CONNECTION_STRING || '',
|
||||
options: mongooseConnectOptions
|
||||
},
|
||||
provisioning: {
|
||||
server_config: process.env.PN_ACT_PROVISIONING_SERVER_CONFIG || ''
|
||||
},
|
||||
redis: {
|
||||
client: {
|
||||
url: process.env.PN_ACT_CONFIG_REDIS_URL || ''
|
||||
|
|
@ -282,6 +286,11 @@ if (!config.datastore.signature_secret) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!config.provisioning.server_config) {
|
||||
LOG_WARN('A server provisioning config file as not been set. Disabling feature, no server data will be provisioned. To enable feature set the PN_ACT_PROVISIONING_SERVER_CONFIG environment variable');
|
||||
disabledFeatures.serverProvisioning = true;
|
||||
}
|
||||
|
||||
if (!configValid) {
|
||||
LOG_ERROR('Config is invalid. Exiting');
|
||||
process.exit(0);
|
||||
|
|
|
|||
77
src/provisioning.ts
Normal file
77
src/provisioning.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import fs from 'node:fs/promises';
|
||||
import { z } from 'zod';
|
||||
import mongoose from 'mongoose';
|
||||
import { config, disabledFeatures } from './config-manager';
|
||||
import { LOG_INFO, LOG_WARN } from './logger';
|
||||
import { Server } from './models/server';
|
||||
|
||||
// Provisioning has a couple edgecases:
|
||||
// - It will only update existing entries, will not add new one
|
||||
// - Only the fields in the below schema will be updated
|
||||
|
||||
const serverProvisioningSchema = z.object({
|
||||
servers: z.array(z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
ip: z.string(),
|
||||
port: z.coerce.number()
|
||||
}))
|
||||
});
|
||||
|
||||
async function readServerProvisioning(configPath: string): Promise<z.infer<typeof serverProvisioningSchema>> {
|
||||
const fileContents = await fs.readFile(configPath, 'utf-8');
|
||||
const parsedConfig = JSON.parse(fileContents);
|
||||
return serverProvisioningSchema.parse(parsedConfig);
|
||||
}
|
||||
|
||||
export async function handleServerProvisioning(): Promise<void> {
|
||||
const serverData = await readServerProvisioning(config.provisioning.server_config).catch((err) => {
|
||||
LOG_WARN('Failed to parse server provisioning config:');
|
||||
console.error(err);
|
||||
});
|
||||
if (!serverData) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO('Starting server provisioning');
|
||||
for (const server of serverData.servers) {
|
||||
const id = new mongoose.Types.ObjectId(server.id);
|
||||
const result = await Server.findOneAndUpdate(id, {
|
||||
$set: {
|
||||
_id: id,
|
||||
service_name: server.name,
|
||||
ip: server.ip,
|
||||
port: server.port
|
||||
}
|
||||
});
|
||||
if (!result) {
|
||||
LOG_WARN(`Could not find existing server DB entry for ID ${server.id} - skipping provisioning`);
|
||||
}
|
||||
}
|
||||
LOG_INFO(`Finished provisioning ${serverData.servers.length} servers`);
|
||||
}
|
||||
|
||||
export function startProvisioner(): void {
|
||||
if (disabledFeatures.serverProvisioning) {
|
||||
return;
|
||||
}
|
||||
|
||||
const runProvisioning = (): void => {
|
||||
handleServerProvisioning().catch((err) => {
|
||||
LOG_WARN('Failed to provision servers:');
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
// Run once at boot
|
||||
runProvisioning();
|
||||
|
||||
(async (): Promise<void> => {
|
||||
const watcher = fs.watch(config.provisioning.server_config);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- Dont need this var
|
||||
for await (const _ of watcher) {
|
||||
LOG_INFO('Detected a change in the server provisioning config');
|
||||
runProvisioning();
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import api from '@/services/api';
|
|||
import localcdn from '@/services/local-cdn';
|
||||
import assets from '@/services/assets';
|
||||
import { config, disabledFeatures } from '@/config-manager';
|
||||
import { startProvisioner } from './provisioning';
|
||||
|
||||
process.title = 'Pretendo - Account';
|
||||
process.on('uncaughtException', (err, origin) => {
|
||||
|
|
@ -113,6 +114,8 @@ async function main(): Promise<void> {
|
|||
await startGRPCServer();
|
||||
LOG_SUCCESS(`gRPC server started on port ${config.grpc.port}`);
|
||||
|
||||
startProvisioner();
|
||||
|
||||
app.listen(config.http.port, () => {
|
||||
LOG_SUCCESS(`HTTP server started on port ${config.http.port}`);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ export interface Config {
|
|||
connection_string: string;
|
||||
options: mongoose.ConnectOptions;
|
||||
};
|
||||
provisioning: {
|
||||
server_config: string;
|
||||
};
|
||||
redis: {
|
||||
client: {
|
||||
url: string;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user