mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 23:14:53 +09:00
Add generate slave token button
Add a generate slave token button to the web interface and modify the generateSlaveToken message and corresponding ctl command to have the slave id be optional. The random id is the desired behavior when adding a slave with the installer, as it'll ask for the token for the new slave and deduce the id from the token.
This commit is contained in:
1 parent
cc562a451e
commit
fc08438164
5 files changed
+81
-7
No files matched your search
+3
-2
@@ -137,10 +137,11 @@ slaveCommands.add(new libCommand.Command({
|
||||
|
||||
slaveCommands.add(new libCommand.Command({
|
||||
definition: ["generate-token", "Generate token for a slave", (yargs) => {
|
||||
yargs.option("id", { type: "number", nargs: 1, describe: "Slave id", demandOption: true });
|
||||
yargs.option("id", { type: "number", nargs: 1, describe: "Slave id" });
|
||||
}],
|
||||
handler: async function(args, control) {
|
||||
let response = await libLink.messages.generateSlaveToken.send(control, { slave_id: args.id });
|
||||
let slaveId = typeof args.id === "number" ? args.id : null;
|
||||
let response = await libLink.messages.generateSlaveToken.send(control, { slave_id: slaveId });
|
||||
print(response.token);
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -422,7 +422,7 @@ messages.generateSlaveToken = new Request({
|
||||
links: ["control-master"],
|
||||
permission: "core.slave.generate_token",
|
||||
requestProperties: {
|
||||
"slave_id": { type: "integer" },
|
||||
"slave_id": { type: ["integer", "null"] },
|
||||
},
|
||||
responseProperties: {
|
||||
"token": { type: "string" },
|
||||
|
||||
@@ -130,7 +130,11 @@ class ControlConnection extends BaseConnection {
|
||||
}
|
||||
|
||||
async generateSlaveTokenRequestHandler(message) {
|
||||
return { token: this.generateSlaveToken(message.data.slave_id) };
|
||||
let slaveId = message.data.slave_id;
|
||||
if (slaveId === null) {
|
||||
slaveId = Math.random() * 2**31 | 0;
|
||||
}
|
||||
return { token: this.generateSlaveToken(slaveId) };
|
||||
}
|
||||
|
||||
async createSlaveConfigRequestHandler(message) {
|
||||
|
||||
@@ -1,11 +1,73 @@
|
||||
import React, { useContext } from "react";
|
||||
import { Table } from "antd";
|
||||
import React, { useContext, useRef, useState } from "react";
|
||||
import { Button, Form, Input, Modal, PageHeader, Table } from "antd";
|
||||
|
||||
import libLink from "@clusterio/lib/link";
|
||||
|
||||
import ControlContext from "./ControlContext";
|
||||
import PageLayout from "./PageLayout";
|
||||
import { useSlaveList } from "../model/slave";
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
|
||||
|
||||
function GenerateSlaveTokenButton(props) {
|
||||
let control = useContext(ControlContext);
|
||||
let [visible, setVisible] = useState(false);
|
||||
let [token, setToken] = useState(null);
|
||||
let [form] = Form.useForm();
|
||||
let tokenTextAreaRef = useRef(null);
|
||||
|
||||
async function generateToken() {
|
||||
let values = form.getFieldsValue();
|
||||
let slaveId = null;
|
||||
if (values.slaveId) {
|
||||
slaveId = Number.parseInt(values.slaveId, 10);
|
||||
if (Number.isNaN(slaveId)) {
|
||||
form.setFields([{ name: "slaveId", errors: ["Must be an integer"] }]);
|
||||
return;
|
||||
}
|
||||
form.setFields([{ name: "slaveId", errors: [] }]);
|
||||
}
|
||||
|
||||
let result = await libLink.messages.generateSlaveToken.send(control, { slave_id: slaveId });
|
||||
setToken(result.token);
|
||||
}
|
||||
|
||||
return <>
|
||||
<Button
|
||||
onClick={() => { setVisible(true); }}
|
||||
>Generate Token</Button>
|
||||
<Modal
|
||||
title="Generate Slave Token"
|
||||
visible={visible}
|
||||
footer={null}
|
||||
onCancel={() => {
|
||||
setVisible(false);
|
||||
setToken(null);
|
||||
form.resetFields();
|
||||
}}
|
||||
>
|
||||
<Form form={form} layout="vertical" requiredMark="optional">
|
||||
<Form.Item name="slaveId" label="Slave ID">
|
||||
<Input/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button
|
||||
onClick={() => { generateToken().catch(notifyErrorHandler("Error generating token")); }}
|
||||
>Generate</Button>
|
||||
</Form.Item>
|
||||
<Form.Item label="Token" required>
|
||||
<Input.TextArea value={token} autoSize ref={tokenTextAreaRef} />
|
||||
</Form.Item>
|
||||
<Button disabled={token === null} onClick={() => {
|
||||
let textArea = tokenTextAreaRef.current.resizableTextArea.textArea;
|
||||
textArea.select();
|
||||
document.execCommand("copy");
|
||||
window.getSelection().removeAllRanges();
|
||||
}}>Copy</Button>
|
||||
</Form>
|
||||
</Modal>
|
||||
</>;
|
||||
}
|
||||
|
||||
|
||||
export default function SlavesPage() {
|
||||
@@ -13,7 +75,11 @@ export default function SlavesPage() {
|
||||
let [slaveList] = useSlaveList();
|
||||
|
||||
return <PageLayout nav={[{ name: "Slaves" }]}>
|
||||
<h2>Slaves</h2>
|
||||
<PageHeader
|
||||
className="site-page-header"
|
||||
title="Slaves"
|
||||
extra=<GenerateSlaveTokenButton />
|
||||
/>
|
||||
<Table
|
||||
columns={[
|
||||
{
|
||||
|
||||
@@ -167,6 +167,9 @@ describe("Integration of Clusterio", function() {
|
||||
it("runs", async function() {
|
||||
await execCtl("slave generate-token --id 42");
|
||||
});
|
||||
it("runs without an id", async function() {
|
||||
await execCtl("slave generate-token");
|
||||
});
|
||||
});
|
||||
describe("instance list", function() {
|
||||
it("runs", async function() {
|
||||
|
||||
Reference in new issue
Block a user