Skip to content

Commit 33eb762

Browse files
committed
Allow domain admin to change domain and account settings
1 parent 4f6851f commit 33eb762

4 files changed

Lines changed: 46 additions & 4 deletions

File tree

api/src/main/java/org/apache/cloudstack/query/QueryService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ public interface QueryService {
9696
"user.vm.denied.details", "rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag",
9797
"Determines whether users can view certain VM settings. When set to empty, default value used is: rootdisksize, cpuOvercommitRatio, memoryOvercommitRatio, Message.ReservedCapacityFreed.Flag.", true);
9898

99+
static final ConfigKey<String> DomainAdminAllowListedConfigurations = new ConfigKey<String>("Advanced", String.class,
100+
"domain.admin.allowlisted.config", "", "Determines which domain and account level configurations the domain admin is able to change", true);
101+
99102
static final ConfigKey<String> UserVMReadOnlyDetails = new ConfigKey<String>("Advanced", String.class,
100103
"user.vm.readonly.details", "dataDiskController, rootDiskController",
101104
"List of read-only VM settings/details as comma separated string", true);

server/src/main/java/com/cloud/api/query/QueryManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4150,6 +4150,6 @@ public String getConfigComponentName() {
41504150

41514151
@Override
41524152
public ConfigKey<?>[] getConfigKeys() {
4153-
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, UserVMDeniedDetails, UserVMReadOnlyDetails, SortKeyAscending, AllowUserViewAllDomainAccounts};
4153+
return new ConfigKey<?>[] {AllowUserViewDestroyedVM, UserVMDeniedDetails, UserVMReadOnlyDetails, SortKeyAscending, AllowUserViewAllDomainAccounts, DomainAdminAllowListedConfigurations};
41544154
}
41554155
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import java.util.ListIterator;
3434
import java.util.Map;
3535
import java.util.Map.Entry;
36+
import java.util.stream.Collectors;
37+
import java.util.stream.Stream;
3638
import java.util.Set;
3739
import java.util.UUID;
3840

@@ -87,6 +89,7 @@
8789
import org.apache.cloudstack.framework.messagebus.MessageBus;
8890
import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
8991
import org.apache.cloudstack.framework.messagebus.PublishScope;
92+
import org.apache.cloudstack.query.QueryService;
9093
import org.apache.cloudstack.region.PortableIp;
9194
import org.apache.cloudstack.region.PortableIpDao;
9295
import org.apache.cloudstack.region.PortableIpRange;
@@ -770,6 +773,20 @@ public Configuration updateConfiguration(final UpdateCfgCmd cmd) throws InvalidP
770773
final ConfigurationVO config = _configDao.findByName(name);
771774
String catergory = null;
772775

776+
final Account caller = CallContext.current().getCallingAccount();
777+
if (_accountMgr.isDomainAdmin(caller.getId())) {
778+
if (domainId == null) {
779+
throw new PermissionDeniedException("Domain admins can change only domain level configuration");
780+
}
781+
782+
final List<String> domainAdminWhitelistConfigs = Stream.of(QueryService.DomainAdminAllowListedConfigurations.value().split(","))
783+
.map(item -> (item).trim())
784+
.collect(Collectors.toList());
785+
if (!domainAdminWhitelistConfigs.contains(name)) {
786+
throw new PermissionDeniedException("Domain admins can not change this configuration");
787+
}
788+
}
789+
773790
// FIX ME - All configuration parameters are not moved from config.java to configKey
774791
if (config == null) {
775792
if (_configDepot.get(name) == null) {
@@ -806,11 +823,14 @@ public Configuration updateConfiguration(final UpdateCfgCmd cmd) throws InvalidP
806823
paramCountCheck++;
807824
}
808825
if (accountId != null) {
826+
Account account = _accountMgr.getAccount(accountId);
827+
_accountMgr.checkAccess(caller, _domainDao.findById(account.getDomainId()));
809828
scope = ConfigKey.Scope.Account.toString();
810829
id = accountId;
811830
paramCountCheck++;
812831
}
813832
if (domainId != null) {
833+
_accountMgr.checkAccess(caller, _domainDao.findById(domainId));
814834
scope = ConfigKey.Scope.Domain.toString();
815835
id = domainId;
816836
paramCountCheck++;

server/src/main/java/com/cloud/server/ManagementServerImpl.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
import java.util.concurrent.TimeUnit;
3737
import java.util.function.Predicate;
3838

39-
4039
import java.util.stream.Collectors;
40+
import java.util.stream.Stream;
4141

4242
import javax.crypto.Mac;
4343
import javax.crypto.spec.SecretKeySpec;
@@ -1953,6 +1953,11 @@ public Pair<List<? extends Configuration>, Integer> searchForConfigurations(fina
19531953
Long id = null;
19541954
int paramCountCheck = 0;
19551955

1956+
final Account caller = CallContext.current().getCallingAccount();
1957+
if (_accountMgr.isDomainAdmin(caller.getId()) && domainId == null) {
1958+
throw new PermissionDeniedException("Domain admin can change only domain level settings");
1959+
}
1960+
19561961
if (zoneId != null) {
19571962
scope = ConfigKey.Scope.Zone.toString();
19581963
id = zoneId;
@@ -1964,11 +1969,14 @@ public Pair<List<? extends Configuration>, Integer> searchForConfigurations(fina
19641969
paramCountCheck++;
19651970
}
19661971
if (accountId != null) {
1972+
Account account = _accountMgr.getAccount(accountId);
1973+
_accountMgr.checkAccess(caller, _domainDao.findById(account.getDomainId()));
19671974
scope = ConfigKey.Scope.Account.toString();
19681975
id = accountId;
19691976
paramCountCheck++;
19701977
}
19711978
if (domainId != null) {
1979+
_accountMgr.checkAccess(caller, _domainDao.findById(domainId));
19721980
scope = ConfigKey.Scope.Domain.toString();
19731981
id = domainId;
19741982
paramCountCheck++;
@@ -2018,10 +2026,21 @@ public Pair<List<? extends Configuration>, Integer> searchForConfigurations(fina
20182026

20192027
final Pair<List<ConfigurationVO>, Integer> result = _configDao.searchAndCount(sc, searchFilter);
20202028

2029+
List<ConfigurationVO> configs = result.first();
2030+
2031+
if (_accountMgr.isDomainAdmin(caller.getId())) {
2032+
final List<String> domainAdminWhitelistConfigs = Stream.of(QueryService.DomainAdminAllowListedConfigurations.value().split(","))
2033+
.map(item -> (item).trim())
2034+
.collect(Collectors.toList());
2035+
configs = configs.stream()
2036+
.filter(item -> domainAdminWhitelistConfigs.contains(item.getName()))
2037+
.collect(Collectors.toList());
2038+
}
2039+
20212040
if (scope != null && !scope.isEmpty()) {
20222041
// Populate values corresponding the resource id
20232042
final List<ConfigurationVO> configVOList = new ArrayList<ConfigurationVO>();
2024-
for (final ConfigurationVO param : result.first()) {
2043+
for (final ConfigurationVO param : configs) {
20252044
final ConfigurationVO configVo = _configDao.findByName(param.getName());
20262045
if (configVo != null) {
20272046
final ConfigKey<?> key = _configDepot.get(param.getName());
@@ -2039,7 +2058,7 @@ public Pair<List<? extends Configuration>, Integer> searchForConfigurations(fina
20392058
return new Pair<List<? extends Configuration>, Integer>(configVOList, configVOList.size());
20402059
}
20412060

2042-
return new Pair<List<? extends Configuration>, Integer>(result.first(), result.second());
2061+
return new Pair<List<? extends Configuration>, Integer>(configs, result.second());
20432062
}
20442063

20452064
@Override

0 commit comments

Comments
 (0)