move google drive backup to new framework for https://github.com/opnsense/core/pull/2251

Still some work todo, integrate configuration into new interface and iterate through available options in remote_backup.php.
The current state is functionally unchanged, only some minor cleanups in the previous backup code.
This commit is contained in:
Ad Schellevis 2018-03-20 20:58:02 +01:00
parent 71485968d2
commit 2eb5ac913a
5 changed files with 43 additions and 127 deletions

View File

@ -290,106 +290,6 @@ function make_config_revision_entry($desc = '')
return $revision;
}
/**
* backup config to google drive and return current file list (/ info)
*
*/
function backup_to_google_drive()
{
$cnf = OPNsense\Core\Config::getInstance();
if ($cnf->isValid()) {
$config = $cnf->object();
if (isset($config->system->remotebackup) && isset($config->system->remotebackup->GDriveEnabled) && $config->system->remotebackup->GDriveEnabled == "on") {
if (!empty($config->system->remotebackup->GDrivePrefixHostname)) {
$fileprefix = (string)$config->system->hostname . "." . (string)$config->system->domain . "-";
} else {
$fileprefix = "config-";
}
try {
$client = new Google\API\Drive();
$client->login($config->system->remotebackup->GDriveEmail->__toString(),
$config->system->remotebackup->GDriveP12key->__toString());
} catch (Exception $e) {
log_error("error connecting to Google Drive");
return array();
}
// backup source data to local strings (plain/encrypted)
$confdata = file_get_contents('/conf/config.xml');
$confdata_enc = encrypt_data($confdata, $config->system->remotebackup->GDrivePassword->__toString());
tagfile_reformat($confdata_enc, $confdata_enc, "config.xml");
// read filelist ({prefix}*.xml)
try {
$files = $client->listFiles($config->system->remotebackup->GDriveFolderID->__toString());
} catch (Exception $e) {
log_error("error while fetching filelist from Google Drive");
return array();
}
$configfiles = array();
foreach ($files as $file) {
if (fnmatch("{$fileprefix}*.xml", $file['title'])) {
$configfiles[$file['title']] = $file;
}
}
krsort($configfiles);
// backup new file if changed (or if first in backup)
$target_filename = $fileprefix . time() . ".xml";
if (count($configfiles) > 1) {
// compare last backup with current, only save new
try {
$bck_data_enc_in = $client->download($configfiles[array_keys($configfiles)[0]]);
$bck_data_enc = "";
tagfile_deformat($bck_data_enc_in, $bck_data_enc, "config.xml");
$bck_data = decrypt_data($bck_data_enc, $config->system->remotebackup->GDrivePassword->__toString());
if ($bck_data == $confdata) {
$target_filename = null;
}
} catch (Exception $e) {
log_error("unable to download " . $configfiles[array_keys($configfiles)[0]]->description . " from Google Drive (" . $e . ")");
}
}
if (!is_null($target_filename)) {
log_error("backup configuration as " . $target_filename);
try {
$configfiles[$target_filename] = $client->upload($config->system->remotebackup->GDriveFolderID->__toString(), $target_filename, $confdata_enc);
} catch (Exception $e) {
log_error("unable to upload " . $target_filename . " to Google Drive (" . $e . ")");
return array();
}
krsort($configfiles);
}
// cleanup old files
if (isset($config->system->remotebackup->GDriveBackupCount) && is_numeric($config->system->remotebackup->GDriveBackupCount->__toString())) {
$fcount = 0;
foreach ($configfiles as $filename => $file) {
if ($fcount >= $config->system->remotebackup->GDriveBackupCount->__toString()) {
log_error("remove " . $filename . " from Google Drive");
try {
$client->delete($file);
} catch (Google_Service_Exception $e) {
log_error("unable to remove " . $filename . " from Google Drive");
}
}
$fcount++;
}
}
// return filelist
return $configfiles;
}
}
// not configured / issue, return empty list
return array();
}
/**
* find list of registered interfaces
* @param array $filters list of filters to apply

View File

@ -58,7 +58,7 @@ abstract class Base
@unlink("{$file}.enc");
return base64_encode($result);
} else {
log_error('Failed to encrypt/decrypt data!');
syslog(LOG_ERR, 'Failed to encrypt/decrypt data!');
return null;
}
}
@ -85,7 +85,7 @@ abstract class Base
@unlink("{$file}.enc");
return $result;
} else {
log_error('Failed to encrypt/decrypt data!');
syslog(LOG_ERR, 'Failed to encrypt/decrypt data!');
return null;
}
}

View File

@ -125,25 +125,25 @@ class Gdrive extends Base implements IBackupProvider
$fileprefix = "config-";
}
try {
$client = new Google\API\Drive();
$client->login($config->system->remotebackup->GDriveEmail->__toString(),
$config->system->remotebackup->GDriveP12key->__toString());
$client = new \Google\API\Drive();
$client->login((string)$config->system->remotebackup->GDriveEmail,
(string)$config->system->remotebackup->GDriveP12key);
} catch (Exception $e) {
log_error("error connecting to Google Drive");
syslog(LOG_ERR, "error connecting to Google Drive");
return array();
}
// backup source data to local strings (plain/encrypted)
$confdata = file_get_contents('/conf/config.xml');
$confdata_enc = chunk_split(
$this->encrypt($confdata, $config->system->remotebackup->GDrivePassword->__toString())
$this->encrypt($confdata, (string)$config->system->remotebackup->GDrivePassword)
);
// read filelist ({prefix}*.xml)
try {
$files = $client->listFiles($config->system->remotebackup->GDriveFolderID->__toString());
$files = $client->listFiles((string)$config->system->remotebackup->GDriveFolderID);
} catch (Exception $e) {
log_error("error while fetching filelist from Google Drive");
syslog(LOG_ERR, "error while fetching filelist from Google Drive");
return array();
}
@ -162,21 +162,30 @@ class Gdrive extends Base implements IBackupProvider
// compare last backup with current, only save new
try {
$bck_data_enc = $client->download($configfiles[array_keys($configfiles)[0]]);
if (strpos(substr($bck_data_enc, 0, 100), '---') !== false) {
// base64 string is wrapped into tags
$start_at = strpos($bck_data_enc, "---\n") + 4 ;
$end_at = strpos($bck_data_enc, "\n---");
$bck_data_enc = substr($bck_data_enc, $start_at, ($end_at-$start_at));
}
$bck_data = $this->decrypt($bck_data_enc,
$config->system->remotebackup->GDrivePassword->__toString());
(string)$config->system->remotebackup->GDrivePassword);
if ($bck_data == $confdata) {
$target_filename = null;
}
} catch (Exception $e) {
log_error("unable to download " . $configfiles[array_keys($configfiles)[0]]->description . " from Google Drive (" . $e . ")");
syslog(LOG_ERR, "unable to download " .
$configfiles[array_keys($configfiles)[0]]->description . " from Google Drive (" . $e . ")"
);
}
}
if (!is_null($target_filename)) {
log_error("backup configuration as " . $target_filename);
syslog(LOG_ERR, "backup configuration as " . $target_filename);
try {
$configfiles[$target_filename] = $client->upload($config->system->remotebackup->GDriveFolderID->__toString(), $target_filename, $confdata_enc);
$configfiles[$target_filename] = $client->upload(
(string)$config->system->remotebackup->GDriveFolderID, $target_filename, $confdata_enc);
} catch (Exception $e) {
log_error("unable to upload " . $target_filename . " to Google Drive (" . $e . ")");
syslog(LOG_ERR, "unable to upload " . $target_filename . " to Google Drive (" . $e . ")");
return array();
}
@ -184,15 +193,16 @@ class Gdrive extends Base implements IBackupProvider
}
// cleanup old files
if (isset($config->system->remotebackup->GDriveBackupCount) && is_numeric($config->system->remotebackup->GDriveBackupCount->__toString())) {
if (isset($config->system->remotebackup->GDriveBackupCount)
&& is_numeric((string)$config->system->remotebackup->GDriveBackupCount)) {
$fcount = 0;
foreach ($configfiles as $filename => $file) {
if ($fcount >= $config->system->remotebackup->GDriveBackupCount->__toString()) {
log_error("remove " . $filename . " from Google Drive");
if ($fcount >= (string)$config->system->remotebackup->GDriveBackupCount) {
syslog(LOG_ERR, "remove " . $filename . " from Google Drive");
try {
$client->delete($file);
} catch (Google_Service_Exception $e) {
log_error("unable to remove " . $filename . " from Google Drive");
syslog(LOG_ERR, "unable to remove " . $filename . " from Google Drive");
}
}
$fcount++;
@ -200,7 +210,7 @@ class Gdrive extends Base implements IBackupProvider
}
// return filelist
return $configfiles;
return array_keys($configfiles);
}
}
@ -222,4 +232,4 @@ class Gdrive extends Base implements IBackupProvider
}
return false;
}
}
}

View File

@ -1,8 +1,12 @@
#!/usr/local/bin/php
<?php
require_once('script/load_phalcon.php');
require_once("util.inc");
require_once("config.inc");
use OPNsense\Backup\BackupFactory;
/* Backup to Google Drive (if configured) */
backup_to_google_drive();
$backupFact = new BackupFactory();
foreach ($backupFact->listProviders() as $classname => $provider) {
if ($provider['handle']->isEnabled()) {
$provider['handle']->backup();
}
}

View File

@ -109,6 +109,7 @@ $areas = array(
);
$do_reboot = false;
$backupFactory = new OPNsense\Backup\BackupFactory();
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$pconfig = array();
@ -283,7 +284,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
system_cron_configure();
try {
$filesInBackup = backup_to_google_drive();
$provider = $backupFactory->getProvider("GDrive");
$filesInBackup = $provider['handle']->backup();
} catch (Exception $e) {
$filesInBackup = array();
}
@ -294,8 +296,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$input_errors[] = gettext("Google Drive communication failure");
} else {
$input_messages = gettext("Backup successful, current file list:") . "<br>";
foreach ($filesInBackup as $filename => $file) {
$input_messages = $input_messages . "<br>" . $filename;
foreach ($filesInBackup as $filename) {
$input_messages .= "<br>" . $filename;
}
}
}