Setup wizard step 1 (SSH key) stays as-is, then redirects to remotes.cgi?action=add&wizard=1 and schedules.cgi?action=add&wizard=1 instead of reimplementing its own forms. - Remove ~200 lines of duplicated form/handler code from setup.cgi - Wizard gets full feature parity (S3/GDrive, password auth, etc.) - key_path pre-fills REMOTE_KEY, remote_name pre-fills REMOTES - wizard=1 flag chains the flow: remote add → schedule add → index Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
124 lines
5.8 KiB
Perl
124 lines
5.8 KiB
Perl
#!/usr/local/cpanel/3rdparty/bin/perl
|
|
# gniza WHM Plugin — Setup Wizard
|
|
# Step 1: SSH Key selection, then redirects to remotes.cgi and schedules.cgi
|
|
use strict;
|
|
use warnings;
|
|
|
|
use lib '/usr/local/cpanel/whostmgr/docroot/cgi/gniza-whm/lib';
|
|
|
|
use Whostmgr::HTMLInterface ();
|
|
use Cpanel::Form ();
|
|
use GnizaWHM::UI;
|
|
|
|
my $form = Cpanel::Form::parseform();
|
|
|
|
handle_step1();
|
|
exit;
|
|
|
|
# ── Step 1: SSH Key ──────────────────────────────────────────
|
|
|
|
sub handle_step1 {
|
|
print "Content-Type: text/html\r\n\r\n";
|
|
Whostmgr::HTMLInterface::defheader('gniza Setup Wizard', '', '/cgi/gniza-whm/setup.cgi');
|
|
|
|
print GnizaWHM::UI::page_header('gniza Setup Wizard');
|
|
|
|
my $keys = GnizaWHM::UI::detect_ssh_keys();
|
|
|
|
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-6">\n<div class="card-body">\n};
|
|
print qq{<h2 class="card-title text-sm">Step 1: SSH Key</h2>\n};
|
|
print qq{<p>gniza uses SSH keys to connect to remote backup destinations. Select an existing key or create one first.</p>\n};
|
|
|
|
if (@$keys) {
|
|
print qq{<div class="my-4">\n};
|
|
print qq{<p><strong>Existing keys found:</strong></p>\n};
|
|
print qq{<table class="table table-zebra w-full">\n};
|
|
print qq{<thead><tr><th></th><th>Type</th><th>Path</th><th>Public Key</th></tr></thead>\n};
|
|
print qq{<tbody>\n};
|
|
my $first = 1;
|
|
for my $k (@$keys) {
|
|
my $checked = $first ? ' checked' : '';
|
|
my $pub = $k->{has_pub} ? 'Available' : 'Missing';
|
|
my $esc_path = GnizaWHM::UI::esc($k->{path});
|
|
my $esc_type = GnizaWHM::UI::esc($k->{type});
|
|
print qq{<tr>};
|
|
print qq{<td><input type="radio" class="radio radio-sm" name="selected_key" value="$esc_path" form="step1form"$checked></td>};
|
|
print qq{<td>$esc_type</td>};
|
|
print qq{<td><code>$esc_path</code></td>};
|
|
print qq{<td>$pub</td>};
|
|
print qq{</tr>\n};
|
|
$first = 0;
|
|
}
|
|
print qq{</tbody>\n</table>\n};
|
|
|
|
print qq{<div class="flex items-center gap-3 mt-3">\n};
|
|
print qq{ <input type="radio" class="radio radio-sm" name="selected_key" value="_custom" form="step1form" id="key_custom_radio">\n};
|
|
print qq{ <label for="key_custom_path">Custom path:</label>\n};
|
|
print qq{ <input type="text" class="input input-bordered input-sm w-full max-w-xs" id="key_custom_path" name="custom_key_path" form="step1form" placeholder="/root/.ssh/id_ed25519" onfocus="document.getElementById('key_custom_radio').checked=true">\n};
|
|
print qq{</div>\n};
|
|
print qq{</div>\n};
|
|
|
|
print qq{<form id="step1form" method="GET" action="remotes.cgi">\n};
|
|
print qq{<input type="hidden" name="action" value="add">\n};
|
|
print qq{<input type="hidden" name="wizard" value="1">\n};
|
|
print qq{<div class="flex gap-2 mt-4">\n};
|
|
print qq{ <button type="submit" class="btn btn-primary btn-sm" onclick="return gnizaPrepStep2()">Next: Configure Remote</button>\n};
|
|
print qq{ <a href="index.cgi" class="btn btn-ghost btn-sm">Cancel</a>\n};
|
|
print qq{</div>\n};
|
|
print qq{</form>\n};
|
|
} else {
|
|
print qq{<div class="alert alert-info mb-4">No SSH keys found in <code>/root/.ssh/</code>. You need to create one first.</div>\n};
|
|
}
|
|
|
|
# Always show key generation instructions
|
|
print qq{<div class="mt-5">\n};
|
|
print qq{<p><strong>Generate a new SSH key</strong> (if needed):</p>\n};
|
|
print qq{<pre class="bg-neutral text-neutral-content p-3 rounded-lg text-sm font-mono overflow-x-auto my-2">ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N ""</pre>\n};
|
|
print qq{<p><strong>Copy the public key</strong> to the remote server:</p>\n};
|
|
print qq{<pre class="bg-neutral text-neutral-content p-3 rounded-lg text-sm font-mono overflow-x-auto my-2">ssh-copy-id -i /root/.ssh/id_ed25519.pub user\@host</pre>\n};
|
|
print qq{<p class="text-xs text-base-content/60 mt-2">Run these commands in WHM → Server Configuration → Terminal, or via SSH.</p>\n};
|
|
print qq{</div>\n};
|
|
|
|
unless (@$keys) {
|
|
print qq{<form method="GET" action="remotes.cgi" class="mt-4">\n};
|
|
print qq{<input type="hidden" name="action" value="add">\n};
|
|
print qq{<input type="hidden" name="wizard" value="1">\n};
|
|
print qq{<div class="flex items-center gap-3 mb-2.5">\n};
|
|
print qq{ <label class="w-44 font-medium text-sm" for="key_path_manual">Key path:</label>\n};
|
|
print qq{ <input type="text" class="input input-bordered input-sm w-full max-w-xs" id="key_path_manual" name="key_path" value="/root/.ssh/id_ed25519">\n};
|
|
print qq{</div>\n};
|
|
print qq{<div class="flex gap-2 mt-4">\n};
|
|
print qq{ <button type="submit" class="btn btn-primary btn-sm">Next: Configure Remote</button>\n};
|
|
print qq{ <a href="index.cgi" class="btn btn-ghost btn-sm">Cancel</a>\n};
|
|
print qq{</div>\n};
|
|
print qq{</form>\n};
|
|
}
|
|
|
|
print qq{</div>\n</div>\n};
|
|
|
|
# JS to resolve selected key into key_path param
|
|
print <<'JS';
|
|
<script>
|
|
function gnizaPrepStep2() {
|
|
var form = document.getElementById('step1form');
|
|
var radios = document.querySelectorAll('input[name="selected_key"]');
|
|
var selected = '';
|
|
for (var i = 0; i < radios.length; i++) {
|
|
if (radios[i].checked) { selected = radios[i].value; break; }
|
|
}
|
|
if (selected === '_custom') {
|
|
selected = document.querySelector('input[name="custom_key_path"]').value;
|
|
}
|
|
if (!selected) { alert('Please select an SSH key.'); return false; }
|
|
var hidden = document.createElement('input');
|
|
hidden.type = 'hidden'; hidden.name = 'key_path'; hidden.value = selected;
|
|
form.appendChild(hidden);
|
|
return true;
|
|
}
|
|
</script>
|
|
JS
|
|
|
|
print GnizaWHM::UI::page_footer();
|
|
Whostmgr::HTMLInterface::footer();
|
|
}
|