Improve logic for logging into the websocket of the target node
This commit is contained in:
parent
5c5e2e24f1
commit
01926e2896
6 changed files with 63 additions and 31 deletions
|
@ -61,15 +61,18 @@ class WebsocketController extends ClientApiController
|
||||||
$permissions = $this->permissionsService->handle($server, $user);
|
$permissions = $this->permissionsService->handle($server, $user);
|
||||||
|
|
||||||
$node = null;
|
$node = null;
|
||||||
|
if ($server->transfer !== null) {
|
||||||
// Check if there is a transfer query param asking to connect to the target node's websocket.
|
|
||||||
if ($request->query('transfer', 'false') === 'true') {
|
|
||||||
// Check if the user has permissions to receive transfer logs.
|
// Check if the user has permissions to receive transfer logs.
|
||||||
if (! in_array('admin.websocket.transfer', $permissions)) {
|
if (! in_array('admin.websocket.transfer', $permissions)) {
|
||||||
throw new HttpException(Response::HTTP_FORBIDDEN, 'You do not have permission to get transfer logs');
|
throw new HttpException(Response::HTTP_FORBIDDEN, 'You do not have permission to view transfer logs');
|
||||||
}
|
}
|
||||||
|
|
||||||
$node = $server->transfer->newNode;
|
// Redirect the websocket request to the new node if the server has been archived.
|
||||||
|
if ($server->transfer->archived) {
|
||||||
|
$node = $server->transfer->newNode;
|
||||||
|
} else {
|
||||||
|
$node = $server->node;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$node = $server->node;
|
$node = $server->node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,6 @@ class ServerTransferController extends Controller
|
||||||
|
|
||||||
// Unsuspend the server and don't continue the transfer.
|
// Unsuspend the server and don't continue the transfer.
|
||||||
if (! $request->input('successful')) {
|
if (! $request->input('successful')) {
|
||||||
//$this->suspensionService->toggle($server, 'unsuspend');
|
|
||||||
$server->transfer->forceFill([
|
$server->transfer->forceFill([
|
||||||
'successful' => false,
|
'successful' => false,
|
||||||
])->saveOrFail();
|
])->saveOrFail();
|
||||||
|
@ -142,6 +141,12 @@ class ServerTransferController extends Controller
|
||||||
->relatedTo($server->uuid, true)
|
->relatedTo($server->uuid, true)
|
||||||
->getToken($signer, new Key($server->node->getDecryptedKey()));
|
->getToken($signer, new Key($server->node->getDecryptedKey()));
|
||||||
|
|
||||||
|
// Update the archived field on the transfer to make clients connect to the websocket
|
||||||
|
// on the new node to be able to receive transfer logs.
|
||||||
|
$server->transfer->forceFill([
|
||||||
|
'archived' => true,
|
||||||
|
])->saveOrFail();
|
||||||
|
|
||||||
// On the daemon transfer repository, make sure to set the node after the server
|
// On the daemon transfer repository, make sure to set the node after the server
|
||||||
// because setServer() tells the repository to use the server's node and not the one
|
// because setServer() tells the repository to use the server's node and not the one
|
||||||
// we want to specify.
|
// we want to specify.
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Pterodactyl\Models;
|
||||||
* @property string $old_additional_allocations
|
* @property string $old_additional_allocations
|
||||||
* @property string $new_additional_allocations
|
* @property string $new_additional_allocations
|
||||||
* @property bool|null $successful
|
* @property bool|null $successful
|
||||||
|
* @property bool $archived
|
||||||
* @property \Carbon\Carbon $created_at
|
* @property \Carbon\Carbon $created_at
|
||||||
* @property \Carbon\Carbon $updated_at
|
* @property \Carbon\Carbon $updated_at
|
||||||
*
|
*
|
||||||
|
@ -55,6 +56,7 @@ class ServerTransfer extends Model
|
||||||
'old_additional_allocations' => 'string',
|
'old_additional_allocations' => 'string',
|
||||||
'new_additional_allocations' => 'string',
|
'new_additional_allocations' => 'string',
|
||||||
'successful' => 'bool',
|
'successful' => 'bool',
|
||||||
|
'archived' => 'bool',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddArchivedFieldToServerTransfersTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('server_transfers', function (Blueprint $table) {
|
||||||
|
$table->boolean('archived')->default(0)->after('new_additional_allocations');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update archived to all be true on existing transfers.
|
||||||
|
Schema::table('server_transfers', function (Blueprint $table) {
|
||||||
|
DB::statement('UPDATE `server_transfers` SET `archived` = 1 WHERE `successful` = 1');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('server_transfers', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('archived');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,13 +5,9 @@ interface Response {
|
||||||
socket: string;
|
socket: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (server: string, transfer: boolean): Promise<Response> => {
|
export default (server: string): Promise<Response> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
http.get(`/api/client/servers/${server}/websocket`, {
|
http.get(`/api/client/servers/${server}/websocket`)
|
||||||
params: {
|
|
||||||
transfer,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(({ data }) => resolve({
|
.then(({ data }) => resolve({
|
||||||
token: data.data.token,
|
token: data.data.token,
|
||||||
socket: data.data.socket,
|
socket: data.data.socket,
|
||||||
|
|
|
@ -15,15 +15,12 @@ const reconnectErrors = [
|
||||||
export default () => {
|
export default () => {
|
||||||
let updatingToken = false;
|
let updatingToken = false;
|
||||||
const [ error, setError ] = useState<'connecting' | string>('');
|
const [ error, setError ] = useState<'connecting' | string>('');
|
||||||
const [ transfer, setTransfer ] = useState<boolean>(false);
|
|
||||||
const { connected, instance } = ServerContext.useStoreState(state => state.socket);
|
const { connected, instance } = ServerContext.useStoreState(state => state.socket);
|
||||||
const uuid = ServerContext.useStoreState(state => state.server.data?.uuid);
|
const uuid = ServerContext.useStoreState(state => state.server.data?.uuid);
|
||||||
const setServerStatus = ServerContext.useStoreActions(actions => actions.status.setServerStatus);
|
const setServerStatus = ServerContext.useStoreActions(actions => actions.status.setServerStatus);
|
||||||
const { setInstance, setConnectionState } = ServerContext.useStoreActions(actions => actions.socket);
|
const { setInstance, setConnectionState } = ServerContext.useStoreActions(actions => actions.socket);
|
||||||
|
|
||||||
const connect = (uuid: string, transfer = false) => {
|
const connect = (uuid: string) => {
|
||||||
setTransfer(transfer);
|
|
||||||
|
|
||||||
const socket = new Websocket();
|
const socket = new Websocket();
|
||||||
|
|
||||||
socket.on('auth success', () => setConnectionState(true));
|
socket.on('auth success', () => setConnectionState(true));
|
||||||
|
@ -52,21 +49,12 @@ export default () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('transfer status', (status: string) => {
|
socket.on('transfer status', (status: string) => {
|
||||||
if (status === 'success') {
|
if (status === 'starting' || status === 'success') {
|
||||||
setTransfer(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === 'starting') {
|
// Force a reconnection to the websocket which will connect us
|
||||||
return;
|
// to the target node instead of the source node.
|
||||||
}
|
|
||||||
|
|
||||||
// This doesn't use the `setTransfer` hook as it doesn't want to work properly in this context,
|
|
||||||
// and causes all kinds of fuckery with the websocket.
|
|
||||||
let transfer = false;
|
|
||||||
if (status === 'archived') {
|
|
||||||
transfer = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the current websocket connection.
|
// Close the current websocket connection.
|
||||||
socket.close();
|
socket.close();
|
||||||
|
@ -75,10 +63,10 @@ export default () => {
|
||||||
setConnectionState(false);
|
setConnectionState(false);
|
||||||
setInstance(null);
|
setInstance(null);
|
||||||
|
|
||||||
connect(uuid, transfer);
|
connect(uuid);
|
||||||
});
|
});
|
||||||
|
|
||||||
getWebsocketToken(uuid, transfer)
|
getWebsocketToken(uuid)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
// Connect and then set the authentication token.
|
// Connect and then set the authentication token.
|
||||||
socket.setToken(data.token).connect(data.socket);
|
socket.setToken(data.token).connect(data.socket);
|
||||||
|
@ -93,7 +81,7 @@ export default () => {
|
||||||
if (updatingToken) return;
|
if (updatingToken) return;
|
||||||
|
|
||||||
updatingToken = true;
|
updatingToken = true;
|
||||||
getWebsocketToken(uuid, transfer)
|
getWebsocketToken(uuid)
|
||||||
.then(data => socket.setToken(data.token, true))
|
.then(data => socket.setToken(data.token, true))
|
||||||
.catch(error => console.error(error))
|
.catch(error => console.error(error))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
Loading…
Reference in a new issue