#!/usr/local/cpanel/3rdparty/bin/perl # gniza WHM Plugin — Remote Destination CRUD use strict; use warnings; use lib '/usr/local/cpanel/whostmgr/docroot/cgi/gniza-whm/lib'; use Whostmgr::HTMLInterface (); use Cpanel::Form (); use File::Copy (); use GnizaWHM::Config; use GnizaWHM::Validator; use GnizaWHM::UI; my $form = Cpanel::Form::parseform(); my $method = $ENV{'REQUEST_METHOD'} // 'GET'; my $action = $form->{'action'} // 'list'; # Route to handler if ($action eq 'test') { handle_test_connection() } elsif ($action eq 'add') { handle_add() } elsif ($action eq 'edit') { handle_edit() } elsif ($action eq 'delete') { handle_delete() } else { handle_list() } exit; # ── Test Connection (JSON) ──────────────────────────────────── sub handle_test_connection { print "Content-Type: application/json\r\n\r\n"; my $type = $form->{'remote_type'} || 'ssh'; if ($type eq 'ssh') { my $host = $form->{'host'} // ''; my $port = $form->{'port'} || '22'; my $user = $form->{'user'} || 'root'; my $auth_method = $form->{'auth_method'} || 'key'; my $key = $form->{'key'} // ''; my $password = $form->{'password'} // ''; if ($host eq '') { print qq({"success":false,"message":"Host is required."}); exit; } if ($auth_method eq 'password') { if ($password eq '') { print qq({"success":false,"message":"Password is required."}); exit; } } else { if ($key eq '') { print qq({"success":false,"message":"SSH key path is required."}); exit; } } my ($ok, $err) = GnizaWHM::UI::test_ssh_connection( host => $host, port => $port, user => $user, auth_method => $auth_method, key => $key, password => $password, ); if ($ok) { print qq({"success":true,"message":"SSH connection successful."}); } else { $err //= 'Unknown error'; $err =~ s/\\/\\\\/g; $err =~ s/"/\\"/g; $err =~ s/\n/\\n/g; print qq({"success":false,"message":"SSH connection failed: $err"}); } } elsif ($type eq 's3' || $type eq 'gdrive') { my %rclone_args = (type => $type); if ($type eq 's3') { $rclone_args{s3_access_key_id} = $form->{'S3_ACCESS_KEY_ID'} // ''; $rclone_args{s3_secret_access_key} = $form->{'S3_SECRET_ACCESS_KEY'} // ''; $rclone_args{s3_region} = $form->{'S3_REGION'} || 'us-east-1'; $rclone_args{s3_endpoint} = $form->{'S3_ENDPOINT'} // ''; $rclone_args{s3_bucket} = $form->{'S3_BUCKET'} // ''; if ($rclone_args{s3_access_key_id} eq '' || $rclone_args{s3_secret_access_key} eq '') { print qq({"success":false,"message":"S3 access key and secret are required."}); exit; } if ($rclone_args{s3_bucket} eq '') { print qq({"success":false,"message":"S3 bucket is required."}); exit; } } else { $rclone_args{gdrive_service_account_file} = $form->{'GDRIVE_SERVICE_ACCOUNT_FILE'} // ''; $rclone_args{gdrive_root_folder_id} = $form->{'GDRIVE_ROOT_FOLDER_ID'} // ''; if ($rclone_args{gdrive_service_account_file} eq '') { print qq({"success":false,"message":"Service account file path is required."}); exit; } } my ($ok, $err) = GnizaWHM::UI::test_rclone_connection(%rclone_args); if ($ok) { my $label = $type eq 's3' ? 'S3' : 'Google Drive'; print qq({"success":true,"message":"$label connection successful."}); } else { $err //= 'Unknown error'; $err =~ s/\\/\\\\/g; $err =~ s/"/\\"/g; $err =~ s/\n/\\n/g; print qq({"success":false,"message":"Connection failed: $err"}); } } else { print qq({"success":false,"message":"Unknown remote type."}); } exit; } # ── List ───────────────────────────────────────────────────── sub handle_list { print "Content-Type: text/html\r\n\r\n"; Whostmgr::HTMLInterface::defheader('gniza Backup Manager — Remotes', '', '/cgi/gniza-whm/remotes.cgi'); print GnizaWHM::UI::page_header('Remote Destinations'); print GnizaWHM::UI::render_nav('remotes.cgi'); print GnizaWHM::UI::render_flash(); my @remotes = GnizaWHM::UI::list_remotes(); print qq{
| Name | Type | Destination | Retention | Actions |
|---|---|---|---|---|
| $esc_name | }; print qq{$type_label | }; print qq{$dest | $retention | }; print qq{};
print qq{ };
print qq{Edit};
print qq{};
print qq{ };
print qq{ | };
print qq{
No remote destinations configured. Add a remote to enable multi-remote backups.
\n}; print qq{Remote configs are stored in /etc/gniza/remotes.d/.