mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 23:24:52 +09:00
Hosts join the cluster by running the installer, which shows a code and waits until the request is approved under Hosts > Add host in the web interface or with clusterioctl host approve. An admin can pass their user token to the installer to approve the host right away. The token is only used for that and is not saved. The controller only accepts hosts that have a record, and only approving a host creates one. Revoking a host deletes its record, so its token can no longer be used to reconnect. Hosts that have connected before keep working. Removes host generate-token, revoke-token and create-config from clusterioctl, bootstrap generate-host-token, the host token messages and the core.host.generate_token, revoke_token and create_config permissions, which are also stripped from stored roles. Adds clusterioctl host pending, approve, reject and revoke, and the core.host.approve and core.host.revoke permissions. Standalone installs add the host to the controller database directly, since the controller is not running during the install.
281 lines
7.3 KiB
TypeScript
281 lines
7.3 KiB
TypeScript
import { Type, Static } from "@sinclair/typebox";
|
|
import { jsonArray, plainJson, StringEnum } from "./composites.js";
|
|
import { CollectorResultSerialized } from "../prometheus.js";
|
|
import { HostConfig } from "../config/definitions.js";
|
|
import HostDetails from "./HostDetails.js";
|
|
|
|
export class HostStopRequest {
|
|
declare ["constructor"]: typeof HostStopRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.stop" as const;
|
|
}
|
|
|
|
export class HostRestartRequest {
|
|
declare ["constructor"]: typeof HostRestartRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.restart" as const;
|
|
}
|
|
|
|
export class HostMarkRestartRequiredRequest {
|
|
declare ["constructor"]: typeof HostMarkRestartRequiredRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.restart" as const;
|
|
}
|
|
|
|
export class HostUpdateRequest {
|
|
declare ["constructor"]: typeof HostUpdateRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.update" as const;
|
|
}
|
|
|
|
export class HostConfigGetRequest {
|
|
declare ["constructor"]: typeof HostConfigGetRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.get_config" as const;
|
|
static Response = plainJson(HostConfig.jsonSchema);
|
|
}
|
|
|
|
export class HostConfigSetRequest {
|
|
declare ["constructor"]: typeof HostConfigSetRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.update_config" as const;
|
|
|
|
constructor(
|
|
public fields: Record<string, string | Record<string, unknown>>,
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"fields": Type.Record(Type.String(), Type.Union([
|
|
Type.String(), Type.Record(Type.String(), Type.Unknown()),
|
|
])),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.fields);
|
|
}
|
|
}
|
|
|
|
export class HostConfigSetFieldRequest {
|
|
declare ["constructor"]: typeof HostConfigSetFieldRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.update_config" as const;
|
|
|
|
constructor(
|
|
public field: string,
|
|
public value: string,
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"field": Type.String(),
|
|
"value": Type.String(),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.field, json.value);
|
|
}
|
|
}
|
|
|
|
export class HostConfigSetPropRequest {
|
|
declare ["constructor"]: typeof HostConfigSetPropRequest;
|
|
static type = "request" as const;
|
|
static src = ["control", "controller"] as const;
|
|
static dst = "host" as const;
|
|
static permission = "core.host.update_config" as const;
|
|
|
|
constructor(
|
|
public field: string,
|
|
public prop: string,
|
|
public value?: unknown,
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"field": Type.String(),
|
|
"prop": Type.String(),
|
|
"value": Type.Optional(Type.Unknown()),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.field, json.prop, json.value);
|
|
}
|
|
}
|
|
|
|
export class HostListRequest {
|
|
declare ["constructor"]: typeof HostListRequest;
|
|
static type = "request" as const;
|
|
static src = "control" as const;
|
|
static dst = "controller" as const;
|
|
static permission = "core.host.list" as const;
|
|
static Response = jsonArray(HostDetails);
|
|
}
|
|
|
|
export class HostInfoUpdate {
|
|
constructor(
|
|
public name: string,
|
|
public publicAddress: string,
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"name": Type.String(),
|
|
"publicAddress": Type.String(),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(
|
|
json.name,
|
|
json.publicAddress,
|
|
);
|
|
}
|
|
}
|
|
|
|
export class HostInfoUpdateEvent {
|
|
declare ["constructor"]: typeof HostInfoUpdateEvent;
|
|
static type = "event" as const;
|
|
static src = "host" as const;
|
|
static dst = "controller" as const;
|
|
|
|
constructor(
|
|
public update: HostInfoUpdate,
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"update": HostInfoUpdate.jsonSchema,
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(HostInfoUpdate.fromJSON(json.update));
|
|
}
|
|
}
|
|
|
|
export class HostUpdatesEvent {
|
|
declare ["constructor"]: typeof HostUpdatesEvent;
|
|
static type = "event" as const;
|
|
static src = "controller" as const;
|
|
static dst = "control" as const;
|
|
static permission = "core.host.subscribe" as const;
|
|
|
|
constructor(
|
|
public updates: HostDetails[],
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"updates": Type.Array(HostDetails.jsonSchema),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.updates.map(update => HostDetails.fromJSON(update)));
|
|
}
|
|
}
|
|
|
|
export class HostMetricsRequest {
|
|
declare ["constructor"]: typeof HostMetricsRequest;
|
|
static type = "request" as const;
|
|
static src = "controller" as const;
|
|
static dst = "host" as const;
|
|
static Response = class Response { // TODO: Use JSON class pattern in Prometheus
|
|
constructor(
|
|
public results: CollectorResultSerialized[],
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"results": Type.Array(CollectorResultSerialized),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.results);
|
|
}
|
|
};
|
|
}
|
|
|
|
export class ControllerConnectionEvent {
|
|
declare ["constructor"]: typeof ControllerConnectionEvent;
|
|
static type = "event" as const;
|
|
static src = "host" as const;
|
|
static dst = "instance" as const;
|
|
|
|
constructor(
|
|
public event: "connect" | "drop" | "resume" | "close",
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"event": StringEnum(["connect", "drop", "resume", "close"]),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.event);
|
|
}
|
|
}
|
|
|
|
export class PrepareControllerDisconnectRequest {
|
|
declare ["constructor"]: typeof PrepareControllerDisconnectRequest;
|
|
static type = "request" as const;
|
|
static src = "host" as const;
|
|
static dst = "instance" as const;
|
|
}
|
|
|
|
export class SyncUserListsEvent {
|
|
declare ["constructor"]: typeof SyncUserListsEvent;
|
|
static type = "event" as const;
|
|
static src = "controller" as const;
|
|
static dst = "host" as const;
|
|
|
|
constructor(
|
|
public adminlist: Set<string>,
|
|
public banlist: Map<string, string>,
|
|
public whitelist: Set<string>,
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"adminlist": Type.Array(Type.String()),
|
|
"banlist": Type.Array(
|
|
Type.Tuple([Type.String(), Type.String()])
|
|
),
|
|
"whitelist": Type.Array(Type.String()),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(new Set(json.adminlist), new Map(json.banlist), new Set(json.whitelist));
|
|
}
|
|
|
|
toJSON() {
|
|
return {
|
|
adminlist: [...this.adminlist],
|
|
banlist: [...this.banlist],
|
|
whitelist: [...this.whitelist],
|
|
};
|
|
}
|
|
}
|
|
|
|
export class HostRevokeRequest {
|
|
declare ["constructor"]: typeof HostRevokeRequest;
|
|
static type = "request" as const;
|
|
static src = "control" as const;
|
|
static dst = "controller" as const;
|
|
static permission = "core.host.revoke" as const;
|
|
|
|
constructor(
|
|
public hostId: number,
|
|
) { }
|
|
|
|
static jsonSchema = Type.Object({
|
|
"hostId": Type.Number(),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.hostId);
|
|
}
|
|
}
|