Subversion Repositories ALCASAR

Rev

Rev 3306 | Rev 3309 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
3294 rexy 1
<?php
2
 
3
// written by Alexandre BOUIJOUX
4
 
5
/*******************
6
 * READ CONF FILES *
7
 ******************/
8
define('CONF_FILE', '/usr/local/etc/alcasar.conf');
9
 
10
$conf_files = [CONF_FILE];
11
 
12
// Files reading test
13
foreach ($conf_files as $file) {
14
	if (!file_exists($file)) {
15
		exit("Requested file $file isn't present");
16
	}
17
 
18
	if (!is_readable($file)) {
19
		exit("Can't read the file $file");
20
	}
21
}
22
 
23
// Read ALCASAR CONF_FILE
24
$file_conf = fopen(CONF_FILE, 'r');
25
if (!$file_conf) {
26
	exit('Error opening the file '.CONF_FILE);
27
}
28
while (!feof($file_conf)) {
29
	$buffer = fgets($file_conf, 4096);
30
	if ((strpos($buffer, '=') !== false) && (substr($buffer, 0, 1) !== '#')) {
31
		$tmp = explode('=', $buffer, 2);
32
		$conf[trim($tmp[0])] = trim($tmp[1]);
33
	}
34
}
35
 
36
// Handle error messages
37
// Move errors messages from cookies to array.
38
$errors_msg = [];
39
$cookies_keys = [ "add_replica_error", "change_replicas_state_error", "add_ssh_key_error", "delete_ssh_key_error" ];
40
foreach ($cookies_keys as $key) {
41
	// Ignore if error didn't happened
42
	if (!array_key_exists($key, $_COOKIE)) {
43
		continue;
44
	}
45
 
46
	// Store message in errors messages array
47
	$errors_msg[$key] = $_COOKIE[$key];
48
 
49
	// Delete the cookie
50
	unset($_COOKIE[$key]);
51
	setcookie($key, false, 1);
52
}
53
 
54
// Choice of language
55
$Language = 'en';
56
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
57
	$Langue	  = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
58
	$Language = strtolower(substr(chop($Langue[0]), 0, 2));
59
}
60
if ($Language === 'fr') {
61
	$l_action		= "Action";
62
	$l_add_to_list		= "Ajouter";
63
	$l_algorithm		= "Algorithme";
64
	$l_apply		= "Appliquer les changements";
65
	$l_bind_port		= "Port de liaison";
66
	$l_cant_read_pubkey	= "Impossible de lire la clé publique de 'root'.";
67
	$l_confirm_uninstall	= "Êtes-vous certain de vouloir désinstaller la fédération ?";
68
	$l_db_pwd		= "Mot de passe BDD";
69
	$l_db_user		= "Utilisateur BDD";
70
	$l_delete		= "Supprimer";
71
	$l_error_details	= "Détails des erreurs";
72
	$l_field		= "Champ";
73
	$l_go_network_conf_page	= "Allez sur la page de configuration réseau.";
74
	$l_host_name		= "Nom d'hôte";
75
	$l_hosts_settings	= "Paramètres de réplication des hôtes";
3306 rexy 76
	$l_import_ssh_key	= "Si cet ALCASAR est primaire, importez ici les clés publiques des secondaires";
3294 rexy 77
	$l_install_repl		= "Installer la fédération";
78
	$l_ip_address		= "Adresse IP";
79
	$l_no_primary_connected = "Aucun primaire connecté";
3308 rexy 80
	$l_no_ssh_key		= "Aucune clé SSH importée.";
3294 rexy 81
	$l_not_connected	= "Non connecté";
3306 rexy 82
	$l_pubkey_to_deploy	= "Si cet ALCASAR est secondaire, copiez la clé publique ci-dessous pour l'importez dans le primaire.";
3294 rexy 83
	$l_remote_access_mgmt	= "Gestion des accès distants";
84
	$l_remote_role		= "Rôle de l'hôte distant";
85
	$l_repl_io_running	= "État";
86
	$l_replication_install	= "Installer la Fédération";
87
	$l_replication_title	= "Fédération";
88
	$l_role_primary		= "Primaire";
89
	$l_role_secondary	= "Secondaire";
3306 rexy 90
	$l_ssh_keys_for_primary	= "Liste des secondaires autorisées à se connecter";
3294 rexy 91
	$l_ssh_port		= "Port SSH";
92
	$l_ssh_user		= "Utilisateur SSH";
93
	$l_ssh_wan_enabled	= "Le SSH sur le WAN est activé.";
94
	$l_ssh_wan_must_be_on	= "Le SSH sur le WAN doit être activé.";
95
	$l_start		= "Démarrer";
96
	$l_stop			= "Arrêter";
97
	$l_uninstall_repl	= "Désinstaller la fédération";
98
	$l_value		= "Valeur";
99
	$l_want_server_as_prim	= "Vous voulez que le serveur soit primaire ?";
100
} else if ($Language === 'es') {
101
	$l_action		= "Action";
102
	$l_add_to_list		= "Ajouter";
103
	$l_algorithm		= "Algorithme";
104
	$l_apply		= "Appliquer les changements";
105
	$l_bind_port		= "Port de liaison";
106
	$l_cant_read_pubkey	= "Impossible de lire la clé publique de 'root'.";
107
	$l_confirm_uninstall	= "¿Estás seguro de que quieres desinstalar la federación?";
108
	$l_db_pwd		= "Mot de passe BDD";
109
	$l_db_user		= "Utilisateur BDD";
110
	$l_delete		= "Supprimer";
111
	$l_error_details	= "Détails des erreurs";
112
	$l_field		= "Champ";
113
	$l_go_network_conf_page	= "Allez sur la page de configuration réseau.";
114
	$l_host_name		= "Nom d'hôte";
115
	$l_hosts_settings	= "Paramètres de réplication des hôtes";
116
	$l_import_ssh_key	= "Importer une clé SSH";
117
	$l_install_repl		= "Creación de la federación";
118
	$l_ip_address		= "Adresse IP";
119
	$l_no_primary_connected = "Aucun primaire connecté";
3308 rexy 120
	$l_no_ssh_key		= "Aucune clé SSH importée.";
3294 rexy 121
	$l_not_connected	= "Non connecté";
122
	$l_pubkey_to_deploy	= "La clé doit être déployée sur les serveurs primaires.";
123
	$l_remote_access_mgmt	= "Gestion des accès distants";
124
	$l_remote_role		= "Rôle de l'hôte distant";
125
	$l_repl_io_running	= "État";
126
	$l_replication_install	= "Creación de la federación";
127
	$l_replication_title	= "Federación";
128
	$l_role_primary		= "Primaire";
129
	$l_role_secondary	= "Secondaire";
130
	$l_ssh_keys_for_primary	= "Liste des clés autorisées à se connecter à l'utilisateur local 'replication'.";
131
	$l_ssh_port		= "Port SSH";
132
	$l_ssh_user		= "Utilisateur SSH";
133
	$l_ssh_wan_enabled	= "Le SSH sur le WAN est activé.";
134
	$l_ssh_wan_must_be_on	= "Le SSH sur le WAN doit être activé.";
135
	$l_start		= "Démarrer";
136
	$l_stop			= "Arrêter";
137
	$l_uninstall_repl	= "Desinstalar la federación";
138
	$l_value		= "Valeur";
139
	$l_want_server_as_prim	= "Vous voulez que le serveur soit primaire ?";
140
} else {
141
	$l_action		= "Action";
142
	$l_add_to_list		= "Add";
143
	$l_algorithm		= "Algorithm";
144
	$l_apply		= "Apply changes";
145
	$l_bind_port		= "Bind port";
146
	$l_cant_read_pubkey	= "Can't read root's public key.";
147
	$l_confirm_uninstall	= "Are you sure you want to uninstall the federation?";
148
	$l_db_pwd		= "Database password";
149
	$l_db_user		= "Database user";
150
	$l_delete		= "Delete";
151
	$l_error_details	= "Error details";
152
	$l_field		= "Field";
153
	$l_go_network_conf_page	= "Go to network config page.";
154
	$l_host_name		= "Host name";
155
	$l_hosts_settings	= "Replicated hosts settings";
156
	$l_import_ssh_key	= "Import a SSH key";
157
	$l_install_repl		= "Setting up the federation";
158
	$l_ip_address		= "IP address";
159
	$l_no_primary_connected = "No primary connected";
3308 rexy 160
	$l_no_ssh_key		= "No SSH key imported.";
3294 rexy 161
	$l_not_connected	= "Not connected";
162
	$l_pubkey_to_deploy	= "The following public key has to be deployed on remote primary servers.";
163
	$l_remote_access_mgmt	= "Remote access management";
164
	$l_remote_role		= "Remote role";
165
	$l_repl_io_running	= "State";
166
	$l_replication_install	= "Setting up the federation";
167
	$l_replication_title	= "Federation";
168
	$l_role_primary		= "Primary";
169
	$l_role_secondary	= "Secondary";
170
	$l_ssh_keys_for_primary	= "List of keys allowed to connect to local 'replication' user.";
171
	$l_ssh_port		= "SSH port";
172
	$l_ssh_user		= "SSH user";
173
	$l_ssh_wan_enabled	= "SSH on WAN is enabled.";
174
	$l_ssh_wan_must_be_on	= "SSH on WAN must be enabled.";
175
	$l_start		= "Start";
176
	$l_stop			= "Stop";
177
	$l_uninstall_repl	= "Uninstall the federation";
178
	$l_value		= "Value";
179
	$l_want_server_as_prim	= "Want server to be a primary?";
180
}
181
 
182
$reg_ip      = '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$';
183
$reg_ip_port = '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\:([1-9]|[1-9][0-9]|[1-9][0-9]{2}|[1-9][0-9]{3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))$';
184
$reg_host    = '^[a-zA-Z0-9-_]+$';
185
$reg_ssh_key = "^(ssh-dss AAAAB3NzaC1kc3|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb2|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29t|ssh-rsa AAAAB3NzaC1yc2)[0-9A-Za-z+/]+[=]{0,3}(\s.*)?$";
186
$reg_linux_user = "[a-z_][a-z0-9_-]*[$]?";
187
$reg_mariadb_user = "^[a-z]{1,32}$";
188
 
189
// Allow new SSH file size of 128kB;
190
$max_ssh_file_size = 131072;
191
 
192
$choice = $_POST['choice'] ?? "";
193
switch ($choice) {
194
	case 'install_replication':
195
		if (isset($conf['REPLICATION']) && $conf['REPLICATION'] == "on") {
196
			exit("Replication already installed.");}
197
		$stdout = [];
198
		exec('sudo /usr/local/bin/alcasar-replication-install.sh 2>&1', $stdout);
199
		header('Location: '.$_SERVER['PHP_SELF']);
200
		break;
201
	case 'uninstall_replication':
202
		if (!isset($conf['REPLICATION']) || $conf['REPLICATION'] == "off") {
203
			exit("Replication not installed.");}
204
		$stdout = [];
205
		exec('sudo /usr/local/bin/alcasar-replication-uninstall.sh 2>&1', $stdout);
206
		header('Location: '.$_SERVER['PHP_SELF']);
207
		break;
208
	case 'add_replica':
209
		$role = trim($_POST['role'] ?? "");
210
		$name = trim($_POST['name'] ?? "");
211
		$ip = trim($_POST['ip'] ?? "");
212
		$port = trim($_POST['port'] ?? "");
3308 rexy 213
		// we fix ssh user name to simplify ACC
214
		// $user = trim($_POST['user'] ?? "");
215
		$user = "replication" ;
216
		// we fix db user name to simplify ACC
217
		// $db_user = trim($_POST['db_user'] ?? "");
218
		$db_user = "db_replication";
3294 rexy 219
		$db_pwd = trim($_POST['db_pwd'] ?? "");
220
		$bind_port = trim($_POST['bind_port'] ?? "");
221
		$stdout = [];
222
		$return = 0;
223
		switch ($role) {
224
			case 'primary':
225
				exec("sudo /usr/local/bin/alcasar-replication-add.sh --to-primary"." --name=".escapeshellarg($name)." --address=".escapeshellarg($ip)." --port=".escapeshellarg($port)." --user=". escapeshellarg($user)." --db-user=".escapeshellarg($db_user)." --db-password=".escapeshellarg($db_pwd)." 2>&1", $stdout, $return);
226
				break;
227
			case 'secondary':
228
				exec("sudo /usr/local/bin/alcasar-replication-add.sh --to-secondary"." --name=".escapeshellarg($name)." --bind-port=".escapeshellarg($bind_port)." --db-user=".escapeshellarg($db_user)." --db-password=".escapeshellarg($db_pwd)." 2>&1", $stdout, $return);
229
				break;
230
			default:
231
				// Error
232
				exit();}
233
		// If script went wrong
234
		if ($return) {
235
			$key = $choice . "_error";
236
			// Concatenate stdout lines
237
			$value = implode(PHP_EOL, $stdout);
238
			// Save error message in cookies
239
			setcookie($key, $value);
240
		}
241
		header('Location: '.$_SERVER['PHP_SELF']);
242
		break;
243
	case 'change_replicas_state':
244
		$stdout = [];
245
		$return = 0;
246
		$key_prefix = "action_primary_";
247
 
248
		// Search for action_primary_<hostname> key
249
		foreach ($_POST as $key => $value) {
250
			if (!str_starts_with($key, $key_prefix)) {
251
				continue;}
252
			// Get the remote name
253
			$name = explode($key_prefix, $key)[1];
254
			switch ($value) {
255
				case 'start':
256
					exec("sudo /usr/local/bin/alcasar-replication-start.sh --name=".escapeshellarg($name)." 2>&1", $stdout, $return);
257
					break;
258
				case 'stop':
259
					exec("sudo /usr/local/bin/alcasar-replication-stop.sh --name=".escapeshellarg($name)." 2>&1", $stdout, $return);
260
					break;
261
				case 'delete':
262
					exec("sudo /usr/local/bin/alcasar-replication-delete.sh --name=".escapeshellarg($name)." 2>&1", $stdout, $return);
263
					break;
264
				default:
265
					break;
266
			}
267
		}
268
		// If script went wrong
269
		if ($return) {
270
			$key = $choice . "_error";
271
			// Concatenate stdout lines
272
			$value = implode(PHP_EOL, $stdout);
273
			// Save error message in cookies
274
			setcookie($key, $value);
275
		}
276
		header('Location: '.$_SERVER['PHP_SELF']);
277
		break;
278
	case 'add_ssh_key':
279
		$file = $_FILES['new_ssh_key_input'] ?? "";
280
		$stdout = [];
281
		$return = 0;
282
		// Stop if file doesn't exist
283
		if (empty($file)) {
284
			break;}
285
		// Check file size
286
		if ($file['size'] > $max_ssh_file_size) {
287
			break;}
288
		// Add new key(s) to authorized keys list
289
		$tmp_file = $file['tmp_name'];
290
		exec("sudo /usr/local/bin/alcasar-replication-ssh-keys-management.sh --add --file=$tmp_file 2>&1", $stdout, $return);
291
		// If script went wrong
292
		if ($return) {
293
			$key = $choice . "_error";
294
			// Concatenate stdout lines
295
			$value = implode(PHP_EOL, $stdout);
296
			// Save error message in cookies
297
			setcookie($key, $value);
298
		}
299
		header('Location: '.$_SERVER['PHP_SELF']);
300
		break;
301
	case 'delete_ssh_key':
302
		$stdout = [];
303
		$return = 0;
304
		$key_prefix = "action_ssh_key_";
305
		foreach ($_POST as $key => $value) {
306
			if (!str_starts_with($key, $key_prefix)) {
307
				continue;}
308
			$decoded_value = htmlspecialchars_decode($value);
309
			// Delete key
310
			exec("sudo /usr/local/bin/alcasar-replication-ssh-keys-management.sh --delete --regex=$decoded_value 2>&1", $stdout, $return);
311
			// If script went wrong
312
			if ($return) {
313
				$key = $choice . "_error";
314
				// Concatenate stdout lines
315
				$value = implode(PHP_EOL, $stdout);
316
				// Save error message in cookies
317
				setcookie($key, $value);
318
			}
319
		}
320
		header('Location: '.$_SERVER['PHP_SELF']);
321
		break;
322
	default:
323
		break;
324
}
325
 
326
?>
327
<!DOCTYPE HTML>
328
<html>
329
<head>
330
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
331
	<title><?= $l_replication_title ?></title>
332
	<link rel="stylesheet" href="/css/acc.css" type="text/css">
333
	<script src="/js/jquery.min.js"></script>
334
	<script src="/js/jquery.connections.js"></script>
335
	<script type="text/javascript">
336
		window.onload = main;
337
		function main() {
338
			show_fields_for_new_primary();
339
			set_required_on_common_fields();
340
			enable_apply_btn_if_selected_primary_action();
341
			enable_apply_btn_if_selected_ssh_key_action();
342
		}
343
		// Set 'required' attribute on fields needed by both primary and secondary
344
		function set_required_on_common_fields() {
345
			document.querySelectorAll(".role_primary.role_secondary").forEach((input) => {
346
				input.setAttribute("required", "");
347
			});
348
		}
349
		// Only enable fields needed for new primary remote
350
		function show_fields_for_new_primary() {
351
			// Toggle 'disabled' and 'required' attributes
352
			document.querySelectorAll("input[class='role_primary']").forEach((input) => {
353
				input.removeAttribute("disabled");
354
				input.setAttribute("required", "");
355
			});
356
			document.querySelectorAll("input[class='role_secondary']").forEach((input) => {
357
				input.setAttribute("disabled", "");
358
				input.removeAttribute("required");
359
			});
360
		}
361
		function show_fields_for_new_secondary() {
362
			// Toggle 'disabled' and 'required' attributes
363
			document.querySelectorAll("input[class='role_primary']").forEach((input) => {
364
				input.removeAttribute("required");
365
				input.setAttribute("disabled", "");
366
			});
367
			document.querySelectorAll("input[class='role_secondary']").forEach((input) => {
368
				input.setAttribute("required", "");
369
				input.removeAttribute("disabled");
370
			});
371
		}
372
		// Enable the remote's list Apply button if there are any pending actions
373
		function enable_apply_btn_if_selected_primary_action() {
374
			let btn = document.querySelector("#apply_changes_primary_btn");
375
			if (!btn) {
376
				return;}
377
			let change_to_apply = false;
378
			// Check for any pending change
379
			document.querySelectorAll(".primary_action_select").forEach((element) => {
380
				if (element.value != "") {
381
					btn.removeAttribute("disabled");
382
					change_to_apply = true;
383
				}
384
			});
385
			// Disable button if there are no pending changes
386
			if (!change_to_apply) {
387
				btn.setAttribute("disabled", "");
388
			}
389
		}
390
		// Enable the SSH keys's list Apply button if there are any pending actions
391
		function enable_apply_btn_if_selected_ssh_key_action() {
392
			let btn = document.querySelector("#apply_changes_ssh_key_btn");
393
			if (!btn) {
394
				return;
395
			}
396
			let change_to_apply = false;
397
			// Check for any pending change
398
			document.querySelectorAll(".ssh_key_action_input").forEach((element) => {
399
				if (element.checked) {
400
					btn.removeAttribute("disabled");
401
					change_to_apply = true;
402
				}
403
			});
404
			// Disable button if there are no pending changes
405
			if (!change_to_apply) {
406
				btn.setAttribute("disabled", "");
407
			}
408
		}
409
	</script>
410
</head>
411
<body>
412
<div id="ldoverlay" class="overlay">
413
	<div class="lds-spinner" id="spinner"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
414
</div>
415
<?php if ($conf['REPLICATION'] == "on") { ?>
416
<div class="panel">
417
	<div class="panel-header"><?= $l_hosts_settings ?></div>
418
</div>
419
<div>
420
<table width="100%" cellspacing="0" cellpadding="5" border="1">
421
	<tr>
422
		<td width="50%" align="center">
423
			<?php $section = "change_replicas_state" ?>
424
			<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="POST">
425
			<input type="hidden" name="choice" value="<?= $section ?>">
426
			<table cellspacing="2" cellpadding="3" border="1" style="table-layout: auto; min-width: 10em;">
427
				<tr>
428
					<th><?= $l_ip_address ?></th>
429
					<th><?= $l_host_name ?></th>
430
					<th><?= $l_repl_io_running ?></th>
431
					<th><?= $l_bind_port ?></th>
432
					<th><?= $l_action ?></th>
433
				</tr>
434
				<?php
435
				$stdout = [];
436
				$return = 0;
437
				exec("sudo /usr/local/bin/alcasar-replication-list.sh --all 2>&1", $stdout, $return);
438
 
439
				// If script went wrong
440
				if ($return) {
441
					// Print error message
442
					$errors_msg[$section."_error"] = implode(PHP_EOL, $stdout);
443
				// Successfully fetched remotes stats
444
				} else {
445
					$connected_prims = [];
446
					$current_prim = "";
447
					// Parse stdout in keys-array
448
					foreach ($stdout as $row) {
449
						// Skip useless delimiter
450
						if (str_starts_with($row, '*')) {
451
							continue;
452
						}
453
						// Split key: value
454
						$exploded = explode(": ", $row);
455
						$key = $exploded[0];
456
						$value = $exploded[1] ?? "";
457
						// Create subarray when starting to display a new remote
458
						if (!strcmp($key, "Connection_name")) {
459
							$current_prim = $value;
460
							$connected_prims[$current_prim] = [];
461
						}
462
						// Put value in prim's subarray
463
						($connected_prims[$current_prim])[$key] = $value;
464
					}
465
					// Skip resetted replicas,
466
					// they will stay displayed still the next database restart.
467
					foreach ($connected_prims as $prim) {
468
						if (empty($prim["Relay_Log_File"])) {
469
							unset($connected_prims[$prim["Connection_name"]]);
470
						}
471
					}
472
					// List each connection
473
					foreach ($connected_prims as $prim) {
474
						?>
475
						<tr>
476
							<td><?php
477
								$master_host = $prim["Master_Host"];
478
								if ($master_host != "127.0.0.1") {
479
									echo "$master_host";
480
								} else {
481
									echo "$l_not_connected";
482
								}
483
							?></td>
484
							<td><?= $prim["Connection_name"] ?></td>
485
							<td><?= $prim["Slave_IO_Running"] ?></td>
486
							<td><?= $prim["Master_Port"] ?></td>
487
							<td>
488
								<select name="action_primary_<?= $prim["Connection_name"] ?>" class="primary_action_select" onchange="enable_apply_btn_if_selected_primary_action()">
489
									<option value=""></option>
490
									<?php
491
										// Actions available on all remotes
492
										$options = array(
493
											"start" => "$l_start",
494
											"stop" => "$l_stop",
495
											"delete" => "$l_delete"
496
										);
497
										// Remove some options depending on the current remote state
498
										switch ($prim["Slave_IO_Running"]) {
499
										case 'Yes':
500
										case 'Connecting':
501
											unset($options["start"]);
502
											unset($options["delete"]);
503
											break;
504
										case 'No':
505
											unset($options["stop"]);
506
											break;
507
										default:
508
											break;
509
										}
510
										// Print options
511
										foreach ($options as $key => $value) { ?>
512
											<option value="<?= $key ?>"><?= $value ?></option>
513
										<?php }
514
									 ?>
515
								</select>
516
							</td>
517
						</tr>
518
					<?php }
519
					// Show submit button if there are primary servers connected
520
					echo "<tr><td colspan=5 valign='middle' align='center'>";
521
					if (sizeof($connected_prims)) { ?>
522
						<input type="submit" id="apply_changes_primary_btn" value="<?= $l_apply ?>" onClick="document.getElementById('ldoverlay').style.display='block';">
523
					<?php } else { ?>
524
						<p><?= $l_no_primary_connected ?></p>
525
					<?php }
526
					echo "</td></tr>";
527
				} ?>
528
			</table>
529
			</form>
530
			<?php if (isset($errors_msg[$section."_error"])) { ?>
531
				<details open>
532
					<summary><?= $l_error_details ?></summary>
533
					<textarea readonly cols=50 rows=10><?= $errors_msg[$section."_error"] ?></textarea>
534
				</details>
535
			<?php } ?>
536
		</td>
537
		<td width="50%" valign="middle" align="center">
538
			<?php $section = "add_replica" ?>
539
			<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="POST">
540
			<input type="hidden" name="choice" value="<?= $section ?>">
541
				<table cellspacing="2" cellpadding="3" border="1">
542
					<tr>
543
						<th><?= $l_field ?></th>
544
						<th><?= $l_value ?></th>
545
					</tr>
546
					<tr>
547
						<td><?= $l_remote_role ?></td>
548
						<td>
549
							<fieldset>
550
								<div>
551
									<input type="radio" id="role_primary" name="role" value="primary" checked onClick="show_fields_for_new_primary()"/>
552
									<label for="role_primary"><?= $l_role_primary ?></label>
553
 
554
									<input type="radio" id="role_secondary" name="role" value="secondary" onClick="show_fields_for_new_secondary()"/>
555
									<label for="role_secondary"><?= $l_role_secondary ?></label>
556
								</div>
557
							</fieldset>
558
						</td>
559
					</tr>
560
					<tr>
561
						<td><label for="input_name"><?= $l_host_name ?></label></td>
562
						<td><input type="text" id="input_name" name="name" class="role_primary role_secondary" pattern="<?= $reg_host ?>"></td>
563
					</tr>
564
					<tr>
565
						<td><label for="input_ip"><?= $l_ip_address ?></label></td>
566
						<td><input type="text" id="input_ip" name="ip" class="role_primary" pattern="<?= $reg_ip ?>"></td>
567
					</tr>
568
					<tr>
569
						<td><label for="input_bind_port"><?= $l_bind_port ?></label></td>
570
						<td><input type="number" id="input_bind_port" name="bind_port" min="0" max="65535" class="role_secondary" pattern="<?= $reg_ip_port ?>"></td>
571
					</tr>
572
					<tr>
573
						<td><label for="input_port"><?= $l_ssh_port ?></label></td>
574
						<td><input type="number" id="input_port" name="port" min="0" max="65535" placeholder="22" class="role_primary" pattern="<?= $reg_ip_port ?>"></td>
575
					</tr>
3308 rexy 576
<!--					<tr>
3294 rexy 577
						<td><label for="input_user"><?= $l_ssh_user ?></label></td>
578
						<td><input type="text" id="input_user" name="user" value="replication" disabled class="role_primary" pattern="<?= $reg_linux_user ?>"></td>
579
					</tr>
580
					<tr>
581
						<td><label for="input_db_user"><?= $l_db_user ?></label></td>
582
						<td><input type="text" id="input_db_user" name="db_user" value="replication" disabled class="role_primary role_secondary" pattern="<?= $reg_mariadb_user ?>"></td>
583
					</tr>
3308 rexy 584
-->
3294 rexy 585
					<tr>
3308 rexy 586
					<td><label for="input_db_pwd"><?= $l_db_pwd ?></label></td>
3294 rexy 587
						<td><input type="password" id="input_db_pwd" name="db_pwd" class="role_primary role_secondary"></td>
588
					</tr>
589
					<tr>
590
						<td colspan=2 valign="middle" align="center">
591
							<input type="submit" class="button" value="<?= $l_add_to_list ?>" onClick="document.getElementById('ldoverlay').style.display='block';">
592
						</td>
593
					</tr>
594
				</table>
595
			</form>
596
			<?php if (isset($errors_msg[$section."_error"])) { ?>
597
				<details open>
598
					<summary><?= $l_error_details ?></summary>
599
					<textarea readonly cols=50 rows=10><?= htmlspecialchars($errors_msg[$section."_error"]) ?></textarea>
600
				</details>
601
			<?php } ?>
602
		</td>
603
	</tr>
604
</table>
605
</div>
606
<br>
607
<div class="panel">
608
	<div class="panel-header"><?= $l_remote_access_mgmt ?></div>
609
</div>
610
<div>
611
<table width="100%" cellspacing="0" cellpadding="5" border="1">
612
	<tr>
613
		<td width="50%" align="center">
614
			<p><?= $l_ssh_keys_for_primary ?></p>
615
			<?php $section = "delete_ssh_key" ?>
616
			<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="POST">
617
			<input type="hidden" name="choice" value="<?= $section ?>">
618
			<table cellspacing="2" cellpadding="3" border="1" style="table-layout: auto; min-width: 10em;">
619
				<tr>
620
					<th><?= $l_host_name ?></th>
621
					<th><?= $l_algorithm ?></th>
622
					<th><?= $l_delete ?></th>
623
				</tr>
624
				<?php
625
				$stdout = [];
626
				$return = 0;
627
				exec("sudo /usr/local/bin/alcasar-replication-ssh-keys-management.sh --list 2>&1", $stdout, $return);
628
				// If script went wrong
629
				if ($return) {
630
					// Print error message
631
					$errors_msg[$section."_error"] = implode(PHP_EOL, $stdout);
632
				// Successfully fetched remotes stats
633
				} else {
634
					// List each key
635
					foreach ($stdout as $line) {
636
						// Skip empty lines
637
						if (str_starts_with($line, ' ')) {
638
							continue;
639
						}
640
						// Split args
641
						$exploded = explode(' ', $line);
642
						$algo = $exploded[0] ?? "";
643
						$hostname = $exploded[2] ?? "";
644
						?>
645
						<tr>
646
							<td><?= $hostname ?></td>
647
							<td><?= $algo ?></td>
648
							<td>
649
								<input type="checkbox" name="action_ssh_key_<?= htmlspecialchars($hostname) ?>" value="<?= htmlspecialchars($hostname) ?>" class="ssh_key_action_input" onchange="enable_apply_btn_if_selected_ssh_key_action()">
650
							</td>
651
						</tr>
652
					<?php }
653
					// Show submit button if there are primary servers connected
3308 rexy 654
					echo "<tr><td colspan=3 valign='middle' align='center'>";
3294 rexy 655
					if (sizeof($stdout)) { ?>
656
						<input type="submit" id="apply_changes_ssh_key_btn" value="<?= $l_apply ?>" onClick="document.getElementById('ldoverlay').style.display='block';">
657
					<?php } else { ?>
658
						<p><?= $l_no_ssh_key ?></p>
659
					<?php }
3308 rexy 660
					echo "</td></tr>";
3294 rexy 661
				} ?>
662
			</table>
663
			</form>
664
			<?php if (isset($errors_msg[$section."_error"])) { ?>
665
				<details open>
666
					<summary><?= $l_error_details ?></summary>
667
					<textarea readonly cols=50 rows=10><?= $errors_msg[$section."_error"] ?></textarea>
668
				</details>
669
			<?php } ?>
670
		</td>
671
		<td width="25%" valign="middle" align="center">
672
			<?php $section = "add_ssh_key" ?>
673
			<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="POST" enctype="multipart/form-data">
674
			<input type="hidden" name="choice" value="<?= $section ?>">
675
				<input type="hidden" name="MAX_FILE_SIZE" value="<?= $max_ssh_file_size ?>" />
3306 rexy 676
				<label for="new_ssh_key_input"><?= $l_import_ssh_key ?><br></label>
3294 rexy 677
				<br>
678
				<input type="file" name="new_ssh_key_input" id="new_ssh_key_input" accept=".pub">
679
				<br>
680
				<input type="submit" class="button" value="<?= $l_add_to_list ?>" onClick="document.getElementById('ldoverlay').style.display='block';">
681
			</form>
682
			<?php if (isset($errors_msg[$section."_error"])) { ?>
683
				<details open>
684
					<summary><?= $l_error_details ?></summary>
685
					<textarea readonly cols=50 rows=10><?= $errors_msg[$section."_error"] ?></textarea>
686
				</details>
687
			<?php } ?>
688
		</td>
689
		<td width="25%" valign="middle" align="center">
3306 rexy 690
				<label for="pubkey_stdout"><?= $l_pubkey_to_deploy ?><br></label>
3294 rexy 691
				<br>
692
				<?php
693
				$stdout = [];
694
				$return = 0;
695
				exec("sudo /usr/local/bin/alcasar-replication-ssh-keys-management.sh --show-pubkey 2>&1", $stdout, $return);
696
				// If script went wrong
697
				if ($return != 0) {
698
					echo "<p>$l_cant_read_pubkey</p>";
699
				} else { ?>
700
					<input type="text" id="pubkey_stdout" readonly value="<?= implode(PHP_EOL, $stdout) ?>">
701
				<?php } ?>
702
		</td>
703
	</tr>
704
</table>
705
</div>
706
<br>
707
<?php } ?>
708
<div class="panel">
709
	<div class="panel-header"><?= $l_replication_title ?></div>
710
</div>
711
<table width="100%" cellspacing="0" cellpadding="5" border="1">
712
	<tr>
713
		<td width="50%" valign="middle" align="center">
714
			<?php if ($conf['REPLICATION'] == "on") { ?>
715
				<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="POST" onsubmit="return confirm('<?= $l_confirm_uninstall ?>');">
716
					<input type="hidden" name="choice" value="uninstall_replication">
717
					<input type="submit" value="<?= $l_uninstall_repl ?>" onClick="document.getElementById('ldoverlay').style.display='block';">
718
				</form>
719
			<?php } else { ?>
720
				<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="POST">
721
					<input type="hidden" name="choice" value="install_replication">
722
					<input type="submit" value="<?= $l_install_repl ?>" onClick="document.getElementById('ldoverlay').style.display='block';">
723
				</form>
724
			<?php } ?>
725
		</td>
726
		<?php if ($conf['REPLICATION'] == "on") { ?>
727
			<td width="50%" valign="middle" align="center">
728
				<?php if ($conf['SSH_WAN'] !== '0') { ?>
729
					<input type="checkbox" id="togglessh" checked disabled>
730
					<label for="togglessh"><?= $l_ssh_wan_enabled ?></label>
731
				<?php } else { ?>
732
				<p><?= $l_want_server_as_prim ?></p>
733
					<input type="checkbox" id="togglessh" disabled>
734
					<label for="togglessh"><b><?= $l_ssh_wan_must_be_on ?></b> <a href="/acc/admin/network.php"><?= $l_go_network_conf_page ?></a></label>
735
				<?php } ?>
736
			</td>
737
		<?php } ?>
738
	</tr>
739
</table>
740
</body>
741
</html>