Skip to content

Commit d3e1976

Browse files
author
Daan Hoogland
committed
Merge release branch 4.22 to main
* 4.22: Fixes issue with loading Capacity dashboard when mulitple backup providers configured (#12550)
2 parents 408e8c0 + 7324ef4 commit d3e1976

File tree

4 files changed

+63
-6
lines changed

4 files changed

+63
-6
lines changed

api/src/main/java/org/apache/cloudstack/backup/BackupManager.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.cloudstack.api.command.user.backup.ListBackupsCmd;
3333
import org.apache.cloudstack.api.response.BackupResponse;
3434
import org.apache.cloudstack.framework.config.ConfigKey;
35+
import org.apache.cloudstack.framework.config.ValidatedConfigKey;
3536
import org.apache.cloudstack.framework.config.Configurable;
3637

3738
import com.cloud.exception.ResourceUnavailableException;
@@ -53,10 +54,11 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
5354
"false",
5455
"Is backup and recovery framework enabled.", false, ConfigKey.Scope.Zone);
5556

56-
ConfigKey<String> BackupProviderPlugin = new ConfigKey<>("Advanced", String.class,
57+
ConfigKey<String> BackupProviderPlugin = new ValidatedConfigKey<>("Advanced", String.class,
5758
"backup.framework.provider.plugin",
5859
"dummy",
59-
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker and nas", true, ConfigKey.Scope.Zone, BackupFrameworkEnabled.key());
60+
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker and nas",
61+
true, ConfigKey.Scope.Zone, BackupFrameworkEnabled.key(), value -> validateBackupProviderConfig((String)value));
6062

6163
ConfigKey<Long> BackupSyncPollingInterval = new ConfigKey<>("Advanced", Long.class,
6264
"backup.framework.sync.interval",
@@ -249,4 +251,14 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
249251
Capacity getBackupStorageUsedStats(Long zoneId);
250252

251253
void checkAndRemoveBackupOfferingBeforeExpunge(VirtualMachine vm);
254+
255+
static void validateBackupProviderConfig(String value) {
256+
if (value != null && (value.contains(",") || value.trim().contains(" "))) {
257+
throw new IllegalArgumentException("Multiple backup provider plugins are not supported. Please provide a single plugin value.");
258+
}
259+
List<String> validPlugins = List.of("dummy", "veeam", "networker", "nas");
260+
if (value != null && !validPlugins.contains(value)) {
261+
throw new IllegalArgumentException("Invalid backup provider plugin: " + value + ". Valid plugin values are: " + String.join(", ", validPlugins));
262+
}
263+
}
252264
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.framework.config;
18+
19+
import java.util.function.Consumer;
20+
21+
public class ValidatedConfigKey<T> extends ConfigKey<T> {
22+
private final Consumer<T> validator;
23+
24+
public ValidatedConfigKey(String category, Class<T> type, String name, String defaultValue, String description, boolean dynamic, Scope scope, String parent, Consumer<T> validator) {
25+
super(category, type, name, defaultValue, description, dynamic, scope, parent);
26+
this.validator = validator;
27+
}
28+
29+
public Consumer<T> getValidator() {
30+
return validator;
31+
}
32+
33+
public void validateValue(String value) {
34+
if (validator != null) {
35+
validator.accept((T) value);
36+
}
37+
}
38+
}

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
import org.apache.cloudstack.framework.config.ConfigDepot;
108108
import org.apache.cloudstack.framework.config.ConfigKey;
109109
import org.apache.cloudstack.framework.config.Configurable;
110+
import org.apache.cloudstack.framework.config.ValidatedConfigKey;
110111
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
111112
import org.apache.cloudstack.framework.config.dao.ConfigurationGroupDao;
112113
import org.apache.cloudstack.framework.config.dao.ConfigurationSubGroupDao;
@@ -764,6 +765,12 @@ public String updateConfiguration(final long userId, final String name, final St
764765
throw new InvalidParameterValueException(validationMsg);
765766
}
766767

768+
ConfigKey<?> configKey = _configDepot.get(name);
769+
if (configKey instanceof ValidatedConfigKey) {
770+
ValidatedConfigKey<?> validatedConfigKey = (ValidatedConfigKey<?>) configKey;
771+
validatedConfigKey.validateValue(value);
772+
}
773+
767774
// If scope of the parameter is given then it needs to be updated in the
768775
// corresponding details table,
769776
// if scope is mentioned as global or not mentioned then it is normal

server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,10 +1728,10 @@ public BackupProvider getBackupProvider(final String name) {
17281728
if (StringUtils.isEmpty(name)) {
17291729
throw new CloudRuntimeException("Invalid backup provider name provided");
17301730
}
1731-
if (!backupProvidersMap.containsKey(name)) {
1732-
throw new CloudRuntimeException("Failed to find backup provider by the name: " + name);
1733-
}
1734-
return backupProvidersMap.get(name);
1731+
if (!backupProvidersMap.containsKey(name)) {
1732+
throw new CloudRuntimeException("Failed to find backup provider by the name: " + name);
1733+
}
1734+
return backupProvidersMap.get(name);
17351735
}
17361736

17371737
@Override

0 commit comments

Comments
 (0)