Skip to content

Commit 0e87040

Browse files
authored
network: allow ability to specify if network's ipaddress usage need to be hidden (#3235)
Problem: Admins don’t want to charge for IP address usage on certain (shared) networks. Root Cause: There is no flag or detail for admins to provide using UI or API when creating networks to specify if they want IP address usage of the network hidden. Solution: A new boolean hideipaddressusage flag is added to the createNetwork API and a checkbox in the ‘Add guest network’ UI for the root admins to specify if they want the shared network’s IP address usage to be hidden in the listUsageRecords API response. The provided flag is saved as the ‘hideIpAddressUsage’ detail in the cloud.network_details table for the network. For existing (shared) networks, root admins can also specify the same boolean API parameter hideipaddressusage with the updateNetwork API request to configure the behaviour for an existing network. When the detail/flag is true, the IP address usage for the (shared) network is not exported in the listUsageRecords API response. The listNetworks API response will include the details of a network for root admin only. (note usage is still recorded in the usage database but not return by the listUsageRecords API) The API flag works for any kind of network via the API, but the checkbox is only shown while creating shared networks in the UI. Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
1 parent 0886c0c commit 0e87040

15 files changed

Lines changed: 290 additions & 196 deletions

File tree

api/src/main/java/com/cloud/network/Network.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@
4040
*/
4141
public interface Network extends ControlledEntity, StateObject<Network.State>, InternalIdentity, Identity, Serializable, Displayable {
4242

43-
public enum GuestType {
43+
enum GuestType {
4444
Shared, Isolated, L2
4545
}
4646

47-
public String updatingInSequence ="updatingInSequence";
47+
String updatingInSequence = "updatingInSequence";
48+
String hideIpAddressUsage = "hideIpAddressUsage";
4849

49-
public static class Service {
50+
class Service {
5051
private static List<Service> supportedServices = new ArrayList<Service>();
5152

5253
public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnProtocols, Capability.VpnTypes);

api/src/main/java/com/cloud/network/NetworkService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
2727
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
2828
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
29+
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
2930
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
3031
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
3132

@@ -81,8 +82,7 @@ IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long ne
8182

8283
IpAddress getIp(long id);
8384

84-
Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId,
85-
Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID, boolean updateInSequence, boolean forced);
85+
Network updateGuestNetwork(final UpdateNetworkCmd cmd);
8686

8787
/**
8888
* Migrate a network from one physical network to another physical network

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public class ApiConstants {
150150
public static final String HA_PROVIDER = "haprovider";
151151
public static final String HA_STATE = "hastate";
152152
public static final String HEALTH = "health";
153+
public static final String HIDE_IP_ADDRESS_USAGE = "hideipaddressusage";
153154
public static final String HOST_ID = "hostid";
154155
public static final String HOST_NAME = "hostname";
155156
public static final String HYPERVISOR = "hypervisor";

api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkCmdByAdmin.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd {
4343
@Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during network creation for shared and L2 networks")
4444
private Boolean bypassVlanOverlapCheck;
4545

46+
@Parameter(name=ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description="when true ip address usage for the network will not be exported by the listUsageRecords API")
47+
private Boolean hideIpAddressUsage;
48+
4649
/////////////////////////////////////////////////////
4750
/////////////////// Accessors ///////////////////////
4851
/////////////////////////////////////////////////////
@@ -58,6 +61,13 @@ public Boolean getBypassVlanOverlapCheck() {
5861
return false;
5962
}
6063

64+
public Boolean getHideIpAddressUsage() {
65+
if (hideIpAddressUsage != null) {
66+
return hideIpAddressUsage;
67+
}
68+
return false;
69+
}
70+
6171
/////////////////////////////////////////////////////
6272
/////////////// API Implementation///////////////////
6373
/////////////////////////////////////////////////////

api/src/main/java/org/apache/cloudstack/api/command/admin/network/UpdateNetworkCmdByAdmin.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,44 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.admin.network;
1818

19-
import org.apache.log4j.Logger;
20-
2119
import org.apache.cloudstack.api.APICommand;
20+
import org.apache.cloudstack.api.ApiConstants;
2221
import org.apache.cloudstack.api.ApiErrorCode;
22+
import org.apache.cloudstack.api.Parameter;
2323
import org.apache.cloudstack.api.ResponseObject.ResponseView;
2424
import org.apache.cloudstack.api.ServerApiException;
2525
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
2626
import org.apache.cloudstack.api.response.NetworkResponse;
27-
import org.apache.cloudstack.context.CallContext;
27+
import org.apache.log4j.Logger;
2828

2929
import com.cloud.exception.ConcurrentOperationException;
3030
import com.cloud.exception.InsufficientCapacityException;
3131
import com.cloud.exception.InvalidParameterValueException;
3232
import com.cloud.network.Network;
33-
import com.cloud.user.Account;
34-
import com.cloud.user.User;
3533

3634
@APICommand(name = "updateNetwork", description = "Updates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Full, entityType = {Network.class},
3735
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
3836
public class UpdateNetworkCmdByAdmin extends UpdateNetworkCmd {
3937
public static final Logger s_logger = Logger.getLogger(UpdateNetworkCmdByAdmin.class.getName());
4038

39+
@Parameter(name= ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description="when true ip address usage for the network will not be exported by the listUsageRecords API")
40+
private Boolean hideIpAddressUsage;
41+
42+
public Boolean getHideIpAddressUsage() {
43+
if (hideIpAddressUsage == null) {
44+
return false;
45+
}
46+
return hideIpAddressUsage;
47+
}
4148

4249
@Override
4350
public void execute() throws InsufficientCapacityException, ConcurrentOperationException{
44-
User callerUser = _accountService.getActiveUser(CallContext.current().getCallingUserId());
45-
Account callerAccount = _accountService.getActiveAccountById(callerUser.getAccountId());
4651
Network network = _networkService.getNetwork(id);
4752
if (network == null) {
4853
throw new InvalidParameterValueException("Couldn't find network by id");
4954
}
5055

51-
Network result = _networkService.updateGuestNetwork(getId(), getNetworkName(), getDisplayText(), callerAccount,
52-
callerUser, getNetworkDomain(), getNetworkOfferingId(), getChangeCidr(), getGuestVmCidr(), getDisplayNetwork(), getCustomId(), getUpdateInSequence(),getForced());
53-
54-
56+
Network result = _networkService.updateGuestNetwork(this);
5557
if (result != null) {
5658
NetworkResponse response = _responseGenerator.createNetworkResponse(ResponseView.Full, result);
5759
response.setResponseName(getCommandName());

api/src/main/java/org/apache/cloudstack/api/command/admin/usage/ListUsageRecordsCmd.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.Map;
2323
import java.util.Set;
2424

25-
import com.cloud.utils.Pair;
2625
import org.apache.cloudstack.api.APICommand;
2726
import org.apache.cloudstack.api.ApiConstants;
2827
import org.apache.cloudstack.api.BaseCmd;
@@ -36,6 +35,8 @@
3635
import org.apache.cloudstack.api.response.UsageRecordResponse;
3736
import org.apache.cloudstack.usage.Usage;
3837

38+
import com.cloud.utils.Pair;
39+
3940
@APICommand(name = ListUsageRecordsCmd.APINAME,
4041
description = "Lists usage records for accounts",
4142
responseObject = UsageRecordResponse.class,
@@ -168,11 +169,13 @@ public void execute() {
168169
}
169170
for (Usage usageRecord : usageRecords.first()) {
170171
UsageRecordResponse usageResponse = _responseGenerator.createUsageResponse(usageRecord, resourceTagResponseMap);
171-
usageResponse.setObjectName("usagerecord");
172-
usageResponses.add(usageResponse);
172+
if (usageResponse != null) {
173+
usageResponse.setObjectName("usagerecord");
174+
usageResponses.add(usageResponse);
175+
}
173176
}
174177

175-
response.setResponses(usageResponses, usageRecords.second());
178+
response.setResponses(usageResponses, usageResponses.size());
176179
}
177180

178181
response.setResponseName(getCommandName());

api/src/main/java/org/apache/cloudstack/api/command/user/network/UpdateNetworkCmd.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.user.network;
1818

19-
import org.apache.log4j.Logger;
20-
2119
import org.apache.cloudstack.acl.RoleType;
2220
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
2321
import org.apache.cloudstack.api.ACL;
@@ -31,16 +29,14 @@
3129
import org.apache.cloudstack.api.ServerApiException;
3230
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
3331
import org.apache.cloudstack.api.response.NetworkResponse;
34-
import org.apache.cloudstack.context.CallContext;
32+
import org.apache.log4j.Logger;
3533

3634
import com.cloud.event.EventTypes;
3735
import com.cloud.exception.ConcurrentOperationException;
3836
import com.cloud.exception.InsufficientCapacityException;
3937
import com.cloud.exception.InvalidParameterValueException;
4038
import com.cloud.network.Network;
4139
import com.cloud.offering.NetworkOffering;
42-
import com.cloud.user.Account;
43-
import com.cloud.user.User;
4440

4541
@APICommand(name = "updateNetwork", description = "Updates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class},
4642
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -159,17 +155,12 @@ public long getEntityOwnerId() {
159155

160156
@Override
161157
public void execute() throws InsufficientCapacityException, ConcurrentOperationException {
162-
User callerUser = _accountService.getActiveUser(CallContext.current().getCallingUserId());
163-
Account callerAccount = _accountService.getActiveAccountById(callerUser.getAccountId());
164158
Network network = _networkService.getNetwork(id);
165159
if (network == null) {
166160
throw new InvalidParameterValueException("Couldn't find network by ID");
167161
}
168162

169-
Network result =
170-
_networkService.updateGuestNetwork(getId(), getNetworkName(), getDisplayText(), callerAccount, callerUser, getNetworkDomain(), getNetworkOfferingId(),
171-
getChangeCidr(), getGuestVmCidr(), getDisplayNetwork(), getCustomId(), getUpdateInSequence(), getForced());
172-
163+
Network result = _networkService.updateGuestNetwork(this);
173164
if (result != null) {
174165
NetworkResponse response = _responseGenerator.createNetworkResponse(ResponseView.Restricted, result);
175166
response.setResponseName(getCommandName());

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
package org.apache.cloudstack.api.response;
1818

1919
import java.util.List;
20-
20+
import java.util.Map;
2121
import java.util.Set;
22+
2223
import org.apache.cloudstack.acl.RoleType;
2324
import org.apache.cloudstack.api.ApiConstants;
2425
import org.apache.cloudstack.api.BaseResponse;
@@ -201,6 +202,10 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes
201202
@Param(description = "the list of resource tags associated with network", responseObject = ResourceTagResponse.class)
202203
private List<ResourceTagResponse> tags;
203204

205+
@SerializedName(ApiConstants.DETAILS)
206+
@Param(description = "the details of the network")
207+
private Map<String, String> details;
208+
204209
@SerializedName(ApiConstants.IP6_GATEWAY)
205210
@Param(description = "the gateway of IPv6 network")
206211
private String ip6Gateway;
@@ -414,6 +419,10 @@ public void setTags(List<ResourceTagResponse> tags) {
414419
this.tags = tags;
415420
}
416421

422+
public void setDetails(Map<String, String> details) {
423+
this.details = details;
424+
}
425+
417426
public void setIp6Gateway(String ip6Gateway) {
418427
this.ip6Gateway = ip6Gateway;
419428
}

engine/schema/src/main/java/com/cloud/network/dao/NetworkDetailVO.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,12 @@ public long getResourceId() {
7979
public boolean isDisplay() {
8080
return display;
8181
}
82+
83+
public void setValue(String value) {
84+
this.value = value;
85+
}
86+
87+
public void setDisplay(boolean display) {
88+
this.display = display;
89+
}
8290
}

0 commit comments

Comments
 (0)