Skip to content

Commit 685cc72

Browse files
rafaelweingartnerDaanHoogland
authored andcommitted
[CLOUDSTACK-10344] bug when moving ACL rules (change order with drag and drop) (#2511)
* Add permission to 'moveNetworkAclItem' API method in default roles
1 parent 5d9ae35 commit 685cc72

11 files changed

Lines changed: 749 additions & 50 deletions

File tree

api/src/main/java/com/cloud/network/vpc/NetworkACLService.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
2222
import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
2323
import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
24+
import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
2425
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
2526
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
2627

2728
import com.cloud.exception.ResourceUnavailableException;
2829
import com.cloud.utils.Pair;
2930

3031
public interface NetworkACLService {
32+
3133
/**
3234
* Creates Network ACL for the specified VPC
3335
*/
@@ -90,4 +92,8 @@ public interface NetworkACLService {
9092

9193
NetworkACL updateNetworkACL(UpdateNetworkACLListCmd updateNetworkACLListCmd);
9294

93-
}
95+
/**
96+
* Updates a network item ACL to a new position. This method allows users to inform between which ACLs the given ACL will be placed. Therefore, the 'number' field will be filled out by the system in the best way possible to place the ACL accordingly.
97+
*/
98+
NetworkACLItem moveNetworkAclRuleToNewPosition(MoveNetworkAclItemCmd moveNetworkAclItemCmd);
99+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ public class ApiConstants {
152152
public static final String ICMP_TYPE = "icmptype";
153153
public static final String ID = "id";
154154
public static final String IDS = "ids";
155+
public static final String PREVIOUS_ACL_RULE_ID = "previousaclruleid";
156+
public static final String NEXT_ACL_RULE_ID = "nextaclruleid";
155157
public static final String INTERNAL_DNS1 = "internaldns1";
156158
public static final String INTERNAL_DNS2 = "internaldns2";
157159
public static final String INTERVAL_TYPE = "intervaltype";
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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.network;
18+
19+
import org.apache.cloudstack.api.APICommand;
20+
import org.apache.cloudstack.api.ApiConstants;
21+
import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
22+
import org.apache.cloudstack.api.Parameter;
23+
import org.apache.cloudstack.api.response.NetworkACLItemResponse;
24+
import org.apache.cloudstack.context.CallContext;
25+
import org.apache.log4j.Logger;
26+
27+
import com.cloud.event.EventTypes;
28+
import com.cloud.network.vpc.NetworkACLItem;
29+
import com.cloud.user.Account;
30+
31+
@APICommand(name = "moveNetworkAclItem", description = "Move an ACL rule to a position bettwen two other ACL rules of the same ACL network list", responseObject = NetworkACLItemResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
32+
public class MoveNetworkAclItemCmd extends BaseAsyncCustomIdCmd {
33+
34+
public static final Logger s_logger = Logger.getLogger(MoveNetworkAclItemCmd.class.getName());
35+
private static final String s_name = "moveNetworkAclItemResponse";
36+
37+
@Parameter(name = ApiConstants.ID, type = CommandType.STRING, required = true, description = "The ID of the network ACL rule that is being moved to a new position.")
38+
private String uuidRuleBeingMoved;
39+
40+
@Parameter(name = ApiConstants.PREVIOUS_ACL_RULE_ID, type = CommandType.STRING, description = "The ID of the first rule that is right before the new position where the rule being moved is going to be placed. This value can be 'NULL' if the rule is being moved to the first position of the network ACL list.")
41+
private String previousAclRuleUuid;
42+
43+
@Parameter(name = ApiConstants.NEXT_ACL_RULE_ID, type = CommandType.STRING, description = "The ID of the rule that is right after the new position where the rule being moved is going to be placed. This value can be 'NULL' if the rule is being moved to the last position of the network ACL list.")
44+
private String nextAclRuleUuid;
45+
46+
@Override
47+
public void execute() {
48+
CallContext.current().setEventDetails(getEventDescription());
49+
50+
NetworkACLItem aclItem = _networkACLService.moveNetworkAclRuleToNewPosition(this);
51+
52+
NetworkACLItemResponse aclResponse = _responseGenerator.createNetworkACLItemResponse(aclItem);
53+
setResponseObject(aclResponse);
54+
aclResponse.setResponseName(getCommandName());
55+
}
56+
57+
public String getUuidRuleBeingMoved() {
58+
return uuidRuleBeingMoved;
59+
}
60+
61+
public String getPreviousAclRuleUuid() {
62+
return previousAclRuleUuid;
63+
}
64+
65+
public String getNextAclRuleUuid() {
66+
return nextAclRuleUuid;
67+
}
68+
69+
@Override
70+
public void checkUuid() {
71+
if (this.getCustomId() != null) {
72+
_uuidMgr.checkUuid(this.getCustomId(), NetworkACLItem.class);
73+
}
74+
}
75+
76+
@Override
77+
public String getEventType() {
78+
return EventTypes.EVENT_NETWORK_ACL_ITEM_UPDATE;
79+
}
80+
81+
@Override
82+
public String getEventDescription() {
83+
return String.format("Placing network ACL item [%s] between [%s] and [%s].", uuidRuleBeingMoved, previousAclRuleUuid, nextAclRuleUuid);
84+
}
85+
86+
@Override
87+
public String getCommandName() {
88+
return s_name;
89+
}
90+
91+
@Override
92+
public long getEntityOwnerId() {
93+
Account caller = CallContext.current().getCallingAccount();
94+
return caller.getAccountId();
95+
}
96+
}

engine/schema/src/main/java/com/cloud/network/vpc/NetworkACLItemDao.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import com.cloud.utils.db.GenericDao;
2222

23-
/*
23+
/**
2424
* Data Access Object for network_acl_item table
2525
*/
2626
public interface NetworkACLItemDao extends GenericDao<NetworkACLItemVO, Long> {
@@ -36,4 +36,12 @@ public interface NetworkACLItemDao extends GenericDao<NetworkACLItemVO, Long> {
3636
NetworkACLItemVO findByAclAndNumber(long aclId, int number);
3737

3838
void loadCidrs(NetworkACLItemVO item);
39+
40+
/**
41+
* Updated the network ACL item 'number' field.
42+
*
43+
* @param networkItemId is the ID of the network ACL rule that will have its 'number' field updated.
44+
* @param newNumberValue is the new value that will be assigned to the 'number' field.
45+
*/
46+
void updateNumberFieldNetworkItem(long networkItemId, int newNumberValue);
3947
}

engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemCidrsDaoImpl.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.ArrayList;
2222
import java.util.List;
2323

24-
2524
import org.apache.log4j.Logger;
2625
import org.springframework.stereotype.Component;
2726

engine/schema/src/main/java/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
// under the License.
1717
package com.cloud.network.vpc.dao;
1818

19+
import java.sql.PreparedStatement;
20+
import java.sql.SQLException;
1921
import java.util.List;
2022

2123
import javax.inject.Inject;
2224

23-
import com.google.common.collect.Lists;
24-
import org.apache.log4j.Logger;
2525
import org.springframework.stereotype.Component;
2626

2727
import com.cloud.network.vpc.NetworkACLItem.State;
@@ -35,11 +35,12 @@
3535
import com.cloud.utils.db.SearchCriteria;
3636
import com.cloud.utils.db.SearchCriteria.Op;
3737
import com.cloud.utils.db.TransactionLegacy;
38+
import com.cloud.utils.exception.CloudRuntimeException;
39+
import com.google.common.collect.Lists;
3840

39-
@Component
4041
@DB()
42+
@Component
4143
public class NetworkACLItemDaoImpl extends GenericDaoBase<NetworkACLItemVO, Long> implements NetworkACLItemDao {
42-
private static final Logger s_logger = Logger.getLogger(NetworkACLItemDaoImpl.class);
4344

4445
protected final SearchBuilder<NetworkACLItemVO> AllFieldsSearch;
4546
protected final SearchBuilder<NetworkACLItemVO> NotRevokedSearch;
@@ -115,12 +116,14 @@ public boolean revoke(NetworkACLItemVO rule) {
115116

116117
@Override
117118
public List<NetworkACLItemVO> listByACL(Long aclId) {
118-
if (aclId == null) return Lists.newArrayList();
119+
if (aclId == null) {
120+
return Lists.newArrayList();
121+
}
119122

120123
SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
121124
sc.setParameters("aclId", aclId);
122125
List<NetworkACLItemVO> list = listBy(sc);
123-
for(NetworkACLItemVO item :list) {
126+
for (NetworkACLItemVO item : list) {
124127
loadCidrs(item);
125128
}
126129
return list;
@@ -140,7 +143,7 @@ public NetworkACLItemVO findByAclAndNumber(long aclId, int number) {
140143
sc.setParameters("aclId", aclId);
141144
sc.setParameters("number", number);
142145
NetworkACLItemVO vo = findOneBy(sc);
143-
if(vo != null) {
146+
if (vo != null) {
144147
loadCidrs(vo);
145148
}
146149
return vo;
@@ -172,4 +175,19 @@ public void loadCidrs(NetworkACLItemVO item) {
172175
List<String> cidrs = _networkACLItemCidrsDao.getCidrs(item.getId());
173176
item.setSourceCidrList(cidrs);
174177
}
175-
}
178+
179+
private String sqlUpdateNumberFieldNetworkItem = "UPDATE network_acl_item SET number = ? where id =?";
180+
181+
@Override
182+
public void updateNumberFieldNetworkItem(long networkItemId, int newNumberValue) {
183+
try (TransactionLegacy txn = TransactionLegacy.currentTxn();
184+
PreparedStatement pstmt = txn.prepareAutoCloseStatement(sqlUpdateNumberFieldNetworkItem)) {
185+
pstmt.setLong(1, newNumberValue);
186+
pstmt.setLong(2, networkItemId);
187+
pstmt.executeUpdate();
188+
txn.commit();
189+
} catch (SQLException e) {
190+
throw new CloudRuntimeException(e);
191+
}
192+
}
193+
}

engine/schema/src/main/resources/META-INF/db/schema-41110to41200.sql

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,10 @@ ALTER TABLE `cloud`.`network_acl_item` ADD COLUMN `reason` VARCHAR(2500) AFTER `
2626
ALTER TABLE `cloud`.`alert` ADD COLUMN `content` VARCHAR(5000);
2727

2828
-- Fix the name of the column used to hold IPv4 range in 'vlan' table.
29-
ALTER TABLE `vlan` CHANGE `description` `ip4_range` varchar(255);
29+
ALTER TABLE `vlan` CHANGE `description` `ip4_range` varchar(255);
30+
31+
-- [CLOUDSTACK-10344] bug when moving ACL rules (change order with drag and drop)
32+
-- We are only adding the permission to the default rules. Any custom rule must be configured by the root admin.
33+
INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), 2, 'moveNetworkAclItem', 'ALLOW', 100) ON DUPLICATE KEY UPDATE rule=rule;
34+
INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), 3, 'moveNetworkAclItem', 'ALLOW', 302) ON DUPLICATE KEY UPDATE rule=rule;
35+
INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) values (UUID(), 4, 'moveNetworkAclItem', 'ALLOW', 260) ON DUPLICATE KEY UPDATE rule=rule;

0 commit comments

Comments
 (0)