Adding Google Cloud Storage support

This commit is contained in:
Aleksandr Bogdanov
2017-09-17 17:51:00 +02:00
parent 241dbf160e
commit 051d04890b
6 changed files with 431 additions and 4 deletions
+13 -3
View File
@@ -146,7 +146,7 @@
</p>
</div>
<!-- S3/Minio/SOS -->
<!-- S3/Minio/SOS/GCS -->
<div class="form-group" ng-class="{ 'has-error': configureBackup.error.endpoint }" ng-show="configureBackup.provider === 'minio' || configureBackup.provider === 's3-v4-compat'">
<label class="control-label" for="inputConfigureBackupEndpoint">Endpoint</label>
<input type="text" class="form-control" ng-model="configureBackup.endpoint" id="inputConfigureBackupEndpoint" name="endpoint" ng-disabled="configureBackup.busy" placeholder="URL of Minio/S3 Compatible" ng-required="configureBackup.provider === 'minio' || configureBackup.provider === 's3-v4-compat'">
@@ -160,7 +160,7 @@
</label>
</div>
<div class="form-group" ng-class="{ 'has-error': configureBackup.error.bucket }" ng-show="s3like(configureBackup.provider)">
<div class="form-group" ng-class="{ 'has-error': configureBackup.error.bucket }" ng-show="s3like(configureBackup.provider) || configureBackup.provider === 'gcs'">
<label class="control-label" for="inputConfigureBackupBucket">Bucket name</label>
<input type="text" class="form-control" ng-model="configureBackup.bucket" id="inputConfigureBackupBucket" name="bucket" ng-disabled="configureBackup.busy" ng-required="s3like(configureBackup.provider)">
</div>
@@ -185,6 +185,16 @@
<input type="text" class="form-control" ng-model="configureBackup.secretAccessKey" id="inputConfigureBackupSecretAccessKey" name="secretAccessKey" ng-disabled="configureBackup.busy" ng-required="s3like(configureBackup.provider)">
</div>
<div class="form-group" ng-class="{ 'has-error': configureBackup.error.gcsKeyInput }" ng-show="configureBackup.provider === 'gcs'">
<div class="input-group">
<input type="file" id="gcsKeyFileInput" style="display:none"/>
<input type="text" class="form-control" placeholder="Service Account Key" ng-model="configureBackup.gcsKey.keyFileName" id="gcsKeyInput" name="cert" onclick="getElementById('gcsKeyFileInput').click();" style="cursor: pointer;" ng-disabled="configureBackup.busy" required>
<span class="input-group-addon">
<i class="fa fa-upload" onclick="getElementById('gcsKeyFileInput').click();"></i>
</span>
</div>
</div>
<div class="form-group" ng-show="configureBackup.provider !== 'noop'">
<label class="control-label" for="storageFormat">Storage Format</label>
<select class="form-control" id="storageFormat" ng-change="configureBackup.key = ''" ng-model="configureBackup.format" ng-options="a.value as a.name for a in formats"></select>
@@ -349,7 +359,7 @@
</div>
<div class="col-xs-6 text-right">
<span ng-show="backupConfig.provider === 'filesystem'">{{ backupConfig.backupFolder }}</span>
<span ng-show="backupConfig.provider === 'minio' || backupConfig.provider === 'exoscale-sos' || backupConfig.provider === 's3-v4-compat' || backupConfig.provider === 'digitalocean-spaces'">{{ backupConfig.bucket + '/' + backupConfig.prefix }}</span>
<span ng-show="backupConfig.provider === 'minio' || backupConfig.provider === 'exoscale-sos' || backupConfig.provider === 's3-v4-compat' || backupConfig.provider === 'digitalocean-spaces' || backupConfig.provider === 'gcs'">{{ backupConfig.bucket + '/' + backupConfig.prefix }}</span>
<span ng-show="backupConfig.provider === 's3'">{{ backupConfig.region + ' ' + backupConfig.bucket + '/' + backupConfig.prefix }}</span>
</div>
</div>
+48
View File
@@ -42,6 +42,7 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
$scope.storageProvider = [
{ name: 'Amazon S3', value: 's3' },
{ name: 'Google Cloud Storage', value: 'gcs' },
{ name: 'DigitalOcean Spaces NYC3', value: 'digitalocean-spaces' },
{ name: 'Exoscale SOS', value: 'exoscale-sos' },
{ name: 'Filesystem', value: 'filesystem' },
@@ -313,6 +314,22 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
return provider === 's3' || provider === 'minio' || provider === 's3-v4-compat' || provider === 'exoscale-sos' || provider === 'digitalocean-spaces';
};
function readFileLocally(obj, file, fileName) {
return function (event) {
$scope.$apply(function () {
obj[file] = null;
obj[fileName] = event.target.files[0].name;
var reader = new FileReader();
reader.onload = function (result) {
if (!result.target || !result.target.result) return console.error('Unable to read local file');
obj[file] = result.target.result;
};
reader.readAsText(event.target.files[0]);
});
};
}
$scope.configureBackup = {
busy: false,
error: {},
@@ -322,6 +339,7 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
prefix: '',
accessKeyId: '',
secretAccessKey: '',
gcsKey: { keyFileName: '', content: '' },
region: '',
endpoint: '',
backupFolder: '',
@@ -334,6 +352,8 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
$scope.configureBackup.prefix = '';
$scope.configureBackup.accessKeyId = '';
$scope.configureBackup.secretAccessKey = '';
$scope.configureBackup.gcsKey.keyFileName = '';
$scope.configureBackup.gcsKey.content = '';
$scope.configureBackup.endpoint = '';
$scope.configureBackup.region = '';
$scope.configureBackup.backupFolder = '';
@@ -352,6 +372,13 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
$scope.configureBackup.region = $scope.backupConfig.region;
$scope.configureBackup.accessKeyId = $scope.backupConfig.accessKeyId;
$scope.configureBackup.secretAccessKey = $scope.backupConfig.secretAccessKey;
if ($scope.backupConfig.provider === 'gcs') {
$scope.configureBackup.gcsKey.keyFileName = $scope.backupConfig.credentials.client_email;
$scope.configureBackup.gcsKey.content = JSON.stringify({
"project_id": $scope.backupConfig.projectId,
"credentials": $scope.backupConfig.credentials
});
}
$scope.configureBackup.endpoint = $scope.backupConfig.endpoint;
$scope.configureBackup.key = $scope.backupConfig.key;
$scope.configureBackup.backupFolder = $scope.backupConfig.backupFolder;
@@ -395,6 +422,25 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
backupConfig.endpoint = 'https://nyc3.digitaloceanspaces.com';
backupConfig.region = 'us-east-1';
}
} else if (backupConfig.provider === 'gcs'){
backupConfig.bucket = $scope.configureBackup.bucket;
backupConfig.prefix = $scope.configureBackup.prefix;
try {
var serviceAccountKey = JSON.parse($scope.configureBackup.gcsKey.content);
backupConfig.projectId = serviceAccountKey.project_id;
backupConfig.credentials = {
client_email: serviceAccountKey.client_email,
private_key: serviceAccountKey.private_key
};
if (!backupConfig.projectId || !backupConfig.credentials || !backupConfig.credentials.client_email || !backupConfig.credentials.private_key) {
throw 'fields_missing';
}
} catch (e) {
$scope.configureBackup.error.generic = 'Cannot parse Google Service Account Key: ' + e.message;
$scope.configureBackup.busy = false;
return;
}
} else if (backupConfig.provider === 'filesystem') {
backupConfig.backupFolder = $scope.configureBackup.backupFolder;
}
@@ -457,6 +503,8 @@ angular.module('Application').controller('SettingsController', ['$scope', '$loca
}
};
document.getElementById('gcsKeyFileInput').onchange = readFileLocally($scope.configureBackup.gcsKey, 'content', 'keyFileName');
$scope.autoUpdate = {
busy: false,
success: false,