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


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/58772934
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/58772934
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/58772934

Branch: refs/heads/master
Commit: 58772934344d2b0316ddb479a977b15b6e97c015
Parents: 570b676
Author: Loic Lambiel <[email protected]>
Authored: Fri May 15 15:15:26 2015 +0200
Committer: Daan Hoogland <[email protected]>
Committed: Mon May 23 22:33:42 2016 +0200

----------------------------------------------------------------------
 .../api/command/user/vm/UpdateVMCmd.java        | 16 ++++++-
 server/src/com/cloud/vm/UserVmManager.java      |  2 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java  | 46 ++++++++++++++++++--
 3 files changed, 59 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/58772934/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java 
b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
index 458122d..9a8bdc2 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
@@ -29,6 +29,7 @@ import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ResponseObject.ResponseView;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.context.CallContext;
 
@@ -39,6 +40,7 @@ import com.cloud.uservm.UserVm;
 import com.cloud.vm.VirtualMachine;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 
 @APICommand(name = "updateVirtualMachine", description="Updates properties of 
a virtual machine. The VM has to be stopped and restarted for the " +
@@ -96,6 +98,14 @@ public class UpdateVMCmd extends BaseCustomIdCmd {
     @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, 
description = "Details in key/value pairs.")
     protected Map<String, String> details;
 
+    @ACL
+    @Parameter(name = ApiConstants.SECURITY_GROUP_IDS,
+               type = CommandType.LIST,
+               collectionType = CommandType.UUID,
+               entityType = SecurityGroupResponse.class,
+               description = "list of security group ids to be applied on the 
virtual machine.")
+    private List<Long> securityGroupIdList;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -145,7 +155,11 @@ public class UpdateVMCmd extends BaseCustomIdCmd {
         return (Map<String, String>) (paramsCollection.toArray())[0];
     }
 
-/////////////////////////////////////////////////////
+    public List<Long> getSecurityGroupIdList() {
+        return securityGroupIdList;
+    }
+
+    /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/58772934/server/src/com/cloud/vm/UserVmManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManager.java 
b/server/src/com/cloud/vm/UserVmManager.java
index fe0e98c..411fd9b 100644
--- a/server/src/com/cloud/vm/UserVmManager.java
+++ b/server/src/com/cloud/vm/UserVmManager.java
@@ -103,7 +103,7 @@ public interface UserVmManager extends UserVmService {
     void collectVmDiskStatistics(UserVmVO userVm);
 
     UserVm updateVirtualMachine(long id, String displayName, String group, 
Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
-                                Boolean isDynamicallyScalable, HTTPMethod 
httpMethod, String customId, String hostName, String instanceName) throws 
ResourceUnavailableException, InsufficientCapacityException;
+                                Boolean isDynamicallyScalable, HTTPMethod 
httpMethod, String customId, String hostName, String instanceName, List<Long> 
securityGroupIdList) throws ResourceUnavailableException, 
InsufficientCapacityException;
 
     //the validateCustomParameters, save and remove CustomOfferingDetils 
functions can be removed from the interface once we can
     //find a common place for all the scaling and upgrading code of both user 
and systemvms.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/58772934/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java 
b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 83ee248..a253fdd 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2289,6 +2289,7 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
         String hostName = cmd.getHostName();
         Map<String,String> details = cmd.getDetails();
         Account caller = CallContext.current().getCallingAccount();
+        List<Long> securityGroupIdList = cmd.getSecurityGroupIdList();
 
         // Input validation and permission checks
         UserVmVO vmInstance = _vmDao.findById(id);
@@ -2339,7 +2340,7 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
         }
 
         return updateVirtualMachine(id, displayName, group, ha, isDisplayVm, 
osTypeId, userData, isDynamicallyScalable,
-                cmd.getHttpMethod(), cmd.getCustomId(), hostName, 
cmd.getInstanceName());
+                cmd.getHttpMethod(), cmd.getCustomId(), hostName, 
cmd.getInstanceName(), securityGroupIdList);
     }
 
     private void saveUsageEvent(UserVmVO vm) {
@@ -2389,10 +2390,11 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
 
     @Override
     public UserVm updateVirtualMachine(long id, String displayName, String 
group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
-            Boolean isDynamicallyScalable, HTTPMethod httpMethod, String 
customId, String hostName, String instanceName) throws 
ResourceUnavailableException, InsufficientCapacityException {
+            Boolean isDynamicallyScalable, HTTPMethod httpMethod, String 
customId, String hostName, String instanceName, List<Long> securityGroupIdList)
+                    throws ResourceUnavailableException, 
InsufficientCapacityException {
         UserVmVO vm = _vmDao.findById(id);
         if (vm == null) {
-            throw new CloudRuntimeException("Unable to find virual machine 
with id " + id);
+            throw new CloudRuntimeException("Unable to find virtual machine 
with id " + id);
         }
 
         if(instanceName != null){
@@ -2451,6 +2453,44 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
             isDynamicallyScalable = vm.isDynamicallyScalable();
         }
 
+        boolean isVMware = (vm.getHypervisorType() == HypervisorType.VMware);
+
+        if (securityGroupIdList != null && isVMware) {
+            throw new InvalidParameterValueException("Security group feature 
is not supported for vmWare hypervisor");
+        } else {
+            // Get default guest network in Basic zone
+            Network defaultNetwork = null;
+            try {
+                DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
+
+                if (zone.getNetworkType() == NetworkType.Basic) {
+                    // Get default guest network in Basic zone
+                    defaultNetwork = 
_networkModel.getExclusiveGuestNetwork(zone.getId());
+                } else if (zone.isSecurityGroupEnabled()) {
+                    NicVO defaultNic = _nicDao.findDefaultNicForVM(vm.getId());
+                    if (defaultNic != null) {
+                        defaultNetwork = 
_networkDao.findById(defaultNic.getNetworkId());
+                    }
+                }
+            } catch (InvalidParameterValueException e) {
+                if(s_logger.isDebugEnabled()) {
+                    s_logger.debug(e.getMessage(),e);
+                }
+                defaultNetwork = _networkModel.getDefaultNetworkForVm(id);
+            }
+
+            if (securityGroupIdList != null && 
_networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork) && 
_networkModel.canAddDefaultSecurityGroup()) {
+                if (vm.getState() == State.Stopped) {
+                    // Remove instance from security groups
+                    _securityGroupMgr.removeInstanceFromGroups(id);
+                    // Add instance in provided groups
+                    _securityGroupMgr.addInstanceToGroups(id, 
securityGroupIdList);
+                } else {
+                    throw new InvalidParameterValueException("Virtual machine 
must be stopped prior to update security groups ");
+                }
+            }
+        }
+
         if (hostName != null) {
             // Check is hostName is RFC compliant
             checkNameForRFCCompliance(hostName);

Reply via email to