Skip to content

Commit c702e6f

Browse files
committed
Enable account settings to be visible under domain settings
All the account settings can't be configured under domain level settings right now. By default, if account setting is not configured then its value will be taken from global setting. Add a global setting "enable.account.settings.for.domain" so that if its enabled then all the account level settings will be visible under domain levelsettings also. If account level setting is configured then that value will be considered else it will take domain scope value. If domain scope value is not configured then it will pick it up from global setting. If domain level setting is not configured then by default the value will be taken from global setting Add another global setting "enable.domain.settings.for.child.domain" so that when its true, if a value for domain setting is not configured then its parent domain value is considered until it reaches ROOT domain. If no value is configured till ROOT domain then global setting value will be taken. Also display all the settings configured under the domain level in list domains api response
1 parent d76caa7 commit c702e6f

File tree

12 files changed

+665
-10
lines changed

12 files changed

+665
-10
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ public class ApiConstants {
132132
public static final String IP6_DNS1 = "ip6dns1";
133133
public static final String IP6_DNS2 = "ip6dns2";
134134
public static final String DOMAIN = "domain";
135+
public static final String DOMAIN_DETAILS = "domaindetails";
135136
public static final String DOMAIN_PATH = "domainpath";
136137
public static final String DOMAIN_ID = "domainid";
137138
public static final String DOMAIN__ID = "domainId";

api/src/main/java/org/apache/cloudstack/api/response/DomainResponse.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import com.cloud.domain.Domain;
2626
import com.cloud.serializer.Param;
2727

28+
import java.util.Map;
29+
2830
@EntityReference(value = Domain.class)
2931
public class DomainResponse extends BaseResponse implements ResourceLimitAndCountResponse {
3032
@SerializedName(ApiConstants.ID)
@@ -170,6 +172,10 @@ public class DomainResponse extends BaseResponse implements ResourceLimitAndCoun
170172
@SerializedName("secondarystorageavailable") @Param(description="the total secondary storage space (in GiB) available to be used for this domain", since="4.2.0")
171173
private String secondaryStorageAvailable;
172174

175+
@SerializedName(ApiConstants.DOMAIN_DETAILS)
176+
@Param(description = "details for the domain")
177+
private Map<String, String> details;
178+
173179
public String getId() {
174180
return this.id;
175181
}
@@ -421,4 +427,8 @@ public void setVmStopped(Integer vmStopped) {
421427
public void setVmRunning(Integer vmRunning) {
422428
// TODO Auto-generated method stub
423429
}
430+
431+
public void setDetails(Map<String, String> details) {
432+
this.details = details;
433+
}
424434
}

engine/schema/src/main/java/com/cloud/domain/dao/DomainDetailsDaoImpl.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import javax.inject.Inject;
24+
2325
import com.cloud.domain.DomainDetailVO;
26+
import com.cloud.domain.DomainVO;
2427
import com.cloud.utils.db.GenericDaoBase;
2528
import com.cloud.utils.db.QueryBuilder;
2629
import com.cloud.utils.db.SearchBuilder;
@@ -30,10 +33,16 @@
3033
import org.apache.cloudstack.framework.config.ConfigKey;
3134
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
3235
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
36+
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
3337

3438
public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> implements DomainDetailsDao, ScopedConfigStorage {
3539
protected final SearchBuilder<DomainDetailVO> domainSearch;
3640

41+
@Inject
42+
protected DomainDao _domainDao;
43+
@Inject
44+
private ConfigurationDao _configDao;
45+
3746
protected DomainDetailsDaoImpl() {
3847
domainSearch = createSearchBuilder();
3948
domainSearch.and("domainId", domainSearch.entity().getDomainId(), Op.EQ);
@@ -98,7 +107,24 @@ public Scope getScope() {
98107

99108
@Override
100109
public String getConfigValue(long id, ConfigKey<?> key) {
101-
DomainDetailVO vo = findDetail(id, key.key());
110+
DomainDetailVO vo = null;
111+
String enableDomainSettingsForChildDomain = _configDao.getValue("enable.domain.settings.for.child.domain");
112+
if (!Boolean.parseBoolean(enableDomainSettingsForChildDomain)) {
113+
vo = findDetail(id, key.key());
114+
return vo == null ? null : vo.getValue();
115+
}
116+
DomainVO domain = _domainDao.findById(id);
117+
// if value is not configured in domain then check its parent domain till ROOT
118+
while (domain != null) {
119+
vo = findDetail(domain.getId(), key.key());
120+
if (vo != null) {
121+
break;
122+
} else if (domain.getParent() != null) {
123+
domain = _domainDao.findById(domain.getParent());
124+
} else {
125+
break;
126+
}
127+
}
102128
return vo == null ? null : vo.getValue();
103129
}
104130
}

engine/schema/src/main/java/com/cloud/user/AccountDetailsDaoImpl.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,38 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import javax.inject.Inject;
2324

2425
import org.apache.cloudstack.framework.config.ConfigKey;
2526
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
2627
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
2728

29+
import com.cloud.domain.DomainDetailVO;
30+
import com.cloud.domain.DomainVO;
31+
import com.cloud.domain.dao.DomainDetailsDao;
32+
import com.cloud.domain.dao.DomainDao;
33+
import com.cloud.user.dao.AccountDao;
34+
2835
import com.cloud.utils.db.GenericDaoBase;
2936
import com.cloud.utils.db.QueryBuilder;
3037
import com.cloud.utils.db.SearchBuilder;
3138
import com.cloud.utils.db.SearchCriteria;
3239
import com.cloud.utils.db.SearchCriteria.Op;
3340
import com.cloud.utils.db.TransactionLegacy;
41+
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
3442

3543
public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long> implements AccountDetailsDao, ScopedConfigStorage {
3644
protected final SearchBuilder<AccountDetailVO> accountSearch;
3745

46+
@Inject
47+
protected AccountDao _accountDao;
48+
@Inject
49+
protected DomainDao _domainDao;
50+
@Inject
51+
protected DomainDetailsDao _domainDetailsDao;
52+
@Inject
53+
private ConfigurationDao _configDao;
54+
3855
protected AccountDetailsDaoImpl() {
3956
accountSearch = createSearchBuilder();
4057
accountSearch.and("accountId", accountSearch.entity().getAccountId(), Op.EQ);
@@ -99,7 +116,37 @@ public Scope getScope() {
99116

100117
@Override
101118
public String getConfigValue(long id, ConfigKey<?> key) {
119+
// check if account level setting is configured
102120
AccountDetailVO vo = findDetail(id, key.key());
103-
return vo == null ? null : vo.getValue();
121+
String value = vo == null ? null : vo.getValue();
122+
if (value != null) {
123+
return value;
124+
}
125+
126+
// if account level setting is not configured then check if
127+
// we can take value from domain
128+
String enableAccountSettingsForDomain = _configDao.getValue("enable.account.settings.for.domain");
129+
if (! Boolean.parseBoolean(enableAccountSettingsForDomain)) {
130+
return null;
131+
}
132+
133+
// check if we can traverse till ROOT domain to get the value
134+
String enableDomainSettingsForChildDomain = _configDao.getValue("enable.domain.settings.for.child.domain");
135+
if (Boolean.parseBoolean(enableDomainSettingsForChildDomain)) {
136+
AccountVO account = _accountDao.findById(id);
137+
DomainVO domain = _domainDao.findById(account.getDomainId());
138+
while (domain != null) {
139+
DomainDetailVO domainVO = _domainDetailsDao.findDetail(domain.getId(), key.key());
140+
if (domainVO != null) {
141+
value = domainVO.getValue();
142+
break;
143+
} else if (domain.getParent() != null) {
144+
domain = _domainDao.findById(domain.getParent());
145+
} else {
146+
break;
147+
}
148+
}
149+
}
150+
return value;
104151
}
105152
}

framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKey.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,19 @@ public T valueIn(Long id) {
160160
}
161161
}
162162

163+
public T valueInDomain(Long domainId) {
164+
if (domainId == null) {
165+
return value();
166+
}
167+
168+
String value = s_depot != null ? s_depot.getDomainScope(this).getConfigValue(domainId, this) : null;
169+
if (value == null) {
170+
return value();
171+
} else {
172+
return valueOf(value);
173+
}
174+
}
175+
163176
@SuppressWarnings("unchecked")
164177
protected T valueOf(String value) {
165178
Number multiplier = 1;

framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,16 @@ public ScopedConfigStorage findScopedConfigStorage(ConfigKey<?> config) {
186186
throw new CloudRuntimeException("Unable to find config storage for this scope: " + config.scope() + " for " + config.key());
187187
}
188188

189+
public ScopedConfigStorage getDomainScope(ConfigKey<?> config) {
190+
for (ScopedConfigStorage storage : _scopedStorages) {
191+
if (storage.getScope() == ConfigKey.Scope.Domain) {
192+
return storage;
193+
}
194+
}
195+
196+
throw new CloudRuntimeException("Unable to find config storage for this scope: " + ConfigKey.Scope.Domain + " for " + config.key());
197+
}
198+
189199
public List<ScopedConfigStorage> getScopedStorages() {
190200
return _scopedStorages;
191201
}

server/src/main/java/com/cloud/api/ApiDBUtils.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javax.annotation.PostConstruct;
2828
import javax.inject.Inject;
2929

30+
import com.cloud.domain.dao.DomainDetailsDao;
3031
import org.apache.cloudstack.acl.Role;
3132
import org.apache.cloudstack.acl.RoleService;
3233
import org.apache.cloudstack.affinity.AffinityGroup;
@@ -399,6 +400,7 @@ public class ApiDBUtils {
399400
static ResourceLimitService s_resourceLimitMgr;
400401
static ProjectService s_projectMgr;
401402
static ResourceManager s_resourceMgr;
403+
static DomainDetailsDao s_domainDetailsDao;
402404
static AccountDetailsDao s_accountDetailsDao;
403405
static NetworkDomainDao s_networkDomainDao;
404406
static HighAvailabilityManager s_haMgr;
@@ -585,6 +587,8 @@ public class ApiDBUtils {
585587
@Inject
586588
private ResourceManager resourceMgr;
587589
@Inject
590+
private DomainDetailsDao domainDetailsDao;
591+
@Inject
588592
private AccountDetailsDao accountDetailsDao;
589593
@Inject
590594
private NetworkDomainDao networkDomainDao;
@@ -767,6 +771,7 @@ void init() {
767771
s_resourceLimitMgr = resourceLimitMgr;
768772
s_projectMgr = projectMgr;
769773
s_resourceMgr = resourceMgr;
774+
s_domainDetailsDao = domainDetailsDao;
770775
s_accountDetailsDao = accountDetailsDao;
771776
s_networkDomainDao = networkDomainDao;
772777
s_haMgr = haMgr;
@@ -1405,6 +1410,11 @@ public static long getProjectOwnwerId(long projectId) {
14051410
return s_projectMgr.getProjectOwner(projectId).getId();
14061411
}
14071412

1413+
public static Map<String, String> getDomainDetails(long domainId) {
1414+
Map<String, String> details = s_domainDetailsDao.findDetails(domainId);
1415+
return details.isEmpty() ? null : details;
1416+
}
1417+
14081418
public static Map<String, String> getAccountDetails(long accountId) {
14091419
Map<String, String> details = s_accountDetailsDao.findDetails(accountId);
14101420
return details.isEmpty() ? null : details;

server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public DomainResponse newDomainResponse(ResponseView view, EnumSet<DomainDetails
8787
domainResponse.setProjectAvailable(projectAvail);
8888
}
8989

90+
domainResponse.setDetails(ApiDBUtils.getDomainDetails(domain.getId()));
9091
domainResponse.setObjectName("domain");
9192

9293
return domainResponse;

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
409409
"Maximum IOPS read burst duration (seconds). If '0' (zero) then does not check for maximum burst length.", true, ConfigKey.Scope.Global, null);
410410
public final static ConfigKey<Long> IOPS_MAX_WRITE_LENGTH = new ConfigKey<Long>(Long.class, "vm.disk.iops.maximum.write.length", "Advanced", "0",
411411
"Maximum IOPS write burst duration (seconds). If '0' (zero) then does not check for maximum burst length.", true, ConfigKey.Scope.Global, null);
412+
public static final ConfigKey<Boolean> EnableAccountSettingsForDomain = new ConfigKey<Boolean>(Boolean.class, "enable.account.settings.for.domain", "Advanced", "false",
413+
"Indicates whether to add account settings for domain. If true, account settings will be added to domain settings, all accounts in the domain will inherit the domain setting if account setting is not set.", true, ConfigKey.Scope.Global, null);
414+
public static final ConfigKey<Boolean> EnableDomainSettingsForChildDomain = new ConfigKey<Boolean>(Boolean.class, "enable.domain.settings.for.child.domain", "Advanced", "false",
415+
"Indicates whether the settings of parent domain should be applied for child domain. If true, the child domain will get value from parent domain if its not configured in child domain else global value is taken.",
416+
true, ConfigKey.Scope.Global, null);
412417

413418
private static final String IOPS_READ_RATE = "IOPS Read";
414419
private static final String IOPS_WRITE_RATE = "IOPS Write";
@@ -824,7 +829,9 @@ private String validateConfigurationValue(final String name, String value, final
824829

825830
final String configScope = cfg.getScope();
826831
if (scope != null) {
827-
if (!configScope.contains(scope)) {
832+
if (!configScope.contains(scope) &&
833+
!(EnableAccountSettingsForDomain.value() && configScope.contains(ConfigKey.Scope.Account.toString()) &&
834+
scope.equals(ConfigKey.Scope.Domain.toString()))) {
828835
s_logger.error("Invalid scope id provided for the parameter " + name);
829836
return "Invalid scope id provided for the parameter " + name;
830837
}
@@ -6378,6 +6385,7 @@ public String getConfigComponentName() {
63786385

63796386
@Override
63806387
public ConfigKey<?>[] getConfigKeys() {
6381-
return new ConfigKey<?>[] {SystemVMUseLocalStorage, IOPS_MAX_READ_LENGTH, IOPS_MAX_WRITE_LENGTH, BYTES_MAX_READ_LENGTH, BYTES_MAX_WRITE_LENGTH};
6388+
return new ConfigKey<?>[] {SystemVMUseLocalStorage, IOPS_MAX_READ_LENGTH, IOPS_MAX_WRITE_LENGTH, BYTES_MAX_READ_LENGTH, BYTES_MAX_WRITE_LENGTH,
6389+
EnableAccountSettingsForDomain, EnableDomainSettingsForChildDomain};
63826390
}
63836391
}

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import javax.inject.Inject;
3838
import javax.naming.ConfigurationException;
3939

40+
import com.cloud.configuration.ConfigurationManagerImpl;
4041
import org.apache.cloudstack.acl.ControlledEntity;
4142
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
4243
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@@ -1871,7 +1872,12 @@ public Pair<List<? extends Configuration>, Integer> searchForConfigurations(fina
18711872

18721873
if (scope != null && !scope.isEmpty()) {
18731874
// getting the list of parameters at requested scope
1874-
sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
1875+
if (ConfigurationManagerImpl.EnableAccountSettingsForDomain.value()
1876+
&& scope.equals(ConfigKey.Scope.Domain.toString())) {
1877+
sc.addAnd("scope", SearchCriteria.Op.IN, ConfigKey.Scope.Domain.toString(), ConfigKey.Scope.Account.toString());
1878+
} else {
1879+
sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
1880+
}
18751881
}
18761882

18771883
final Pair<List<ConfigurationVO>, Integer> result = _configDao.searchAndCount(sc, searchFilter);
@@ -1884,7 +1890,13 @@ public Pair<List<? extends Configuration>, Integer> searchForConfigurations(fina
18841890
if (configVo != null) {
18851891
final ConfigKey<?> key = _configDepot.get(param.getName());
18861892
if (key != null) {
1887-
configVo.setValue(key.valueIn(id) == null ? null : key.valueIn(id).toString());
1893+
if (scope.equals(ConfigKey.Scope.Domain.toString())) {
1894+
Object value = key.valueInDomain(id);
1895+
configVo.setValue(value == null ? null : value.toString());
1896+
} else {
1897+
Object value = key.valueIn(id);
1898+
configVo.setValue(value == null ? null : value.toString());
1899+
}
18881900
configVOList.add(configVo);
18891901
} else {
18901902
s_logger.warn("ConfigDepot could not find parameter " + param.getName() + " for scope " + scope);

0 commit comments

Comments
 (0)