From 0504e0423aa52cac25222973c0c043705fc0d087 Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Wed, 25 Sep 2024 12:21:42 +0200 Subject: [PATCH] backups: add hetzner object storage --- CHANGES | 3 +++ dashboard/src/js/client.js | 5 +++++ dashboard/src/js/restore.js | 8 ++++++-- dashboard/src/restore.html | 5 +++++ dashboard/src/views/app.html | 5 +++++ dashboard/src/views/app.js | 8 ++++++-- dashboard/src/views/backups.html | 5 +++++ dashboard/src/views/backups.js | 8 ++++++-- src/storage.js | 1 + 9 files changed, 42 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 0774a6dd7..a0510fc1d 100644 --- a/CHANGES +++ b/CHANGES @@ -2851,3 +2851,6 @@ [8.0.6] * Fix AdGuard resolving dashboard to docker bridge IP +[8.1.0] +* backups: add hetzner object storage + diff --git a/dashboard/src/js/client.js b/dashboard/src/js/client.js index 20bd685a8..3d07997ab 100644 --- a/dashboard/src/js/client.js +++ b/dashboard/src/js/client.js @@ -167,6 +167,10 @@ const REGIONS_WASABI = [ { name: 'Virginia (US East 2)', value: 'https://s3.us-east-2.wasabisys.com' } ]; +const REGIONS_HETZNER = [ + { name: 'Falkenstein (FSN1)', value: 'https://fsn1.your-objectstorage.com' }, +]; + // https://docs.digitalocean.com/products/platform/availability-matrix/ const REGIONS_DIGITALOCEAN = [ { name: 'AMS3', value: 'https://ams3.digitaloceanspaces.com' }, @@ -292,6 +296,7 @@ const STORAGE_PROVIDERS = [ { name: 'Filesystem', value: 'filesystem' }, { name: 'Filesystem (Mountpoint)', value: 'mountpoint' }, // legacy { name: 'Google Cloud Storage', value: 'gcs' }, + { name: 'Hetzner Object Storage', value: 'hetzner-objectstorage' }, { name: 'IDrive e2', value: 'idrive-e2' }, { name: 'IONOS (Profitbricks)', value: 'ionos-objectstorage' }, { name: 'Linode Object Storage', value: 'linode-objectstorage' }, diff --git a/dashboard/src/js/restore.js b/dashboard/src/js/restore.js index 2ea6c30a1..5984f9768 100644 --- a/dashboard/src/js/restore.js +++ b/dashboard/src/js/restore.js @@ -1,7 +1,7 @@ 'use strict'; /* global $, angular, SECRET_PLACEHOLDER, STORAGE_PROVIDERS, BACKUP_FORMATS, window, FileReader, document, redirectIfNeeded */ -/* global REGIONS_S3, REGIONS_WASABI, REGIONS_DIGITALOCEAN, REGIONS_EXOSCALE, REGIONS_SCALEWAY, REGIONS_LINODE, REGIONS_OVH, REGIONS_IONOS, REGIONS_UPCLOUD, REGIONS_VULTR, REGIONS_CONTABO */ +/* global REGIONS_S3, REGIONS_WASABI, REGIONS_DIGITALOCEAN, REGIONS_EXOSCALE, REGIONS_SCALEWAY, REGIONS_LINODE, REGIONS_OVH, REGIONS_IONOS, REGIONS_UPCLOUD, REGIONS_VULTR, REGIONS_CONTABO, REGIONS_HETZNER */ // create main application module var app = angular.module('Application', ['pascalprecht.translate', 'ngCookies', 'angular-md5', 'ui-notification', 'ui.bootstrap']); @@ -77,6 +77,7 @@ app.controller('RestoreController', ['$scope', 'Client', function ($scope, Clien $scope.s3Regions = REGIONS_S3; $scope.wasabiRegions = REGIONS_WASABI; $scope.doSpacesRegions = REGIONS_DIGITALOCEAN; + $scope.hetznerRegions = REGIONS_HETZNER; $scope.exoscaleSosRegions = REGIONS_EXOSCALE; $scope.scalewayRegions = REGIONS_SCALEWAY; $scope.linodeRegions = REGIONS_LINODE; @@ -92,7 +93,7 @@ app.controller('RestoreController', ['$scope', 'Client', function ($scope, Clien $scope.s3like = function (provider) { return provider === 's3' || provider === 'minio' || provider === 's3-v4-compat' || provider === 'exoscale-sos' - || provider === 'digitalocean-spaces' || provider === 'wasabi' || provider === 'scaleway-objectstorage' + || provider === 'digitalocean-spaces' || provider === 'wasabi' || provider === 'scaleway-objectstorage' || provider === 'hetzner-objectstorage' || provider === 'linode-objectstorage' || provider === 'ovh-objectstorage' || provider === 'backblaze-b2' || provider === 'cloudflare-r2' || provider === 'ionos-objectstorage' || provider === 'vultr-objectstorage' || provider === 'upcloud-objectstorage' || provider === 'idrive-e2' || provider === 'contabo-objectstorage'; @@ -162,6 +163,9 @@ app.controller('RestoreController', ['$scope', 'Client', function ($scope, Clien backupConfig.signatureVersion = 'v4'; } else if (backupConfig.provider === 'digitalocean-spaces') { backupConfig.region = 'us-east-1'; + } else if (backupConfig.provider === 'hetzner-objectstorage') { + backupConfig.region = 'us-east-1'; + backupConfig.signatureVersion = 'v4'; } } else if (backupConfig.provider === 'gcs') { backupConfig.bucket = $scope.bucket; diff --git a/dashboard/src/restore.html b/dashboard/src/restore.html index c4c367a3c..45413bfed 100644 --- a/dashboard/src/restore.html +++ b/dashboard/src/restore.html @@ -208,6 +208,11 @@ +
+ + +
+
diff --git a/dashboard/src/views/app.html b/dashboard/src/views/app.html index a16223bec..7597414e3 100644 --- a/dashboard/src/views/app.html +++ b/dashboard/src/views/app.html @@ -421,6 +421,11 @@
+
+ + +
+
diff --git a/dashboard/src/views/app.js b/dashboard/src/views/app.js index 142c1d3a9..43e4c4685 100644 --- a/dashboard/src/views/app.js +++ b/dashboard/src/views/app.js @@ -10,7 +10,7 @@ /* global Clipboard */ /* global SECRET_PLACEHOLDER */ /* global APP_TYPES, STORAGE_PROVIDERS, BACKUP_FORMATS */ -/* global REGIONS_S3, REGIONS_WASABI, REGIONS_DIGITALOCEAN, REGIONS_EXOSCALE, REGIONS_SCALEWAY, REGIONS_LINODE, REGIONS_OVH, REGIONS_IONOS, REGIONS_UPCLOUD, REGIONS_VULTR */ +/* global REGIONS_S3, REGIONS_WASABI, REGIONS_DIGITALOCEAN, REGIONS_EXOSCALE, REGIONS_SCALEWAY, REGIONS_LINODE, REGIONS_OVH, REGIONS_IONOS, REGIONS_UPCLOUD, REGIONS_VULTR, REGIONS_HETZNER */ /* global onAppClick */ angular.module('Application').controller('AppController', ['$scope', '$location', '$translate', '$timeout', '$interval', '$route', '$routeParams', 'Client', function ($scope, $location, $translate, $timeout, $interval, $route, $routeParams, Client) { @@ -25,6 +25,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location' $scope.upcloudRegions = REGIONS_UPCLOUD; $scope.vultrRegions = REGIONS_VULTR; $scope.contaboRegions = REGIONS_VULTR; + $scope.hetznerRegions = REGIONS_HETZNER; $scope.storageProviders = STORAGE_PROVIDERS; @@ -1425,7 +1426,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location' $scope.s3like = function (provider) { return provider === 's3' || provider === 'minio' || provider === 's3-v4-compat' - || provider === 'exoscale-sos' || provider === 'digitalocean-spaces' + || provider === 'exoscale-sos' || provider === 'digitalocean-spaces' || provider === 'hetzner-objectstorage' || provider === 'scaleway-objectstorage' || provider === 'wasabi' || provider === 'backblaze-b2' || provider === 'cloudflare-r2' || provider === 'linode-objectstorage' || provider === 'ovh-objectstorage' || provider === 'ionos-objectstorage' || provider === 'vultr-objectstorage' || provider === 'upcloud-objectstorage' || provider === 'idrive-e2' @@ -1547,6 +1548,9 @@ angular.module('Application').controller('AppController', ['$scope', '$location' backupConfig.signatureVersion = 'v4'; } else if (backupConfig.provider === 'digitalocean-spaces') { backupConfig.region = 'us-east-1'; + } else if (backupConfig.provider === 'hetzner-objectstorage') { + backupConfig.region = 'us-east-1'; + backupConfig.signatureVersion = 'v4'; } } else if (backupConfig.provider === 'gcs') { backupConfig.bucket = $scope.importBackup.bucket; diff --git a/dashboard/src/views/backups.html b/dashboard/src/views/backups.html index b6a9ac942..90d711809 100644 --- a/dashboard/src/views/backups.html +++ b/dashboard/src/views/backups.html @@ -302,6 +302,11 @@
+
+ + +
+
diff --git a/dashboard/src/views/backups.js b/dashboard/src/views/backups.js index 189601167..ba6cfcfd3 100644 --- a/dashboard/src/views/backups.js +++ b/dashboard/src/views/backups.js @@ -1,7 +1,7 @@ 'use strict'; /* global $, angular, TASK_TYPES, SECRET_PLACEHOLDER, STORAGE_PROVIDERS, BACKUP_FORMATS, APP_TYPES */ -/* global REGIONS_S3, REGIONS_WASABI, REGIONS_DIGITALOCEAN, REGIONS_EXOSCALE, REGIONS_SCALEWAY, REGIONS_LINODE, REGIONS_OVH, REGIONS_IONOS, REGIONS_UPCLOUD, REGIONS_VULTR , REGIONS_CONTABO */ +/* global REGIONS_S3, REGIONS_WASABI, REGIONS_DIGITALOCEAN, REGIONS_EXOSCALE, REGIONS_SCALEWAY, REGIONS_LINODE, REGIONS_OVH, REGIONS_IONOS, REGIONS_UPCLOUD, REGIONS_VULTR , REGIONS_CONTABO, REGIONS_HETZNER */ /* global document, window, FileReader */ angular.module('Application').controller('BackupsController', ['$scope', '$location', '$rootScope', '$timeout', 'Client', function ($scope, $location, $rootScope, $timeout, Client) { @@ -34,6 +34,7 @@ angular.module('Application').controller('BackupsController', ['$scope', '$locat $scope.upcloudRegions = REGIONS_UPCLOUD; $scope.vultrRegions = REGIONS_VULTR; $scope.contaboRegions = REGIONS_CONTABO; + $scope.hetznerRegions = REGIONS_HETZNER; $scope.storageProviders = STORAGE_PROVIDERS.concat([ { name: 'No-op (Only for testing)', value: 'noop' } @@ -270,7 +271,7 @@ angular.module('Application').controller('BackupsController', ['$scope', '$locat $scope.s3like = function (provider) { return provider === 's3' || provider === 'minio' || provider === 's3-v4-compat' - || provider === 'exoscale-sos' || provider === 'digitalocean-spaces' + || provider === 'exoscale-sos' || provider === 'digitalocean-spaces' || provider === 'hetzner-objectstorage' || provider === 'scaleway-objectstorage' || provider === 'wasabi' || provider === 'backblaze-b2' || provider === 'cloudflare-r2' || provider === 'linode-objectstorage' || provider === 'ovh-objectstorage' || provider === 'ionos-objectstorage' || provider === 'vultr-objectstorage' || provider === 'upcloud-objectstorage' || provider === 'idrive-e2' @@ -653,6 +654,9 @@ angular.module('Application').controller('BackupsController', ['$scope', '$locat backupConfig.signatureVersion = 'v4'; } else if (backupConfig.provider === 'digitalocean-spaces') { backupConfig.region = 'us-east-1'; + } else if (backupConfig.provider === 'hetzner-objectstorage') { + backupConfig.region = 'us-east-1'; + backupConfig.signatureVersion = 'v4'; } backupConfig.limits.uploadPartSize = parseInt($scope.configureBackup.uploadPartSize); diff --git a/src/storage.js b/src/storage.js index 0dc155239..6c0a80351 100644 --- a/src/storage.js +++ b/src/storage.js @@ -31,6 +31,7 @@ function api(provider) { case 'vultr-objectstorage': return require('./storage/s3.js'); case 'upcloud-objectstorage': return require('./storage/s3.js'); case 'contabo-objectstorage': return require('./storage/s3.js'); + case 'hetzner-objectstorage': return require('./storage/s3.js'); case 'noop': return require('./storage/noop.js'); default: return null; }