Skip to content

Commit 871a27a

Browse files
authored
Merge branch '4.19' into healthcheck-4.19
2 parents 8bc7c3d + 0d5047b commit 871a27a

File tree

33 files changed

+754
-123
lines changed

33 files changed

+754
-123
lines changed

api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.ArrayList;
2020
import java.util.List;
2121

22+
import org.apache.commons.collections.CollectionUtils;
23+
import org.apache.commons.lang3.StringUtils;
2224
import org.apache.log4j.Logger;
2325

2426
import org.apache.cloudstack.acl.RoleType;
@@ -103,14 +105,13 @@ public String getProtocol() {
103105

104106
@Override
105107
public List<String> getSourceCidrList() {
106-
if (cidrlist != null) {
108+
if (CollectionUtils.isNotEmpty(cidrlist) && !(cidrlist.size() == 1 && StringUtils.isBlank(cidrlist.get(0)))) {
107109
return cidrlist;
108110
} else {
109-
List<String> oneCidrList = new ArrayList<String>();
111+
List<String> oneCidrList = new ArrayList<>();
110112
oneCidrList.add(NetUtils.ALL_IP4_CIDRS);
111113
return oneCidrList;
112114
}
113-
114115
}
115116

116117
// ///////////////////////////////////////////////////

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
187187
@Param(description = "true network requires restart")
188188
private Boolean restartRequired;
189189

190+
@SerializedName(ApiConstants.SPECIFY_VLAN)
191+
@Param(description = "true if network supports specifying vlan, false otherwise")
192+
private Boolean specifyVlan;
193+
190194
@SerializedName(ApiConstants.SPECIFY_IP_RANGES)
191195
@Param(description = "true if network supports specifying ip ranges, false otherwise")
192196
private Boolean specifyIpRanges;
@@ -487,6 +491,10 @@ public void setRestartRequired(Boolean restartRequired) {
487491
this.restartRequired = restartRequired;
488492
}
489493

494+
public void setSpecifyVlan(Boolean specifyVlan) {
495+
this.specifyVlan = specifyVlan;
496+
}
497+
490498
public void setSpecifyIpRanges(Boolean specifyIpRanges) {
491499
this.specifyIpRanges = specifyIpRanges;
492500
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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.api.command.user.firewall;
18+
19+
import java.util.ArrayList;
20+
import java.util.Arrays;
21+
import java.util.Collections;
22+
import java.util.List;
23+
24+
import org.apache.commons.collections.CollectionUtils;
25+
import org.junit.Assert;
26+
import org.junit.Test;
27+
import org.junit.runner.RunWith;
28+
import org.mockito.junit.MockitoJUnitRunner;
29+
import org.springframework.test.util.ReflectionTestUtils;
30+
31+
import com.cloud.utils.net.NetUtils;
32+
33+
@RunWith(MockitoJUnitRunner.class)
34+
public class CreateFirewallRuleCmdTest {
35+
36+
private void validateAllIp4Cidr(final CreateFirewallRuleCmd cmd) {
37+
Assert.assertTrue(CollectionUtils.isNotEmpty(cmd.getSourceCidrList()));
38+
Assert.assertEquals(1, cmd.getSourceCidrList().size());
39+
Assert.assertEquals(NetUtils.ALL_IP4_CIDRS, cmd.getSourceCidrList().get(0));
40+
}
41+
42+
@Test
43+
public void testGetSourceCidrList_Null() {
44+
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
45+
ReflectionTestUtils.setField(cmd, "cidrlist", null);
46+
validateAllIp4Cidr(cmd);
47+
}
48+
49+
@Test
50+
public void testGetSourceCidrList_Empty() {
51+
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
52+
ReflectionTestUtils.setField(cmd, "cidrlist", new ArrayList<>());
53+
validateAllIp4Cidr(cmd);
54+
}
55+
56+
@Test
57+
public void testGetSourceCidrList_NullFirstElement() {
58+
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
59+
List<String> list = new ArrayList<>();
60+
list.add(null);
61+
ReflectionTestUtils.setField(cmd, "cidrlist", list);
62+
validateAllIp4Cidr(cmd);
63+
}
64+
65+
@Test
66+
public void testGetSourceCidrList_EmptyFirstElement() {
67+
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
68+
ReflectionTestUtils.setField(cmd, "cidrlist", Collections.singletonList(" "));
69+
validateAllIp4Cidr(cmd);
70+
}
71+
72+
@Test
73+
public void testGetSourceCidrList_Valid() {
74+
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
75+
String cidr = "10.1.1.1/22";
76+
ReflectionTestUtils.setField(cmd, "cidrlist", Collections.singletonList(cidr));
77+
Assert.assertTrue(CollectionUtils.isNotEmpty(cmd.getSourceCidrList()));
78+
Assert.assertEquals(1, cmd.getSourceCidrList().size());
79+
Assert.assertEquals(cidr, cmd.getSourceCidrList().get(0));
80+
}
81+
82+
@Test
83+
public void testGetSourceCidrList_EmptyFirstElementButMore() {
84+
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
85+
String cidr = "10.1.1.1/22";
86+
ReflectionTestUtils.setField(cmd, "cidrlist", Arrays.asList(" ", cidr));
87+
Assert.assertTrue(CollectionUtils.isNotEmpty(cmd.getSourceCidrList()));
88+
Assert.assertEquals(2, cmd.getSourceCidrList().size());
89+
Assert.assertEquals(cidr, cmd.getSourceCidrList().get(1));
90+
}
91+
}

engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ public interface NetworkOrchestrationService {
8181
ConfigKey<Integer> NetworkLockTimeout = new ConfigKey<Integer>(Integer.class, NetworkLockTimeoutCK, "Network", "600",
8282
"Lock wait timeout (seconds) while implementing network", true, Scope.Global, null);
8383

84+
ConfigKey<String> DeniedRoutes = new ConfigKey<String>(String.class, "denied.routes", "Network", "",
85+
"Routes that are denied, can not be used for Static Routes creation for the VPC Private Gateway", true, ConfigKey.Scope.Zone, null);
86+
8487
ConfigKey<String> GuestDomainSuffix = new ConfigKey<String>(String.class, GuestDomainSuffixCK, "Network", "cloud.internal",
8588
"Default domain name for vms inside virtualized networks fronted by router", true, ConfigKey.Scope.Zone, null);
8689

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4792,7 +4792,7 @@ public String getConfigComponentName() {
47924792

47934793
@Override
47944794
public ConfigKey<?>[] getConfigKeys() {
4795-
return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
4795+
return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout, DeniedRoutes,
47964796
GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
47974797
PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RollingRestartEnabled,
47984798
TUNGSTEN_ENABLED };

engine/schema/src/main/java/com/cloud/host/dao/HostDaoImpl.java

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.cloud.org.Managed;
6161
import com.cloud.resource.ResourceState;
6262
import com.cloud.utils.DateUtil;
63+
import com.cloud.utils.StringUtils;
6364
import com.cloud.utils.db.Attribute;
6465
import com.cloud.utils.db.DB;
6566
import com.cloud.utils.db.Filter;
@@ -83,13 +84,13 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
8384
private static final Logger status_logger = Logger.getLogger(Status.class);
8485
private static final Logger state_logger = Logger.getLogger(ResourceState.class);
8586

86-
private static final String LIST_HOST_IDS_BY_COMPUTETAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
87-
+ "FROM (SELECT host_id, tag, is_tag_a_rule FROM host_tags GROUP BY host_id,tag) AS filtered "
88-
+ "WHERE tag IN(%s) AND is_tag_a_rule = 0 "
87+
private static final String LIST_HOST_IDS_BY_HOST_TAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
88+
+ "FROM (SELECT host_id, tag, is_tag_a_rule FROM host_tags GROUP BY host_id,tag,is_tag_a_rule) AS filtered "
89+
+ "WHERE tag IN (%s) AND (is_tag_a_rule = 0 OR is_tag_a_rule IS NULL) "
8990
+ "GROUP BY host_id "
9091
+ "HAVING tag_count = %s ";
9192
private static final String SEPARATOR = ",";
92-
private static final String LIST_CLUSTERID_FOR_HOST_TAG = "select distinct cluster_id from host join ( %s ) AS selected_hosts ON host.id = selected_hosts.host_id";
93+
private static final String LIST_CLUSTER_IDS_FOR_HOST_TAGS = "select distinct cluster_id from host join ( %s ) AS selected_hosts ON host.id = selected_hosts.host_id";
9394
private static final String GET_HOSTS_OF_ACTIVE_VMS = "select h.id " +
9495
"from vm_instance vm " +
9596
"join host h on (vm.host_id=h.id) " +
@@ -785,6 +786,15 @@ public void markHostsAsDisconnected(long msId, long lastPing) {
785786

786787
@Override
787788
public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag) {
789+
return listHostsWithOrWithoutHostTags(type, clusterId, podId, dcId, hostTag, true);
790+
}
791+
792+
private List<HostVO> listHostsWithOrWithoutHostTags(Host.Type type, Long clusterId, Long podId, long dcId, String hostTags, boolean withHostTags) {
793+
if (StringUtils.isEmpty(hostTags)) {
794+
s_logger.debug("Host tags not specified, to list hosts");
795+
return new ArrayList();
796+
}
797+
788798
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
789799
HostVO entity = hostSearch.entity();
790800
hostSearch.and("type", entity.getType(), SearchCriteria.Op.EQ);
@@ -795,7 +805,9 @@ public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, lo
795805
hostSearch.and("resourceState", entity.getResourceState(), SearchCriteria.Op.EQ);
796806

797807
SearchCriteria<HostVO> sc = hostSearch.create();
798-
sc.setParameters("type", type.toString());
808+
if (type != null) {
809+
sc.setParameters("type", type.toString());
810+
}
799811
if (podId != null) {
800812
sc.setParameters("pod", podId);
801813
}
@@ -806,27 +818,38 @@ public List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, lo
806818
sc.setParameters("status", Status.Up.toString());
807819
sc.setParameters("resourceState", ResourceState.Enabled.toString());
808820

809-
List<HostVO> tmpHosts = listBy(sc);
810-
List<HostVO> correctHostsByHostTags = new ArrayList();
811-
List<Long> hostIdsByComputeOffTags = findHostByComputeOfferings(hostTag);
821+
List<HostVO> upAndEnabledHosts = listBy(sc);
822+
if (CollectionUtils.isEmpty(upAndEnabledHosts)) {
823+
return new ArrayList();
824+
}
812825

813-
tmpHosts.forEach((host) -> { if(hostIdsByComputeOffTags.contains(host.getId())) correctHostsByHostTags.add(host);});
826+
List<Long> hostIdsByHostTags = findHostIdsByHostTags(hostTags);
827+
if (CollectionUtils.isEmpty(hostIdsByHostTags)) {
828+
return withHostTags ? new ArrayList() : upAndEnabledHosts;
829+
}
814830

815-
return correctHostsByHostTags;
831+
if (withHostTags) {
832+
List<HostVO> upAndEnabledHostsWithHostTags = new ArrayList();
833+
upAndEnabledHosts.forEach((host) -> { if (hostIdsByHostTags.contains(host.getId())) upAndEnabledHostsWithHostTags.add(host);});
834+
return upAndEnabledHostsWithHostTags;
835+
} else {
836+
List<HostVO> upAndEnabledHostsWithoutHostTags = new ArrayList();
837+
upAndEnabledHosts.forEach((host) -> { if (!hostIdsByHostTags.contains(host.getId())) upAndEnabledHostsWithoutHostTags.add(host);});
838+
return upAndEnabledHostsWithoutHostTags;
839+
}
816840
}
817841

818842
@Override
819843
public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag) {
844+
if (StringUtils.isNotEmpty(haTag)) {
845+
return listHostsWithOrWithoutHostTags(type, clusterId, podId, dcId, haTag, false);
846+
}
847+
820848
SearchBuilder<HostTagVO> hostTagSearch = _hostTagsDao.createSearchBuilder();
821849
hostTagSearch.and();
822850
hostTagSearch.op("isTagARule", hostTagSearch.entity().getIsTagARule(), Op.EQ);
823851
hostTagSearch.or("tagDoesNotExist", hostTagSearch.entity().getIsTagARule(), Op.NULL);
824852
hostTagSearch.cp();
825-
if (haTag != null && !haTag.isEmpty()) {
826-
hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
827-
hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
828-
hostTagSearch.cp();
829-
}
830853

831854
SearchBuilder<HostVO> hostSearch = createSearchBuilder();
832855

@@ -837,18 +860,12 @@ public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Lon
837860
hostSearch.and("status", hostSearch.entity().getStatus(), SearchCriteria.Op.EQ);
838861
hostSearch.and("resourceState", hostSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
839862

840-
841863
hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
842864

843-
844865
SearchCriteria<HostVO> sc = hostSearch.create();
845866

846867
sc.setJoinParameters("hostTagSearch", "isTagARule", false);
847868

848-
if (haTag != null && !haTag.isEmpty()) {
849-
sc.setJoinParameters("hostTagSearch", "tag", haTag);
850-
}
851-
852869
if (type != null) {
853870
sc.setParameters("type", type);
854871
}
@@ -1300,19 +1317,19 @@ public List<HostVO> listAllHostsThatHaveNoRuleTag(Type type, Long clusterId, Lon
13001317
}
13011318

13021319
@Override
1303-
public List<Long> listClustersByHostTag(String computeOfferingTags) {
1320+
public List<Long> listClustersByHostTag(String hostTags) {
13041321
TransactionLegacy txn = TransactionLegacy.currentTxn();
1305-
String sql = this.LIST_CLUSTERID_FOR_HOST_TAG;
1322+
String selectStmtToListClusterIdsByHostTags = this.LIST_CLUSTER_IDS_FOR_HOST_TAGS;
13061323
PreparedStatement pstmt = null;
13071324
List<Long> result = new ArrayList();
1308-
List<String> tags = Arrays.asList(computeOfferingTags.split(this.SEPARATOR));
1309-
String subselect = getHostIdsByComputeTags(tags);
1310-
sql = String.format(sql, subselect);
1325+
List<String> tags = Arrays.asList(hostTags.split(this.SEPARATOR));
1326+
String selectStmtToListHostIdsByHostTags = getSelectStmtToListHostIdsByHostTags(tags);
1327+
selectStmtToListClusterIdsByHostTags = String.format(selectStmtToListClusterIdsByHostTags, selectStmtToListHostIdsByHostTags);
13111328

13121329
try {
1313-
pstmt = txn.prepareStatement(sql);
1330+
pstmt = txn.prepareStatement(selectStmtToListClusterIdsByHostTags);
13141331

1315-
for(int i = 0; i < tags.size(); i++){
1332+
for (int i = 0; i < tags.size(); i++){
13161333
pstmt.setString(i+1, tags.get(i));
13171334
}
13181335

@@ -1323,20 +1340,20 @@ public List<Long> listClustersByHostTag(String computeOfferingTags) {
13231340
pstmt.close();
13241341
return result;
13251342
} catch (SQLException e) {
1326-
throw new CloudRuntimeException("DB Exception on: " + sql, e);
1343+
throw new CloudRuntimeException("DB Exception on: " + selectStmtToListClusterIdsByHostTags, e);
13271344
}
13281345
}
13291346

1330-
private List<Long> findHostByComputeOfferings(String computeOfferingTags){
1347+
private List<Long> findHostIdsByHostTags(String hostTags){
13311348
TransactionLegacy txn = TransactionLegacy.currentTxn();
13321349
PreparedStatement pstmt = null;
13331350
List<Long> result = new ArrayList();
1334-
List<String> tags = Arrays.asList(computeOfferingTags.split(this.SEPARATOR));
1335-
String select = getHostIdsByComputeTags(tags);
1351+
List<String> tags = Arrays.asList(hostTags.split(this.SEPARATOR));
1352+
String selectStmtToListHostIdsByHostTags = getSelectStmtToListHostIdsByHostTags(tags);
13361353
try {
1337-
pstmt = txn.prepareStatement(select);
1354+
pstmt = txn.prepareStatement(selectStmtToListHostIdsByHostTags);
13381355

1339-
for(int i = 0; i < tags.size(); i++){
1356+
for (int i = 0; i < tags.size(); i++){
13401357
pstmt.setString(i+1, tags.get(i));
13411358
}
13421359

@@ -1347,7 +1364,7 @@ private List<Long> findHostByComputeOfferings(String computeOfferingTags){
13471364
pstmt.close();
13481365
return result;
13491366
} catch (SQLException e) {
1350-
throw new CloudRuntimeException("DB Exception on: " + select, e);
1367+
throw new CloudRuntimeException("DB Exception on: " + selectStmtToListHostIdsByHostTags, e);
13511368
}
13521369
}
13531370

@@ -1372,10 +1389,10 @@ public List<Long> findClustersThatMatchHostTagRule(String computeOfferingTags) {
13721389
return new ArrayList<>(result);
13731390
}
13741391

1375-
private String getHostIdsByComputeTags(List<String> offeringTags){
1392+
private String getSelectStmtToListHostIdsByHostTags(List<String> hostTags){
13761393
List<String> questionMarks = new ArrayList();
1377-
offeringTags.forEach((tag) -> { questionMarks.add("?"); });
1378-
return String.format(this.LIST_HOST_IDS_BY_COMPUTETAGS, String.join(",", questionMarks),questionMarks.size());
1394+
hostTags.forEach((tag) -> { questionMarks.add("?"); });
1395+
return String.format(this.LIST_HOST_IDS_BY_HOST_TAGS, String.join(",", questionMarks), questionMarks.size());
13791396
}
13801397

13811398
@Override

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535

3636
import com.cloud.utils.db.Encrypt;
3737
import com.cloud.utils.db.GenericDao;
38+
39+
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
3840
import org.apache.commons.lang3.StringUtils;
3941

4042
@Entity
@@ -368,4 +370,9 @@ public Map<String, String> getDetails() {
368370
public void setDetails(Map<String, String> details) {
369371
this.details = details;
370372
}
373+
374+
@Override
375+
public String toString() {
376+
return String.format("User %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "name", "uuid"));
377+
}
371378
}

0 commit comments

Comments
 (0)