Add backup FROM SFTP to local

This commit is contained in:
Clement Desmidt 2020-04-16 17:57:14 +02:00
parent c18d517afb
commit 0952cf2db3
9 changed files with 184 additions and 17 deletions

View File

@ -29,10 +29,14 @@ class Folder extends TransportAbstract
*/ */
public function send() public function send()
{ {
if ($this->backup->isDistant()) {
$this->backup = $this->backup->retrieve();
}
if ($this->backup->isLocal()) {
foreach ($this->backup->getFilesToBackup() as $file => $name) { foreach ($this->backup->getFilesToBackup() as $file => $name) {
if (copy($file, $this->folder . $name) === false) { if (copy($file, $this->folder . $name) === false) {
throw new \Exception(sprintf('Copy of %s in %s failed', $name, $this->folder)); throw new \Exception(sprintf('Copy of %s in %s failed', $name, $this->folder));
}; }
} }
foreach ($this->backup->getStreamsToBackup() as $name => $file) { foreach ($this->backup->getStreamsToBackup() as $name => $file) {
if (substr_count($name, '.') + 1 < 2) { if (substr_count($name, '.') + 1 < 2) {
@ -42,6 +46,8 @@ class Folder extends TransportAbstract
throw new \Exception(sprintf('Saving of %s in %s failed', $name, $this->folder)); throw new \Exception(sprintf('Saving of %s in %s failed', $name, $this->folder));
} }
} }
}
return true; return true;
} }
} }

View File

@ -28,7 +28,7 @@ abstract class BackupAbstract
* *
* @param array $config array of options and parameters * @param array $config array of options and parameters
*/ */
public function __construct($config = array()) public function __construct($config = [])
{ {
$this->options = !empty($config['options']) ? $config['options'] : []; $this->options = !empty($config['options']) ? $config['options'] : [];

View File

@ -1,16 +1,21 @@
<?php <?php
namespace Shikiryu\Backup\Backup; namespace Shikiryu\Backup\Backup;
use Shikiryu\Exceptions\BackupException;
class Files extends BackupAbstract class Files extends BackupAbstract
{ {
use IsLocalTrait;
/** /**
* @param array $config * @param array $config
* @throws \Exception * @throws BackupException
*/ */
public function __construct(array $config = array()) public function __construct(array $config = [])
{ {
if (!isset($config['files'])) { if (!isset($config['files'])) {
throw new \Exception('Files needs a "files" configuration.'); throw new BackupException('Files needs a "files" configuration.');
} }
$filesToBackup = $config['files']; $filesToBackup = $config['files'];
if (!empty($filesToBackup) && is_array($filesToBackup)) { if (!empty($filesToBackup) && is_array($filesToBackup)) {
@ -27,7 +32,7 @@ class Files extends BackupAbstract
* *
* @SuppressWarnings("unused") * @SuppressWarnings("unused")
*/ */
public function isValid() public function isValid(): bool
{ {
$result = true; $result = true;
foreach ($this->files_to_backup as $file => $name) { foreach ($this->files_to_backup as $file => $name) {

View File

@ -4,6 +4,8 @@ namespace Shikiryu\Backup\Backup;
class Folder extends BackupAbstract class Folder extends BackupAbstract
{ {
use IsLocalTrait;
public function __construct(array $config = array()) public function __construct(array $config = array())
{ {
parent::__construct($config); parent::__construct($config);

View File

@ -0,0 +1,18 @@
<?php
namespace Shikiryu\Backup\Backup;
trait IsDistantTrait
{
public function isLocal()
{
return false;
}
public function isDistant()
{
return true;
}
abstract public function retrieve();
}

View File

@ -0,0 +1,16 @@
<?php
namespace Shikiryu\Backup\Backup;
trait IsLocalTrait
{
public function isLocal()
{
return true;
}
public function isDistant()
{
return false;
}
}

View File

@ -4,6 +4,7 @@ namespace Shikiryu\Backup\Backup;
class Mysql extends BackupAbstract class Mysql extends BackupAbstract
{ {
use IsLocalTrait;
/** /**
* @var $pdo \PDO * @var $pdo \PDO
@ -22,7 +23,7 @@ class Mysql extends BackupAbstract
/** /**
* @param array $config * @param array $config
*/ */
public function __construct(array $config = array()) public function __construct(array $config = [])
{ {
parent::__construct($config); parent::__construct($config);
} }
@ -31,7 +32,7 @@ class Mysql extends BackupAbstract
* @param array $tables * @param array $tables
* @return $this|string * @return $this|string
*/ */
private function fromTables($tables = array()) private function fromTables($tables = [])
{ {
if (!empty($tables)) { if (!empty($tables)) {
$this->tables = $tables; $this->tables = $tables;

112
app/code/backup/SFTP.php Normal file
View File

@ -0,0 +1,112 @@
<?php
namespace Shikiryu\Backup\Backup;
use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP as LibSFTP;
use phpseclib\Net\SSH2;
class SFTP extends BackupAbstract
{
use IsDistantTrait;
/**
* @var LibSFTP
*/
private $connection;
/** @var string */
protected $host;
/** @var int */
protected $port = 22;
/** @var string */
protected $login;
/** @var string */
protected $password;
/** @var string */
protected $key;
public function __construct($config = [])
{
if (!isset($config['files'])) {
throw new \Exception('Files needs a "files" configuration.');
}
$filesToBackup = $config['files'];
if (!empty($filesToBackup) && is_array($filesToBackup)) {
$names = array_map('basename', $filesToBackup);
$this->files_to_backup = array_combine($filesToBackup, $names);
}
parent::__construct($config);
}
/**
* @inheritDoc
*/
protected function preBuild()
{
// TODO: Implement preBuild() method.
}
/**
* @inheritDoc
*/
protected function postBuild()
{
// TODO: Implement postBuild() method.
}
/**
* @inheritDoc
*/
protected function build()
{
// TODO: Implement build() method.
}
/**
* @inheritDoc
* @throws \Exception
*/
public function isValid()
{
if (empty($this->password) && empty($this->key)) {
return false;
}
define('NET_SSH2_LOGGING', SSH2::LOG_COMPLEX);
$this->connection = new LibSFTP($this->host, $this->port);
if (!empty($this->key)) {
$this->password = new RSA();
$this->password->loadKey(file_get_contents($this->key));
}
if (!$this->connection->login($this->login, $this->password)) {
throw new \Exception(sprintf('I can\'t connect to the SFTP %s', $this->host));
}
$this->connection->enableQuietMode();
$this->connection->exec('whoami');
return $this->connection->getStdError() === '' && $this->connection->read() !== '';
}
/**
* @return Files
*/
public function retrieve()
{
$tmp_files = [];
foreach ($this->files_to_backup as $path => $name) {
$tmp_file = TEMP_DIR.$name;
$tmp_files[] = $tmp_file;
$this->connection->get($path, $tmp_file);
}
unset($tmp_file);
try {
$tmp_backup = new Files(['files' => $tmp_files]);
unset($tmp_files);
} catch (\Exception $e) {
echo $e->getMessage();
}
return $tmp_backup;
}
}

View File

@ -14,6 +14,13 @@
"tables": [ "tables": [
"" ""
] ]
},
"SFTP": {
"host" : "sftp.domain.com",
"port" : "22",
"login" : "login",
"password" : "password",
"folder" : "/folder"
} }
}, },
"transport": { "transport": {
@ -38,7 +45,7 @@
"folder" : "/folder" "folder" : "/folder"
}, },
"Folder": { "Folder": {
"folder" : "/folder"
}, },
"Dropbox": { "Dropbox": {
"token": "123456789123456789" "token": "123456789123456789"