Skip to content

Commit 7abda3b

Browse files
committed
Merge remote-tracking branch 'apache/4.20'
2 parents 4cf6fc9 + ae2ffbe commit 7abda3b

File tree

24 files changed

+623
-111
lines changed

24 files changed

+623
-111
lines changed

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

+8
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
196196
@Param(description = "true network requires restart")
197197
private Boolean restartRequired;
198198

199+
@SerializedName(ApiConstants.SPECIFY_VLAN)
200+
@Param(description = "true if network supports specifying vlan, false otherwise")
201+
private Boolean specifyVlan;
202+
199203
@SerializedName(ApiConstants.SPECIFY_IP_RANGES)
200204
@Param(description = "true if network supports specifying ip ranges, false otherwise")
201205
private Boolean specifyIpRanges;
@@ -516,6 +520,10 @@ public void setRestartRequired(Boolean restartRequired) {
516520
this.restartRequired = restartRequired;
517521
}
518522

523+
public void setSpecifyVlan(Boolean specifyVlan) {
524+
this.specifyVlan = specifyVlan;
525+
}
526+
519527
public void setSpecifyIpRanges(Boolean specifyIpRanges) {
520528
this.specifyIpRanges = specifyIpRanges;
521529
}

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
import javax.persistence.Transient;
3434

3535
import org.apache.cloudstack.api.InternalIdentity;
36+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
37+
import org.apache.commons.lang3.StringUtils;
3638

3739
import com.cloud.utils.db.Encrypt;
3840
import com.cloud.utils.db.GenericDao;
39-
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
40-
import org.apache.commons.lang3.StringUtils;
4141

4242
@Entity
4343
@Table(name = "user")
@@ -131,12 +131,6 @@ public enum Setup2FAstatus {
131131
public UserAccountVO() {
132132
}
133133

134-
@Override
135-
public String toString() {
136-
return String.format("UserAccount %s.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields
137-
(this, "id", "uuid", "username", "accountName"));
138-
}
139-
140134
@Override
141135
public long getId() {
142136
return id;
@@ -379,4 +373,10 @@ public Map<String, String> getDetails() {
379373
public void setDetails(Map<String, String> details) {
380374
this.details = details;
381375
}
376+
377+
@Override
378+
public String toString() {
379+
return String.format("UserAccount %s.", ReflectionToStringBuilderUtils.reflectOnlySelectedFields
380+
(this, "id", "uuid", "username", "accountName"));
381+
}
382382
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
18+
DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`;
19+
20+
CREATE PROCEDURE `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION` (
21+
IN role VARCHAR(255),
22+
IN rule VARCHAR(255),
23+
IN permission VARCHAR(255)
24+
)
25+
BEGIN
26+
DECLARE role_id BIGINT(20) UNSIGNED
27+
; DECLARE max_sort_order BIGINT(20) UNSIGNED
28+
29+
; SELECT `r`.`id` INTO role_id
30+
FROM `cloud`.`roles` `r`
31+
WHERE `r`.`name` = role
32+
AND `r`.`is_default` = 1
33+
34+
; SELECT MAX(`rp`.`sort_order`) INTO max_sort_order
35+
FROM `cloud`.`role_permissions` `rp`
36+
WHERE `rp`.`role_id` = role_id
37+
38+
; IF NOT EXISTS (
39+
SELECT * FROM `cloud`.`role_permissions` `rp`
40+
WHERE `rp`.`role_id` = role_id
41+
AND `rp`.`rule` = rule
42+
) THEN
43+
UPDATE `cloud`.`role_permissions` `rp`
44+
SET `rp`.`sort_order` = max_sort_order + 1
45+
WHERE `rp`.`sort_order` = max_sort_order
46+
AND `rp`.`role_id` = role_id
47+
48+
; INSERT INTO `cloud`.`role_permissions`
49+
(uuid, role_id, rule, permission, sort_order)
50+
VALUES (uuid(), role_id, rule, permission, max_sort_order)
51+
; END IF
52+
;END;

engine/schema/src/main/resources/META-INF/db/schema-41910to41920.sql

+22
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,25 @@
2121

2222
-- Add last_id to the volumes table
2323
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.volumes', 'last_id', 'bigint(20) unsigned DEFAULT NULL');
24+
25+
-- Grant access to 2FA APIs for the "Read-Only User - Default" role
26+
27+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Read-Only User - Default', 'setupUserTwoFactorAuthentication', 'ALLOW');
28+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Read-Only User - Default', 'validateUserTwoFactorAuthenticationCode', 'ALLOW');
29+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Read-Only User - Default', 'listUserTwoFactorAuthenticatorProviders', 'ALLOW');
30+
31+
-- Grant access to 2FA APIs for the "Support User - Default" role
32+
33+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Support User - Default', 'setupUserTwoFactorAuthentication', 'ALLOW');
34+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Support User - Default', 'validateUserTwoFactorAuthenticationCode', 'ALLOW');
35+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Support User - Default', 'listUserTwoFactorAuthenticatorProviders', 'ALLOW');
36+
37+
-- Grant access to 2FA APIs for the "Read-Only Admin - Default" role
38+
39+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Read-Only Admin - Default', 'setupUserTwoFactorAuthentication', 'ALLOW');
40+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Read-Only Admin - Default', 'validateUserTwoFactorAuthenticationCode', 'ALLOW');
41+
42+
-- Grant access to 2FA APIs for the "Support Admin - Default" role
43+
44+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Support Admin - Default', 'setupUserTwoFactorAuthentication', 'ALLOW');
45+
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Support Admin - Default', 'validateUserTwoFactorAuthenticationCode', 'ALLOW');

engine/schema/src/main/resources/META-INF/db/schema-42000to42010.sql

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
-- Add column api_key_access to user and account tables
2323
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the user" AFTER `secret_key`');
2424
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
25+
CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" ');
2526

2627
-- Modify index for mshost_peer
2728
DELETE FROM `cloud`.`mshost_peer`;

engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,24 @@ public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile
124124
protected List<StoragePool> reorderPoolsByCapacity(DeploymentPlan plan, List<StoragePool> pools) {
125125
Long zoneId = plan.getDataCenterId();
126126
Long clusterId = plan.getClusterId();
127-
short capacityType;
128127

129128
if (CollectionUtils.isEmpty(pools)) {
130129
return null;
131130
}
132131

133-
if (pools.get(0).getPoolType().isShared()) {
132+
short capacityType = Capacity.CAPACITY_TYPE_LOCAL_STORAGE;
133+
String storageType = "local";
134+
StoragePool storagePool = pools.get(0);
135+
if (storagePool.isShared()) {
134136
capacityType = Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED;
135-
} else {
136-
capacityType = Capacity.CAPACITY_TYPE_LOCAL_STORAGE;
137+
storageType = "shared";
137138
}
138139

140+
logger.debug(String.format(
141+
"Filtering storage pools by capacity type [%s] as the first storage pool of the list, with name [%s] and ID [%s], is a [%s] storage.",
142+
capacityType, storagePool.getName(), storagePool.getUuid(), storageType
143+
));
144+
139145
List<Long> poolIdsByCapacity = capacityDao.orderHostsByFreeCapacity(zoneId, clusterId, capacityType);
140146

141147
logger.debug(String.format("List of pools in descending order of available capacity [%s].", poolIdsByCapacity));
@@ -221,6 +227,8 @@ public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachinePro
221227
}
222228

223229
List<StoragePool> reorderStoragePoolsBasedOnAlgorithm(List<StoragePool> pools, DeploymentPlan plan, Account account) {
230+
logger.debug(String.format("Using allocation algorithm [%s] to reorder pools.", allocationAlgorithm));
231+
224232
if (allocationAlgorithm.equals("random") || allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
225233
reorderRandomPools(pools);
226234
} else if (StringUtils.equalsAny(allocationAlgorithm, "userdispersing", "firstfitleastconsumed")) {

packaging/el8/cloud.spec

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Requires: (openssh-clients or openssh)
7171
Requires: (nfs-utils or nfs-client)
7272
Requires: iproute
7373
Requires: wget
74-
Requires: mysql
74+
Requires: (mysql or mariadb)
7575
Requires: sudo
7676
Requires: /sbin/service
7777
Requires: /sbin/chkconfig

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterScaleWorker.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ private boolean removeKubernetesClusterNode(final String ipAddress, final int po
203203
retryCounter++;
204204
try {
205205
Pair<Boolean, String> result = SshHelper.sshExecute(ipAddress, port, getControlNodeLoginUser(),
206-
pkFile, null, String.format("sudo /opt/bin/kubectl drain %s --ignore-daemonsets --delete-local-data", hostName),
206+
pkFile, null, String.format("sudo /opt/bin/kubectl drain %s --ignore-daemonsets --delete-emptydir-data", hostName),
207207
10000, 10000, 60000);
208208
if (!result.first()) {
209209
logger.warn("Draining node: {} on VM: {} in Kubernetes cluster: {} unsuccessful", hostName, userVm, kubernetesCluster);

plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java

+4
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,10 @@ public void validateUserPasswordAndUpdateIfNeeded(String newPassword, UserVO use
527527

528528
@Override
529529
public void checkApiAccess(Account account, String command) throws PermissionDeniedException {
530+
}
530531

532+
@Override
533+
public UserAccount clearUserTwoFactorAuthenticationInSetupStateOnLogin(UserAccount user) {
534+
return null;
531535
}
532536
}

scripts/util/create-kubernetes-binaries-iso.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ echo "Downloading Kubernetes tools ${RELEASE}..."
5353
k8s_dir="${working_dir}/k8s"
5454
mkdir -p "${k8s_dir}"
5555
cd "${k8s_dir}"
56-
curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
56+
curl -L --remote-name-all https://dl.k8s.io/release/${RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
5757
kubeadm_file_permissions=`stat --format '%a' kubeadm`
5858
chmod +x kubeadm
5959

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

+1
Original file line numberDiff line numberDiff line change
@@ -2565,6 +2565,7 @@ public NetworkResponse createNetworkResponse(ResponseView view, Network network)
25652565
response.setIsSystem(networkOffering.isSystemOnly());
25662566
response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString());
25672567
response.setIsPersistent(networkOffering.isPersistent());
2568+
response.setSpecifyVlan(networkOffering.isSpecifyVlan());
25682569
if (Network.GuestType.Isolated.equals(network.getGuestType()) && network.getVpcId() == null) {
25692570
response.setEgressDefaultPolicy(networkOffering.isEgressDefaultPolicy());
25702571
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ public ResponseObject loginUser(final HttpSession session, final String username
11971197
domainId = userDomain.getId();
11981198
}
11991199

1200-
final UserAccount userAcct = accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
1200+
UserAccount userAcct = accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters);
12011201
if (userAcct != null) {
12021202
final String timezone = userAcct.getTimezone();
12031203
float offsetInHrs = 0f;
@@ -1242,6 +1242,7 @@ public ResponseObject loginUser(final HttpSession session, final String username
12421242
session.setAttribute("timezoneoffset", Float.valueOf(offsetInHrs).toString());
12431243
}
12441244

1245+
userAcct = accountMgr.clearUserTwoFactorAuthenticationInSetupStateOnLogin(userAcct);
12451246
boolean is2faEnabled = false;
12461247
if (userAcct.isUser2faEnabled() || (Boolean.TRUE.equals(AccountManagerImpl.enableUserTwoFactorAuthentication.valueIn(userAcct.getDomainId())) && Boolean.TRUE.equals(AccountManagerImpl.mandateUserTwoFactorAuthentication.valueIn(userAcct.getDomainId())))) {
12471248
is2faEnabled = true;

server/src/main/java/com/cloud/storage/StorageManagerImpl.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@
6262
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
6363
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
6464
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
65-
import org.apache.cloudstack.api.command.admin.storage.UpdateObjectStoragePoolCmd;
6665
import org.apache.cloudstack.api.command.admin.storage.UpdateImageStoreCmd;
66+
import org.apache.cloudstack.api.command.admin.storage.UpdateObjectStoragePoolCmd;
6767
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
6868
import org.apache.cloudstack.api.command.admin.storage.heuristics.CreateSecondaryStorageSelectorCmd;
6969
import org.apache.cloudstack.api.command.admin.storage.heuristics.RemoveSecondaryStorageSelectorCmd;
@@ -234,8 +234,8 @@
234234
import com.cloud.utils.DateUtil;
235235
import com.cloud.utils.NumbersUtil;
236236
import com.cloud.utils.Pair;
237-
import com.cloud.utils.UriUtils;
238237
import com.cloud.utils.StringUtils;
238+
import com.cloud.utils.UriUtils;
239239
import com.cloud.utils.component.ComponentContext;
240240
import com.cloud.utils.component.ManagerBase;
241241
import com.cloud.utils.concurrency.NamedThreadFactory;
@@ -499,8 +499,8 @@ public List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, Hypervi
499499
public boolean isLocalStorageActiveOnHost(Long hostId) {
500500
List<StoragePoolHostVO> storagePoolHostRefs = _storagePoolHostDao.listByHostId(hostId);
501501
for (StoragePoolHostVO storagePoolHostRef : storagePoolHostRefs) {
502-
StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(storagePoolHostRef.getPoolId());
503-
if (PrimaryDataStoreVO.getPoolType() == StoragePoolType.LVM || PrimaryDataStoreVO.getPoolType() == StoragePoolType.EXT) {
502+
StoragePoolVO primaryDataStoreVO = _storagePoolDao.findById(storagePoolHostRef.getPoolId());
503+
if (primaryDataStoreVO != null && (primaryDataStoreVO.getPoolType() == StoragePoolType.LVM || primaryDataStoreVO.getPoolType() == StoragePoolType.EXT)) {
504504
SearchBuilder<VolumeVO> volumeSB = volumeDao.createSearchBuilder();
505505
volumeSB.and("poolId", volumeSB.entity().getPoolId(), SearchCriteria.Op.EQ);
506506
volumeSB.and("removed", volumeSB.entity().getRemoved(), SearchCriteria.Op.NULL);
@@ -511,7 +511,7 @@ public boolean isLocalStorageActiveOnHost(Long hostId) {
511511
volumeSB.join("activeVmSB", activeVmSB, volumeSB.entity().getInstanceId(), activeVmSB.entity().getId(), JoinBuilder.JoinType.INNER);
512512

513513
SearchCriteria<VolumeVO> volumeSC = volumeSB.create();
514-
volumeSC.setParameters("poolId", PrimaryDataStoreVO.getId());
514+
volumeSC.setParameters("poolId", primaryDataStoreVO.getId());
515515
volumeSC.setParameters("state", Volume.State.Expunging, Volume.State.Destroy);
516516
volumeSC.setJoinParameters("activeVmSB", "state", State.Starting, State.Running, State.Stopping, State.Migrating);
517517

@@ -2171,9 +2171,9 @@ public String getPrimaryStorageNameLabel(VolumeVO volume) {
21712171
// poolId is null only if volume is destroyed, which has been checked
21722172
// before.
21732173
assert poolId != null;
2174-
StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(poolId);
2175-
assert PrimaryDataStoreVO != null;
2176-
return PrimaryDataStoreVO.getUuid();
2174+
StoragePoolVO primaryDataStoreVO = _storagePoolDao.findById(poolId);
2175+
assert primaryDataStoreVO != null;
2176+
return primaryDataStoreVO.getUuid();
21772177
}
21782178

21792179
@Override
@@ -2724,8 +2724,8 @@ private CapacityVO getStoragePoolUsedStatsInternal(Long zoneId, Long podId, Long
27242724
}
27252725

27262726
CapacityVO capacity = new CapacityVO(poolId, zoneId, podId, clusterId, 0, 0, Capacity.CAPACITY_TYPE_STORAGE);
2727-
for (StoragePoolVO pool : pools) {
2728-
StorageStats stats = ApiDBUtils.getStoragePoolStatistics(pool.getId());
2727+
for (StoragePoolVO primaryDataStoreVO : pools) {
2728+
StorageStats stats = ApiDBUtils.getStoragePoolStatistics(primaryDataStoreVO.getId());
27292729
if (stats == null) {
27302730
continue;
27312731
}

0 commit comments

Comments
 (0)