Skip to content

Commit c8d848d

Browse files
llambielDaanHoogland
authored andcommitted
CLOUDSTACK-9203 security group update on running instance
cherry-picked from a exoscale internal fix: Implement security group move on updateVM API call Prevent security group update while instance is running Conflicts: api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java server/src/com/cloud/vm/UserVmManager.java server/src/com/cloud/vm/UserVmManagerImpl.java
1 parent 570b676 commit c8d848d

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.cloudstack.api.ResponseObject.ResponseView;
3030
import org.apache.cloudstack.api.ServerApiException;
3131
import org.apache.cloudstack.api.response.GuestOSResponse;
32+
import org.apache.cloudstack.api.response.SecurityGroupResponse;
3233
import org.apache.cloudstack.api.response.UserVmResponse;
3334
import org.apache.cloudstack.context.CallContext;
3435

@@ -39,7 +40,9 @@
3940
import com.cloud.vm.VirtualMachine;
4041

4142
import java.util.Collection;
43+
import java.util.List;
4244
import java.util.Map;
45+
import java.util.List;
4346

4447
@APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " +
4548
"new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " +
@@ -96,6 +99,14 @@ public class UpdateVMCmd extends BaseCustomIdCmd {
9699
@Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Details in key/value pairs.")
97100
protected Map<String, String> details;
98101

102+
@ACL
103+
@Parameter(name = ApiConstants.SECURITY_GROUP_IDS,
104+
type = CommandType.LIST,
105+
collectionType = CommandType.UUID,
106+
entityType = SecurityGroupResponse.class,
107+
description = "list of security group ids to be applied on the virtual machine.")
108+
private List<Long> securityGroupIdList;
109+
99110
/////////////////////////////////////////////////////
100111
/////////////////// Accessors ///////////////////////
101112
/////////////////////////////////////////////////////
@@ -145,7 +156,11 @@ public Map<String, String> getDetails() {
145156
return (Map<String, String>) (paramsCollection.toArray())[0];
146157
}
147158

148-
/////////////////////////////////////////////////////
159+
public List<Long> getSecurityGroupIdList() {
160+
return securityGroupIdList;
161+
}
162+
163+
/////////////////////////////////////////////////////
149164
/////////////// API Implementation///////////////////
150165
/////////////////////////////////////////////////////
151166

server/src/com/cloud/vm/UserVmManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map<String, Strin
103103
void collectVmDiskStatistics(UserVmVO userVm);
104104

105105
UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
106-
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName) throws ResourceUnavailableException, InsufficientCapacityException;
106+
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName, List<Long> securityGroupIdList) throws ResourceUnavailableException, InsufficientCapacityException;
107107

108108
//the validateCustomParameters, save and remove CustomOfferingDetils functions can be removed from the interface once we can
109109
//find a common place for all the scaling and upgrading code of both user and systemvms.

server/src/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,6 +2289,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx
22892289
String hostName = cmd.getHostName();
22902290
Map<String,String> details = cmd.getDetails();
22912291
Account caller = CallContext.current().getCallingAccount();
2292+
List<Long> securityGroupIdList = cmd.getSecurityGroupIdList();
22922293

22932294
// Input validation and permission checks
22942295
UserVmVO vmInstance = _vmDao.findById(id);
@@ -2339,7 +2340,7 @@ public UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableEx
23392340
}
23402341

23412342
return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, osTypeId, userData, isDynamicallyScalable,
2342-
cmd.getHttpMethod(), cmd.getCustomId(), hostName, cmd.getInstanceName());
2343+
cmd.getHttpMethod(), cmd.getCustomId(), hostName, cmd.getInstanceName(), securityGroupIdList);
23432344
}
23442345

23452346
private void saveUsageEvent(UserVmVO vm) {
@@ -2389,7 +2390,8 @@ private void generateNetworkUsageForVm(VirtualMachine vm, boolean isDisplay, Str
23892390

23902391
@Override
23912392
public UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
2392-
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName) throws ResourceUnavailableException, InsufficientCapacityException {
2393+
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName, List<Long> securityGroupIdList)
2394+
throws ResourceUnavailableException, InsufficientCapacityException {
23932395
UserVmVO vm = _vmDao.findById(id);
23942396
if (vm == null) {
23952397
throw new CloudRuntimeException("Unable to find virual machine with id " + id);
@@ -2451,6 +2453,25 @@ public UserVm updateVirtualMachine(long id, String displayName, String group, Bo
24512453
isDynamicallyScalable = vm.isDynamicallyScalable();
24522454
}
24532455

2456+
// Get default guest network in Basic zone
2457+
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
2458+
Network defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
2459+
2460+
boolean isVMware = (vm.getHypervisorType() == HypervisorType.VMware);
2461+
2462+
if (securityGroupIdList != null && isVMware) {
2463+
throw new InvalidParameterValueException("Security group feature is not supported for vmWare hypervisor");
2464+
} else if (securityGroupIdList != null && _networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && _networkModel.canAddDefaultSecurityGroup()) {
2465+
if (vm.getState() == State.Stopped) {
2466+
// Remove instance from security groups
2467+
_securityGroupMgr.removeInstanceFromGroups(id);
2468+
// Add instance in provided groups
2469+
_securityGroupMgr.addInstanceToGroups(id, securityGroupIdList);
2470+
} else {
2471+
throw new InvalidParameterValueException("Virtual machine must be stopped prior to update security groups ");
2472+
}
2473+
}
2474+
24542475
if (hostName != null) {
24552476
// Check is hostName is RFC compliant
24562477
checkNameForRFCCompliance(hostName);

0 commit comments

Comments
 (0)