mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-10 15:26:13 +01:00
incremental backups: stage 2: destinations
This commit is contained in:
0
IncBackups/__init__.py
Normal file
0
IncBackups/__init__.py
Normal file
6
IncBackups/admin.py
Normal file
6
IncBackups/admin.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
8
IncBackups/apps.py
Normal file
8
IncBackups/apps.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class IncbackupsConfig(AppConfig):
|
||||||
|
name = 'IncBackups'
|
||||||
0
IncBackups/migrations/__init__.py
Normal file
0
IncBackups/migrations/__init__.py
Normal file
6
IncBackups/models.py
Normal file
6
IncBackups/models.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
417
IncBackups/static/IncBackups/IncBackups.js
Normal file
417
IncBackups/static/IncBackups/IncBackups.js
Normal file
@@ -0,0 +1,417 @@
|
|||||||
|
//*** Backup site ****//
|
||||||
|
|
||||||
|
app.controller('createIncrementalBackups', function ($scope, $http, $timeout) {
|
||||||
|
|
||||||
|
$scope.destination = true;
|
||||||
|
$scope.backupButton = true;
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
$scope.runningBackup = true;
|
||||||
|
$scope.cancelButton = true;
|
||||||
|
|
||||||
|
populateCurrentRecords();
|
||||||
|
|
||||||
|
$scope.cancelBackup = function () {
|
||||||
|
|
||||||
|
var backupCancellationDomain = $scope.websiteToBeBacked;
|
||||||
|
|
||||||
|
url = "/backup/cancelBackupCreation";
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
backupCancellationDomain: backupCancellationDomain,
|
||||||
|
fileName: $scope.fileName,
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.fetchDetails = function () {
|
||||||
|
getBackupStatus();
|
||||||
|
populateCurrentRecords();
|
||||||
|
$scope.destination = false;
|
||||||
|
$scope.runningBackup = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function getBackupStatus() {
|
||||||
|
|
||||||
|
$scope.cyberpanelLoadingBottom = false;
|
||||||
|
|
||||||
|
var websiteToBeBacked = $scope.websiteToBeBacked;
|
||||||
|
|
||||||
|
url = "/backup/backupStatus";
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
websiteToBeBacked: websiteToBeBacked,
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
|
||||||
|
|
||||||
|
if (response.data.backupStatus === 1) {
|
||||||
|
|
||||||
|
if (response.data.abort === 1) {
|
||||||
|
$timeout.cancel();
|
||||||
|
$scope.cyberpanelLoadingBottom = true;
|
||||||
|
$scope.destination = false;
|
||||||
|
$scope.runningBackup = false;
|
||||||
|
$scope.cancelButton = true;
|
||||||
|
$scope.backupButton = false;
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
$scope.fileName = response.data.fileName;
|
||||||
|
$scope.status = response.data.status;
|
||||||
|
populateCurrentRecords();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$scope.destination = true;
|
||||||
|
$scope.backupButton = true;
|
||||||
|
$scope.runningBackup = false;
|
||||||
|
$scope.cancelButton = false;
|
||||||
|
|
||||||
|
$scope.fileName = response.data.fileName;
|
||||||
|
$scope.status = response.data.status;
|
||||||
|
$timeout(getBackupStatus, 2000);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$timeout.cancel();
|
||||||
|
$scope.cyberpanelLoadingBottom = true;
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
$scope.cancelButton = true;
|
||||||
|
$scope.backupButton = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$scope.destinationSelection = function () {
|
||||||
|
$scope.backupButton = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function populateCurrentRecords() {
|
||||||
|
|
||||||
|
var websiteToBeBacked = $scope.websiteToBeBacked;
|
||||||
|
|
||||||
|
url = "/backup/getCurrentBackups";
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
websiteToBeBacked: websiteToBeBacked,
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
|
||||||
|
|
||||||
|
if (response.data.fetchStatus == 1) {
|
||||||
|
$scope.records = JSON.parse(response.data.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$scope.createBackup = function () {
|
||||||
|
|
||||||
|
var websiteToBeBacked = $scope.websiteToBeBacked;
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
|
||||||
|
|
||||||
|
url = "/backup/submitBackupCreation";
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
websiteToBeBacked: websiteToBeBacked,
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
|
||||||
|
|
||||||
|
if (response.data.metaStatus === 1) {
|
||||||
|
getBackupStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$scope.deleteBackup = function (id) {
|
||||||
|
|
||||||
|
|
||||||
|
url = "/backup/deleteBackup";
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
backupID: id,
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
|
||||||
|
|
||||||
|
if (response.data.deleteStatus == 1) {
|
||||||
|
|
||||||
|
populateCurrentRecords();
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
///** Backup site ends **///
|
||||||
|
|
||||||
|
|
||||||
|
app.controller('incrementalDestinations', function ($scope, $http) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
$scope.sftpHide = true;
|
||||||
|
$scope.awsHide = true;
|
||||||
|
|
||||||
|
$scope.fetchDetails = function () {
|
||||||
|
|
||||||
|
if ($scope.destinationType === 'SFTP') {
|
||||||
|
$scope.sftpHide = false;
|
||||||
|
$scope.populateCurrentRecords();
|
||||||
|
} else {
|
||||||
|
$scope.sftpHide = true;
|
||||||
|
$scope.awsHide = false;
|
||||||
|
$scope.populateCurrentRecords();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.populateCurrentRecords = function () {
|
||||||
|
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
|
||||||
|
|
||||||
|
url = "/IncrementalBackups/populateCurrentRecords";
|
||||||
|
|
||||||
|
var type = 'SFTP';
|
||||||
|
if ($scope.destinationType === 'SFTP'){
|
||||||
|
type = 'SFTP';
|
||||||
|
}else{
|
||||||
|
type = 'AWS';
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
$scope.records = JSON.parse(response.data.data);
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addDestination = function (type) {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
|
||||||
|
|
||||||
|
url = "/IncrementalBackups/addDestination";
|
||||||
|
|
||||||
|
if(type === 'SFTP'){
|
||||||
|
var data = {
|
||||||
|
type: type,
|
||||||
|
IPAddress: $scope.IPAddress,
|
||||||
|
password: $scope.password,
|
||||||
|
backupSSHPort: $scope.backupSSHPort
|
||||||
|
};
|
||||||
|
}else {
|
||||||
|
var data = {
|
||||||
|
type: type,
|
||||||
|
AWS_ACCESS_KEY_ID: $scope.AWS_ACCESS_KEY_ID,
|
||||||
|
AWS_SECRET_ACCESS_KEY: $scope.AWS_SECRET_ACCESS_KEY,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
$scope.populateCurrentRecords();
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success!',
|
||||||
|
text: 'Destination successfully added.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.removeDestination = function (type, ipAddress) {
|
||||||
|
$scope.cyberpanelLoading = false;
|
||||||
|
|
||||||
|
|
||||||
|
url = "/IncrementalBackups/removeDestination";
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
type: type,
|
||||||
|
IPAddress: ipAddress,
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': getCookie('csrftoken')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||||
|
|
||||||
|
|
||||||
|
function ListInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
$scope.populateCurrentRecords();
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Success!',
|
||||||
|
text: 'Destination successfully removed.',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: response.data.error_message,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function cantLoadInitialDatas(response) {
|
||||||
|
$scope.cyberpanelLoading = true;
|
||||||
|
new PNotify({
|
||||||
|
title: 'Operation Failed!',
|
||||||
|
text: 'Could not connect to server, please refresh this page',
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
186
IncBackups/templates/IncBackups/createBackup.html
Executable file
186
IncBackups/templates/IncBackups/createBackup.html
Executable file
@@ -0,0 +1,186 @@
|
|||||||
|
|
||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Create Incremental Backup" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div id="page-title">
|
||||||
|
<h2>{% trans "Back up Website" %} - <a target="_blank" href="http://go.cyberpanel.net/backup" style="height: 23px;line-height: 21px;" class="btn btn-border btn-alt border-red btn-link font-red" title=""><span>{% trans "Backup Docs" %}</span></a></h2>
|
||||||
|
<p>{% trans "This page can be used to create incremental backups for your websites." %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-controller="createIncrementalBackups" class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Back up Website" %} <img ng-hide="backupLoading" src="{% static 'images/loading.gif' %}">
|
||||||
|
</h3>
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
|
||||||
|
<form action="/" class="form-horizontal bordered-row">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Select Website" %} </label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select ng-change="fetchDetails()" ng-model="websiteToBeBacked" class="form-control">
|
||||||
|
{% for items in websiteList %}
|
||||||
|
<option>{{ items }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="destination" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Destination" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select ng-change="destinationSelection()" ng-model="backupDestinations" class="form-control">
|
||||||
|
<option>{% trans "Local" %}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="destination" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Backup Content" %}</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input ng-model="websiteData" type="checkbox" value="">
|
||||||
|
Data
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input ng-model="websiteEmails" type="checkbox" value="">
|
||||||
|
Emails
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input ng-model="websiteSSLs" type="checkbox" value="">
|
||||||
|
SSL Certificates
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!---- if Back up is running ----->
|
||||||
|
|
||||||
|
<div ng-hide="runningBackup" class="form-group">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>{% trans "File Name" %}</th>
|
||||||
|
<th>{% trans "Status" %} <img ng-hide="backupLoadingBottom" src="{% static 'images/loading.gif' %}"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{% trans "Running" %}</td>
|
||||||
|
<td>{$ fileName $}</td>
|
||||||
|
<td style="color: red"><strong>{$ status $}</strong></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!---- if Back up is running------>
|
||||||
|
|
||||||
|
<div ng-hide="backupButton" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<button type="button" ng-click="createBackup()" class="btn btn-primary btn-lg btn-block">{% trans "Create Back up" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="cancelButton" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<button type="button" ng-click="cancelBackup()" class="btn btn-primary btn-lg btn-block">{% trans "Cancel Backup" %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!------ List of records --------------->
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "ID" %}</th>
|
||||||
|
<th>{% trans "File" %}</th>
|
||||||
|
<th>{% trans "Date" %}</th>
|
||||||
|
<th>{% trans "Size" %}</th>
|
||||||
|
<th>{% trans "Status" %}</th>
|
||||||
|
<th>{% trans "Delete" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="record in records track by $index">
|
||||||
|
<td ng-bind="record.id"></td>
|
||||||
|
<td ng-bind="record.file"></td>
|
||||||
|
<td ng-bind="record.date"></td>
|
||||||
|
<td ng-bind="record.size"></td>
|
||||||
|
<td ng-bind="record.status"></td>
|
||||||
|
<a href=""><td ng-click="deleteBackup(record.id)"><img src="{% static 'images/delete.png' %}"></td></a>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!------ List of records --------------->
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div id="websiteDeleteFailure" class="alert alert-danger">
|
||||||
|
<p>{% trans "Cannot delete website, Error message: " %}{$ errorMessage $}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="websiteDeleteSuccess" class="alert alert-success">
|
||||||
|
<p>Website <strong>{$ deletedWebsite $}</strong> {% trans "Successfully Deleted" %}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
186
IncBackups/templates/IncBackups/incrementalDestinations.html
Executable file
186
IncBackups/templates/IncBackups/incrementalDestinations.html
Executable file
@@ -0,0 +1,186 @@
|
|||||||
|
{% extends "baseTemplate/index.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Set up Back up Destinations" %}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
|
||||||
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
|
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div id="page-title">
|
||||||
|
<h2>{% trans "Set up Incremental Back up Destinations" %} - <a target="_blank"
|
||||||
|
href="http://go.cyberpanel.net/remote-backup"
|
||||||
|
style="height: 23px;line-height: 21px;"
|
||||||
|
class="btn btn-border btn-alt border-red btn-link font-red"
|
||||||
|
title=""><span>{% trans "Remote Backups" %}</span></a>
|
||||||
|
</h2>
|
||||||
|
<p>{% trans "On this page you can set up your Back up destinations. (SFTP and AWS)" %}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-controller="incrementalDestinations" class="panel">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h3 class="title-hero">
|
||||||
|
{% trans "Set up Back up Destinations." %} <img ng-hide="cyberpanelLoading"
|
||||||
|
src="{% static 'images/loading.gif' %}">
|
||||||
|
</h3>
|
||||||
|
<div class="example-box-wrapper">
|
||||||
|
|
||||||
|
|
||||||
|
<form action="/" class="form-horizontal bordered-row">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Select Type" %} </label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select ng-change="fetchDetails()" ng-model="destinationType" class="form-control">
|
||||||
|
<option>SFTP</option>
|
||||||
|
<option>AWS</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--- SFTP --->
|
||||||
|
|
||||||
|
<div ng-hide="sftpHide" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "IP Address" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input type="text" class="form-control" ng-model="IPAddress" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="sftpHide" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Password" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input placeholder="" type="password" class="form-control" ng-model="password" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="sftpHide" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Port" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input placeholder="{% trans "Backup server SSH Port, leave empty for 22." %}"
|
||||||
|
type="text" class="form-control" ng-model="backupSSHPort" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="sftpHide" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<button type="button" ng-click="addDestination('SFTP')"
|
||||||
|
class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--- SFTP --->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!------ List of Destinations --------------->
|
||||||
|
|
||||||
|
<div ng-hide="sftpHide" class="form-group">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "IP" %}</th>
|
||||||
|
<th>{% trans "Port" %}</th>
|
||||||
|
<th>{% trans "Delete" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="record in records track by $index">
|
||||||
|
<td ng-bind="record.ip"></td>
|
||||||
|
<td ng-bind="record.port"></td>
|
||||||
|
<td ng-click="removeDestination('SFTP',record.ip)"><img src="{% static 'images/delete.png' %}">
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!------ List of records --------------->
|
||||||
|
|
||||||
|
|
||||||
|
<!--- SFTP End --->
|
||||||
|
|
||||||
|
<!--- AWS Start --->
|
||||||
|
|
||||||
|
<div ng-hide="awsHide" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "AWS_ACCESS_KEY_ID" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input type="text" class="form-control" ng-model="AWS_ACCESS_KEY_ID" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="awsHide" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "AWS_SECRET_ACCESS_KEY" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input placeholder="" type="password" class="form-control" ng-model="AWS_SECRET_ACCESS_KEY" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ng-hide="awsHide" class="form-group">
|
||||||
|
<label class="col-sm-3 control-label"></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<button type="button" ng-click="addDestination('AWS')"
|
||||||
|
class="btn btn-primary btn-lg btn-block">{% trans "Add Destination" %}</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--- SFTP --->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!------ List of Destinations --------------->
|
||||||
|
|
||||||
|
<div ng-hide="awsHide" class="form-group">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "AWS_ACCESS_KEY_ID" %}</th>
|
||||||
|
<th>{% trans "Delete" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="record in records track by $index">
|
||||||
|
<td ng-bind="record.AWS_ACCESS_KEY_ID"></td>
|
||||||
|
<td ng-click="removeDestination('AWS', record.AWS_ACCESS_KEY_ID)"><img src="{% static 'images/delete.png' %}">
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!------ List of records --------------->
|
||||||
|
|
||||||
|
|
||||||
|
<!--- AWS End --->
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
6
IncBackups/tests.py
Normal file
6
IncBackups/tests.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
11
IncBackups/urls.py
Normal file
11
IncBackups/urls.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from django.conf.urls import url
|
||||||
|
import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^createBackup$', views.createBackup, name='createBackupInc'),
|
||||||
|
url(r'^backupDestinations$', views.backupDestinations, name='backupDestinationsInc'),
|
||||||
|
url(r'^addDestination$', views.addDestination, name='addDestinationInc'),
|
||||||
|
url(r'^populateCurrentRecords$', views.populateCurrentRecords, name='populateCurrentRecordsInc'),
|
||||||
|
url(r'^removeDestination$', views.removeDestination, name='removeDestinationInc'),
|
||||||
|
|
||||||
|
]
|
||||||
245
IncBackups/views.py
Normal file
245
IncBackups/views.py
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.shortcuts import render
|
||||||
|
from plogical.acl import ACLManager
|
||||||
|
from django.shortcuts import HttpResponse
|
||||||
|
from plogical.processUtilities import ProcessUtilities
|
||||||
|
from plogical.virtualHostUtilities import virtualHostUtilities
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
def defRenderer(request, templateName, args):
|
||||||
|
return render(request, templateName, args)
|
||||||
|
|
||||||
|
def createBackup(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'createBackup') == 0:
|
||||||
|
return ACLManager.loadError()
|
||||||
|
|
||||||
|
websitesName = ACLManager.findAllSites(currentACL, userID)
|
||||||
|
return defRenderer(request, 'IncBackups/createBackup.html', {'websiteList': websitesName})
|
||||||
|
except BaseException, msg:
|
||||||
|
return HttpResponse(str(msg))
|
||||||
|
|
||||||
|
def backupDestinations(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||||
|
return ACLManager.loadError()
|
||||||
|
|
||||||
|
return defRenderer(request, 'IncBackups/incrementalDestinations.html', {})
|
||||||
|
except BaseException, msg:
|
||||||
|
return HttpResponse(str(msg))
|
||||||
|
|
||||||
|
def addDestination(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||||
|
return ACLManager.loadErrorJson('destStatus', 0)
|
||||||
|
|
||||||
|
data = json.loads(request.body)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if data['type'] == 'SFTP':
|
||||||
|
|
||||||
|
ipAddress = data['IPAddress']
|
||||||
|
password = data['password']
|
||||||
|
|
||||||
|
ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress)
|
||||||
|
|
||||||
|
try:
|
||||||
|
port = data['backupSSHPort']
|
||||||
|
except:
|
||||||
|
port = "22"
|
||||||
|
|
||||||
|
if os.path.exists(ipFile):
|
||||||
|
final_dic = {'status': 0, 'error_message': 'This destination already exists.'}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.mkdir('/home/cyberpanel/sftp')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
execPath = "/usr/local/CyberCP/bin/python2 " + virtualHostUtilities.cyberPanel + "/plogical/backupUtilities.py"
|
||||||
|
execPath = execPath + " submitDestinationCreation --ipAddress " + ipAddress + " --password " \
|
||||||
|
+ password + " --port " + port
|
||||||
|
|
||||||
|
output = ProcessUtilities.outputExecutioner(execPath)
|
||||||
|
|
||||||
|
if output.find('1,') > -1:
|
||||||
|
|
||||||
|
content = '%s\n%s' % (ipAddress, port)
|
||||||
|
writeToFile = open(ipFile, 'w')
|
||||||
|
writeToFile.write(content)
|
||||||
|
writeToFile.close()
|
||||||
|
|
||||||
|
command = 'cat /root/.ssh/config'
|
||||||
|
currentConfig = ProcessUtilities.outputExecutioner(command)
|
||||||
|
|
||||||
|
tmpFile = '/home/cyberpanel/sshconfig'
|
||||||
|
|
||||||
|
writeToFile = open(tmpFile, 'w')
|
||||||
|
writeToFile.write(currentConfig)
|
||||||
|
|
||||||
|
content = """Host %s
|
||||||
|
IdentityFile ~/.ssh/cyberpanel
|
||||||
|
Port %s
|
||||||
|
""" % (ipAddress, port)
|
||||||
|
writeToFile.write(content)
|
||||||
|
writeToFile.close()
|
||||||
|
|
||||||
|
|
||||||
|
command = 'mv %s /root/.ssh/config' % (tmpFile)
|
||||||
|
ProcessUtilities.executioner(command)
|
||||||
|
|
||||||
|
command = 'chown root:root /root/.ssh/config'
|
||||||
|
ProcessUtilities.executioner(command)
|
||||||
|
|
||||||
|
final_dic = {'status': 1, 'error_message': 'None'}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
final_dic = {'status': 0, 'error_message': output}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
else:
|
||||||
|
aws = '/home/cyberpanel/aws'
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.mkdir(aws)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
AWS_ACCESS_KEY_ID = data['AWS_ACCESS_KEY_ID']
|
||||||
|
AWS_SECRET_ACCESS_KEY = data['AWS_SECRET_ACCESS_KEY']
|
||||||
|
|
||||||
|
awsFile = '/home/cyberpanel/aws/%s' % (AWS_ACCESS_KEY_ID)
|
||||||
|
|
||||||
|
writeToFile = open(awsFile, 'w')
|
||||||
|
writeToFile.write(AWS_SECRET_ACCESS_KEY)
|
||||||
|
writeToFile.close()
|
||||||
|
|
||||||
|
final_dic = {'status': 1}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
final_dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
def populateCurrentRecords(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||||
|
return ACLManager.loadErrorJson('fetchStatus', 0)
|
||||||
|
|
||||||
|
data = json.loads(request.body)
|
||||||
|
|
||||||
|
if data['type'] == 'SFTP':
|
||||||
|
|
||||||
|
path = '/home/cyberpanel/sftp'
|
||||||
|
|
||||||
|
if os.path.exists(path):
|
||||||
|
|
||||||
|
json_data = "["
|
||||||
|
checker = 0
|
||||||
|
|
||||||
|
for items in os.listdir(path):
|
||||||
|
fullPath = '/home/cyberpanel/sftp/%s' % (items)
|
||||||
|
|
||||||
|
data = open(fullPath, 'r').readlines()
|
||||||
|
dic = {
|
||||||
|
'ip': data[0].strip('\n'),
|
||||||
|
'port': data[1],
|
||||||
|
}
|
||||||
|
|
||||||
|
if checker == 0:
|
||||||
|
json_data = json_data + json.dumps(dic)
|
||||||
|
checker = 1
|
||||||
|
else:
|
||||||
|
json_data = json_data + ',' + json.dumps(dic)
|
||||||
|
else:
|
||||||
|
final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''})
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
else:
|
||||||
|
path = '/home/cyberpanel/aws'
|
||||||
|
|
||||||
|
if os.path.exists(path):
|
||||||
|
|
||||||
|
json_data = "["
|
||||||
|
checker = 0
|
||||||
|
|
||||||
|
for items in os.listdir(path):
|
||||||
|
dic = {
|
||||||
|
'AWS_ACCESS_KEY_ID': items
|
||||||
|
}
|
||||||
|
|
||||||
|
if checker == 0:
|
||||||
|
json_data = json_data + json.dumps(dic)
|
||||||
|
checker = 1
|
||||||
|
else:
|
||||||
|
json_data = json_data + ',' + json.dumps(dic)
|
||||||
|
else:
|
||||||
|
final_json = json.dumps({'status': 1, 'error_message': "None", "data": ''})
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
json_data = json_data + ']'
|
||||||
|
final_json = json.dumps({'status': 1, 'error_message': "None", "data": json_data})
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
final_dic = {'status': 0, 'error_message': str(msg)}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
def removeDestination(request):
|
||||||
|
try:
|
||||||
|
userID = request.session['userID']
|
||||||
|
currentACL = ACLManager.loadedACL(userID)
|
||||||
|
|
||||||
|
if ACLManager.currentContextPermission(currentACL, 'addDeleteDestinations') == 0:
|
||||||
|
return ACLManager.loadErrorJson('destStatus', 0)
|
||||||
|
|
||||||
|
data = json.loads(request.body)
|
||||||
|
|
||||||
|
ipAddress = data['IPAddress']
|
||||||
|
|
||||||
|
if data['type'] == 'SFTP':
|
||||||
|
ipFile = '/home/cyberpanel/sftp/%s' % (ipAddress)
|
||||||
|
else:
|
||||||
|
ipFile = '/home/cyberpanel/aws/%s' % (ipAddress)
|
||||||
|
|
||||||
|
|
||||||
|
os.remove(ipFile)
|
||||||
|
|
||||||
|
final_dic = {'status': 1, 'error_message': 'None'}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
|
|
||||||
|
except BaseException, msg:
|
||||||
|
final_dic = {'destStatus': 0, 'error_message': str(msg)}
|
||||||
|
final_json = json.dumps(final_dic)
|
||||||
|
return HttpResponse(final_json)
|
||||||
@@ -752,6 +752,7 @@ class backupUtilities:
|
|||||||
expectation.append("password:")
|
expectation.append("password:")
|
||||||
expectation.append("Password:")
|
expectation.append("Password:")
|
||||||
expectation.append("Permission denied")
|
expectation.append("Permission denied")
|
||||||
|
expectation.append("100%")
|
||||||
|
|
||||||
command = "scp -o StrictHostKeyChecking=no -P "+ port +" /root/.ssh/cyberpanel.pub root@" + IPAddress + ":/root/.ssh/authorized_keys"
|
command = "scp -o StrictHostKeyChecking=no -P "+ port +" /root/.ssh/cyberpanel.pub root@" + IPAddress + ":/root/.ssh/authorized_keys"
|
||||||
setupKeys = pexpect.spawn(command, timeout=3)
|
setupKeys = pexpect.spawn(command, timeout=3)
|
||||||
@@ -770,6 +771,8 @@ class backupUtilities:
|
|||||||
setupKeys.wait()
|
setupKeys.wait()
|
||||||
elif index == 2:
|
elif index == 2:
|
||||||
return [0, 'Please enable password authentication on your remote server.']
|
return [0, 'Please enable password authentication on your remote server.']
|
||||||
|
elif index == 3:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
raise BaseException
|
raise BaseException
|
||||||
|
|
||||||
@@ -802,6 +805,7 @@ class backupUtilities:
|
|||||||
expectation.append("password:")
|
expectation.append("password:")
|
||||||
expectation.append("Password:")
|
expectation.append("Password:")
|
||||||
expectation.append("Permission denied")
|
expectation.append("Permission denied")
|
||||||
|
expectation.append("File exists")
|
||||||
|
|
||||||
command = "ssh -o StrictHostKeyChecking=no -p "+ port +" root@"+IPAddress+' "mkdir /root/.ssh || rm -f /root/.ssh/temp && rm -f /root/.ssh/authorized_temp && cp /root/.ssh/authorized_keys /root/.ssh/temp"'
|
command = "ssh -o StrictHostKeyChecking=no -p "+ port +" root@"+IPAddress+' "mkdir /root/.ssh || rm -f /root/.ssh/temp && rm -f /root/.ssh/authorized_temp && cp /root/.ssh/authorized_keys /root/.ssh/temp"'
|
||||||
setupKeys = pexpect.spawn(command, timeout=3)
|
setupKeys = pexpect.spawn(command, timeout=3)
|
||||||
@@ -816,6 +820,8 @@ class backupUtilities:
|
|||||||
setupKeys.sendline(password)
|
setupKeys.sendline(password)
|
||||||
elif index == 2:
|
elif index == 2:
|
||||||
return [0, 'Please enable password authentication on your remote server.']
|
return [0, 'Please enable password authentication on your remote server.']
|
||||||
|
elif index == 3:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
raise BaseException
|
raise BaseException
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user