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("Permission denied")
|
||||
expectation.append("100%")
|
||||
|
||||
command = "scp -o StrictHostKeyChecking=no -P "+ port +" /root/.ssh/cyberpanel.pub root@" + IPAddress + ":/root/.ssh/authorized_keys"
|
||||
setupKeys = pexpect.spawn(command, timeout=3)
|
||||
@@ -770,6 +771,8 @@ class backupUtilities:
|
||||
setupKeys.wait()
|
||||
elif index == 2:
|
||||
return [0, 'Please enable password authentication on your remote server.']
|
||||
elif index == 3:
|
||||
pass
|
||||
else:
|
||||
raise BaseException
|
||||
|
||||
@@ -802,6 +805,7 @@ class backupUtilities:
|
||||
expectation.append("password:")
|
||||
expectation.append("Password:")
|
||||
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"'
|
||||
setupKeys = pexpect.spawn(command, timeout=3)
|
||||
@@ -816,6 +820,8 @@ class backupUtilities:
|
||||
setupKeys.sendline(password)
|
||||
elif index == 2:
|
||||
return [0, 'Please enable password authentication on your remote server.']
|
||||
elif index == 3:
|
||||
pass
|
||||
else:
|
||||
raise BaseException
|
||||
|
||||
|
||||
Reference in New Issue
Block a user