incubator-cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mlsoren...@apache.org
Subject [4/52] [partial] Summary: Fixes for api_refactoring
Date Thu, 10 Jan 2013 00:48:37 GMT
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
new file mode 100644
index 0000000..349f4a1
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
@@ -0,0 +1,464 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.api.*;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.SecurityGroupResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+
+@APICommand(name = "deployVirtualMachine", description="Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject=UserVmResponse.class)
+public class DeployVMCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName());
+
+    private static final String s_name = "deployvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
+            required=true, description="availability zone for the virtual machine")
+    private Long zoneId;
+
+    @ACL
+    @Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=ServiceOfferingResponse.class,
+            required=true, description="the ID of the service offering for the virtual machine")
+    private Long serviceOfferingId;
+
+    @ACL
+    @Parameter(name=ApiConstants.TEMPLATE_ID, type=CommandType.UUID, entityType=TemplateResponse.class,
+            required=true, description="the ID of the template for the virtual machine")
+    private Long templateId;
+
+    @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="host name for the virtual machine")
+    private String name;
+
+    @Parameter(name=ApiConstants.DISPLAY_NAME, type=CommandType.STRING, description="an optional user generated name for the virtual machine")
+    private String displayName;
+
+    //Owner information
+    @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the virtual machine. Must be used with domainId.")
+    private String accountName;
+
+    @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+            description="an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.")
+    private Long domainId;
+
+    //Network information
+    @ACL
+    @Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=NetworkResponse.class,
+            description="list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter")
+    private List<Long> networkIds;
+
+    //DataDisk information
+    @ACL
+    @Parameter(name=ApiConstants.DISK_OFFERING_ID, type=CommandType.UUID, entityType=DiskOfferingResponse.class,
+            description="the ID of the disk offering for the virtual machine. If the template is of ISO format," +
+                    " the diskOfferingId is for the root disk volume. Otherwise this parameter is used to indicate the " +
+                    "offering for the data disk volume. If the templateId parameter passed is from a Template object," +
+                    " the diskOfferingId refers to a DATA Disk Volume created. If the templateId parameter passed is " +
+                    "from an ISO object, the diskOfferingId refers to a ROOT Disk Volume created.")
+    private Long diskOfferingId;
+
+    @Parameter(name=ApiConstants.SIZE, type=CommandType.LONG, description="the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId")
+    private Long size;
+
+    @Parameter(name=ApiConstants.GROUP, type=CommandType.STRING, description="an optional group for the virtual machine")
+    private String group;
+
+    @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, description="the hypervisor on which to deploy the virtual machine")
+    private String hypervisor;
+
+    @Parameter(name=ApiConstants.USER_DATA, type=CommandType.STRING, description="an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Currently only HTTP GET is supported. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding.", length=2048)
+    private String userData;
+
+    @Parameter(name=ApiConstants.SSH_KEYPAIR, type=CommandType.STRING, description="name of the ssh key pair used to login to the virtual machine")
+    private String sshKeyPairName;
+
+    @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
+            description="destination Host ID to deploy the VM to - parameter available for root admin only")
+    private Long hostId;
+
+    @ACL
+    @Parameter(name=ApiConstants.SECURITY_GROUP_IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=SecurityGroupResponse.class,
+            description="comma separated list of security groups id that going to be applied to the virtual machine. " +
+                    "Should be passed only when vm is created from a zone with Basic Network support." +
+                    " Mutually exclusive with securitygroupnames parameter")
+    private List<Long> securityGroupIdList;
+
+    @ACL
+    @Parameter(name=ApiConstants.SECURITY_GROUP_NAMES, type=CommandType.LIST, collectionType=CommandType.STRING, entityType=SecurityGroupResponse.class,
+            description="comma separated list of security groups names that going to be applied to the virtual machine." +
+                    " Should be passed only when vm is created from a zone with Basic Network support. " +
+                    "Mutually exclusive with securitygroupids parameter")
+    private List<String> securityGroupNameList;
+
+    @ACL(checkKeyAccess=true)
+    @Parameter(name = ApiConstants.IP_NETWORK_LIST, type = CommandType.MAP, entityType={Network.class,IpAddress.class},
+            description = "ip to network mapping. Can't be specified with networkIds parameter." +
+                    " Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].networkid=204 - requests to" +
+                    " use ip 10.10.10.11 in network id=204")
+    private Map ipToNetworkList;
+
+    @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="the ip address for default vm's network")
+    private String ipAddress;
+
+    @Parameter(name=ApiConstants.KEYBOARD, type=CommandType.STRING, description="an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us")
+    private String keyboard;
+
+    @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType=ProjectResponse.class,
+            description="Deploy vm for the project")
+    private Long projectId;
+
+    @Parameter(name=ApiConstants.START_VM, type=CommandType.BOOLEAN, description="true if network offering supports specifying ip ranges; defaulted to true if not specified")
+    private Boolean startVm;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getEntityTable() {
+        return "vm_instance";
+    }
+
+    public String getAccountName() {
+        if (accountName == null) {
+            return UserContext.current().getCaller().getAccountName();
+        }
+        return accountName;
+    }
+
+    public Long getDiskOfferingId() {
+        return diskOfferingId;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public Long getDomainId() {
+        if (domainId == null) {
+            return UserContext.current().getCaller().getDomainId();
+        }
+        return domainId;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public HypervisorType getHypervisor() {
+        return HypervisorType.getType(hypervisor);
+    }
+
+    public List<Long> getSecurityGroupIdList() {
+        if (securityGroupNameList != null && securityGroupIdList != null) {
+            throw new InvalidParameterValueException("securitygroupids parameter is mutually exclusive with securitygroupnames parameter");
+        }
+
+       //transform group names to ids here
+       if (securityGroupNameList != null) {
+            List<Long> securityGroupIds = new ArrayList<Long>();
+            for (String groupName : securityGroupNameList) {
+                Long groupId = _responseGenerator.getSecurityGroupId(groupName, getEntityOwnerId());
+                if (groupId == null) {
+                    throw new InvalidParameterValueException("Unable to find group by name " + groupName + " for account " + getEntityOwnerId());
+                } else {
+                    securityGroupIds.add(groupId);
+                }
+            }
+            return securityGroupIds;
+        } else {
+            return securityGroupIdList;
+        }
+    }
+
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    public Long getTemplateId() {
+        return templateId;
+    }
+
+    public String getUserData() {
+        return userData;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public List<Long> getNetworkIds() {
+       if (ipToNetworkList != null) {
+           if (networkIds != null || ipAddress != null) {
+               throw new InvalidParameterValueException("ipToNetworkMap can't be specified along with networkIds or ipAddress");
+           } else {
+               List<Long> networks = new ArrayList<Long>();
+               networks.addAll(getIpToNetworkMap().keySet());
+               return networks;
+           }
+       }
+        return networkIds;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getSSHKeyPairName() {
+        return sshKeyPairName;
+    }
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    public boolean getStartVm() {
+        return startVm == null ? true : startVm;
+    }
+
+    private Map<Long, String> getIpToNetworkMap() {
+        if ((networkIds != null || ipAddress != null) && ipToNetworkList != null) {
+            throw new InvalidParameterValueException("NetworkIds and ipAddress can't be specified along with ipToNetworkMap parameter");
+        }
+        LinkedHashMap<Long, String> ipToNetworkMap = null;
+        if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
+            ipToNetworkMap = new LinkedHashMap<Long, String>();
+            Collection ipsCollection = ipToNetworkList.values();
+            Iterator iter = ipsCollection.iterator();
+            while (iter.hasNext()) {
+                HashMap<String, String> ips = (HashMap<String, String>) iter.next();
+                Long networkId = Long.valueOf(_responseGenerator.getIdentiyId("networks", ips.get("networkid")));
+                String requestedIp = (String) ips.get("ip");
+                ipToNetworkMap.put(networkId, requestedIp);
+            }
+        }
+
+        return ipToNetworkMap;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return UserContext.current().getCaller().getId();
+        }
+
+        return accountId;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_CREATE;
+    }
+
+    @Override
+    public String getCreateEventType() {
+        return EventTypes.EVENT_VM_CREATE;
+    }
+
+    @Override
+    public String getCreateEventDescription() {
+        return "creating Vm";
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "starting Vm. Vm Id: "+getEntityId();
+    }
+
+    @Override
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.VirtualMachine;
+    }
+
+    @Override
+    public void execute(){
+        UserVm result;
+
+        if (getStartVm()) {
+            try {
+                UserContext.current().setEventDetails("Vm Id: "+getEntityId());
+                if (getHypervisor() == HypervisorType.BareMetal) {
+                    result = _bareMetalVmService.startVirtualMachine(this);
+                } else {
+                    result = _userVmService.startVirtualMachine(this);
+                }
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Exception: ", ex);
+                throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+            } catch (ConcurrentOperationException ex) {
+                s_logger.warn("Exception: ", ex);
+                throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
+            } catch (InsufficientCapacityException ex) {
+                s_logger.info(ex);
+                s_logger.trace(ex);
+                throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
+            }
+        } else {
+            result = _userVmService.getUserVm(getEntityId());
+        }
+
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy vm");
+        }
+    }
+
+    @Override
+    public void create() throws ResourceAllocationException{
+        try {
+            //Verify that all objects exist before passing them to the service
+            Account owner = _accountService.getActiveAccountById(getEntityOwnerId());
+
+            DataCenter zone = _configService.getZone(zoneId);
+            if (zone == null) {
+                throw new InvalidParameterValueException("Unable to find zone by id=" + zoneId);
+            }
+
+            ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId);
+            if (serviceOffering == null) {
+                throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+            }
+
+            VirtualMachineTemplate template = _templateService.getTemplate(templateId);
+            // Make sure a valid template ID was specified
+            if (template == null) {
+                throw new InvalidParameterValueException("Unable to use template " + templateId);
+            }
+
+            DiskOffering diskOffering = null;
+            if (diskOfferingId != null) {
+                diskOffering = _configService.getDiskOffering(diskOfferingId);
+                if (diskOffering == null) {
+                    throw new InvalidParameterValueException("Unable to find disk offering " + diskOfferingId);
+                }
+            }
+
+            if (!zone.isLocalStorageEnabled()) {
+                if (serviceOffering.getUseLocalStorage()) {
+                    throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it");
+                }
+                if (diskOffering != null && diskOffering.getUseLocalStorage()) {
+                    throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " uses it");
+                }
+            }
+
+            UserVm vm = null;
+            if (getHypervisor() == HypervisorType.BareMetal) {
+                vm = _bareMetalVmService.createVirtualMachine(this);
+            } else {
+                if (zone.getNetworkType() == NetworkType.Basic) {
+                    if (getNetworkIds() != null) {
+                        throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
+                    } else {
+                        vm = _userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(), owner, name,
+                                displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard);
+                    }
+                } else {
+                    if (zone.isSecurityGroupEnabled())  {
+                        vm = _userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, getNetworkIds(), getSecurityGroupIdList(),
+                                owner, name, displayName, diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard);
+                    } else {
+                        if (getSecurityGroupIdList() != null && !getSecurityGroupIdList().isEmpty()) {
+                            throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
+                        }
+                        vm = _userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, getNetworkIds(), owner, name, displayName,
+                                diskOfferingId, size, group, getHypervisor(), userData, sshKeyPairName, getIpToNetworkMap(), ipAddress, keyboard);
+                    }
+                }
+            }
+
+            if (vm != null) {
+                setEntityId(vm.getId());
+            } else {
+                throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy vm");
+            }
+        } catch (InsufficientCapacityException ex) {
+            s_logger.info(ex);
+            s_logger.trace(ex);
+            throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        }  catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
new file mode 100644
index 0000000..db830d1
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/DestroyVMCmd.java
@@ -0,0 +1,110 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.cloudstack.api.*;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "destroyVirtualMachine", description="Destroys a virtual machine. Once destroyed, only the administrator can recover it.", responseObject=UserVmResponse.class)
+public class DestroyVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(DestroyVMCmd.class.getName());
+
+    private static final String s_name = "destroyvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_DESTROY;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "destroying vm: " + getId();
+    }
+
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.VirtualMachine;
+    }
+
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ConcurrentOperationException{
+        UserContext.current().setEventDetails("Vm Id: "+getId());
+        UserVm result;
+        if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
+            result = _bareMetalVmService.destroyVm(this);
+        } else {
+            result = _userVmService.destroyVm(this);
+        }
+
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName("virtualmachine");
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to destroy vm");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java
new file mode 100644
index 0000000..cd3a560
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/GetVMPasswordCmd.java
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.security.InvalidParameterException;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.GetVMPasswordResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.user.Account;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "getVMPassword", responseObject=GetVMPasswordResponse.class, description="Returns an encrypted password for the VM")
+public class GetVMPasswordCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(GetVMPasswordCmd.class.getName());
+    private static final String s_name = "getvmpasswordresponse";
+
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class
+            , required=true, description="The ID of the virtual machine")
+    private Long id;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public void execute() {
+        String passwd = _mgr.getVMPassword(this);
+        if (passwd == null || passwd.equals(""))
+            throw new InvalidParameterException("No password for VM with id '" + getId() + "' found.");
+
+        this.setResponseObject(new GetVMPasswordResponse(getCommandName(), passwd));
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
new file mode 100644
index 0000000..b74c8e7
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
@@ -0,0 +1,218 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiConstants.VMDetails;
+import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.Parameter;
+
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.IsoVmResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.PodResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.async.AsyncJob;
+import com.cloud.exception.InvalidParameterValueException;
+
+
+@APICommand(name = "listVirtualMachines", description="List the virtual machines owned by the account.", responseObject=UserVmResponse.class)
+public class ListVMsCmd extends BaseListTaggedResourcesCmd {
+    public static final Logger s_logger = Logger.getLogger(ListVMsCmd.class.getName());
+
+    private static final String s_name = "listvirtualmachinesresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.GROUP_ID, type=CommandType.UUID, entityType=InstanceGroupResponse.class,
+            description="the group ID")
+    private Long groupId;
+
+    @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
+            description="the host ID")
+    private Long hostId;
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            description="the ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="name of the virtual machine")
+    private String instanceName;
+
+    @Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
+            description="the pod ID")
+    private Long podId;
+
+    @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="state of the virtual machine")
+    private String state;
+
+    @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class,
+            description="the availability zone ID")
+    private Long zoneId;
+
+    @Parameter(name=ApiConstants.FOR_VIRTUAL_NETWORK, type=CommandType.BOOLEAN,
+            description="list by network type; true if need to list vms using Virtual Network, false otherwise")
+    private Boolean forVirtualNetwork;
+
+    @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class,
+            description="list by network id")
+    private Long networkId;
+
+    @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, description="the target hypervisor for the template")
+    private String hypervisor;
+
+    @Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class,
+            description="the storage ID where vm's volumes belong to")
+    private Long storageId;
+
+    @Parameter(name=ApiConstants.DETAILS, type=CommandType.LIST, collectionType=CommandType.STRING,
+            description="comma separated list of host details requested, " +
+            "value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, iso, volume, min]." +
+                    " If no parameter is passed in, the details will be defaulted to all" )
+    private List<String> viewDetails;
+
+    @Parameter(name=ApiConstants.TEMPLATE_ID, type=CommandType.UUID, entityType=TemplateResponse.class,
+            description="list vms by template")
+    private Long templateId;
+
+    @Parameter(name=ApiConstants.ISO_ID, type=CommandType.UUID, entityType=IsoVmResponse.class,
+            description="list vms by iso")
+    private Long isoId;
+
+    @Parameter(name=ApiConstants.VPC_ID, type=CommandType.UUID, entityType=VpcResponse.class,
+            description="list vms by vpc")
+    private Long vpcId;
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getGroupId() {
+        return groupId;
+    }
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getInstanceName() {
+        return instanceName;
+    }
+
+    public Long getPodId() {
+        return podId;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public Long getZoneId() {
+        return zoneId;
+    }
+
+    public Boolean getForVirtualNetwork() {
+        return forVirtualNetwork;
+    }
+
+    public void setForVirtualNetwork(Boolean forVirtualNetwork) {
+        this.forVirtualNetwork = forVirtualNetwork;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public String getHypervisor() {
+        return hypervisor;
+    }
+
+    public Long getStorageId() {
+        return storageId;
+    }
+
+    public Long getTemplateId() {
+        return templateId;
+    }
+
+    public Long getIsoId() {
+        return isoId;
+    }
+
+    public Long getVpcId(){
+        return vpcId;
+    }
+
+    public EnumSet<VMDetails> getDetails() throws InvalidParameterValueException {
+        EnumSet<VMDetails> dv;
+        if (viewDetails==null || viewDetails.size() <=0){
+            dv = EnumSet.of(VMDetails.all);
+        }
+        else {
+            try {
+                ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
+                for (String detail: viewDetails){
+                    dc.add(VMDetails.valueOf(detail));
+                }
+                dv = EnumSet.copyOf(dc);
+            }
+            catch (IllegalArgumentException e){
+                throw new InvalidParameterValueException("The details parameter contains a non permitted value. The allowed values are " + EnumSet.allOf(VMDetails.class));
+            }
+        }
+        return dv;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.VirtualMachine;
+    }
+
+    @Override
+    public void execute(){
+        ListResponse<UserVmResponse> response = _queryService.searchForUserVMs(this);
+        response.setResponseName(getCommandName());
+        this.setResponseObject(response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java
new file mode 100644
index 0000000..45ebc28
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/RebootVMCmd.java
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "rebootVirtualMachine", description="Reboots a virtual machine.", responseObject=UserVmResponse.class)
+public class RebootVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RebootVMCmd.class.getName());
+    private static final String s_name = "rebootvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_REBOOT;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "rebooting user vm: " + getId();
+    }
+
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.VirtualMachine;
+    }
+
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException{
+        UserContext.current().setEventDetails("Vm Id: "+getId());
+        UserVm result;
+        if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
+            result = _bareMetalVmService.rebootVirtualMachine(this);
+        } else {
+            result = _userVmService.rebootVirtualMachine(this);
+        }
+
+        if (result !=null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to reboot vm instance");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java
new file mode 100644
index 0000000..a4c2b37
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/ResetVMPasswordCmd.java
@@ -0,0 +1,122 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "resetPasswordForVirtualMachine", responseObject=UserVmResponse.class, description="Resets the password for virtual machine. " +
+                    "The virtual machine must be in a \"Stopped\" state and the template must already " +
+                    "support this feature for this command to take effect. [async]")
+public class ResetVMPasswordCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(ResetVMPasswordCmd.class.getName());
+
+    private static final String s_name = "resetpasswordforvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    // unexposed parameter needed for serializing/deserializing the command
+    @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, expose=false)
+    private String password;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_RESETPASSWORD;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return  "resetting password for vm: " + getId();
+    }
+
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.VirtualMachine;
+    }
+
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException{
+        password = _mgr.generateRandomPassword();
+        UserContext.current().setEventDetails("Vm Id: "+getId());
+        UserVm result = _userVmService.resetVMPassword(this, password);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to reset vm password");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
new file mode 100644
index 0000000..9b2452e
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/RestoreVMCmd.java
@@ -0,0 +1,88 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "restoreVirtualMachine", description="Restore a VM to original template or specific snapshot", responseObject=UserVmResponse.class, since="3.0.0")
+public class RestoreVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(RestoreVMCmd.class);
+    private static final String s_name = "restorevmresponse";
+
+    @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="Virtual Machine ID")
+    private Long vmId;
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_RESTORE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Restore a VM to orignal template or specific snapshot";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+            ResourceAllocationException {
+        UserVm result;
+        UserContext.current().setEventDetails("Vm Id: " + getVmId());
+        result = _userVmService.restoreVM(this);
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to restore vm " + getVmId());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getVmId());
+        if (vm == null) {
+             return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
+        }
+        return vm.getAccountId();
+    }
+
+    public long getVmId() {
+        return vmId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java
new file mode 100644
index 0000000..36199d1
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/StartVMCmd.java
@@ -0,0 +1,142 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.cloudstack.api.*;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.exception.ExecutionException;
+
+@APICommand(name = "startVirtualMachine", responseObject = UserVmResponse.class, description = "Starts a virtual machine.")
+public class StartVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StartVMCmd.class.getName());
+
+    private static final String s_name = "startvirtualmachineresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
+            required = true, description = "The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
+            description="destination Host ID to deploy the VM to - parameter available for root admin only", since="3.0.1")
+    private Long hostId;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getHostId() {
+        return hostId;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
+        // tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_START;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "starting user vm: " + getId();
+    }
+
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.VirtualMachine;
+    }
+
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException {
+        try {
+            UserContext.current().setEventDetails("Vm Id: " + getId());
+
+            UserVm result ;
+            if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
+                result = _bareMetalVmService.startVirtualMachine(this);
+            } else {
+                result = _userVmService.startVirtualMachine(this);
+            }
+
+            if (result != null) {
+                UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            } else {
+                throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to start a vm");
+            }
+        } catch (ConcurrentOperationException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
+        } catch (StorageUnavailableException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
+        } catch (ExecutionException ex) {
+            s_logger.warn("Exception: ", ex);
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java
new file mode 100644
index 0000000..8e58906
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/StopVMCmd.java
@@ -0,0 +1,126 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.cloudstack.api.*;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "stopVirtualMachine", responseObject = UserVmResponse.class, description = "Stops a virtual machine.")
+public class StopVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StopVMCmd.class.getName());
+
+    private static final String s_name = "stopvirtualmachineresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @ACL
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType=UserVmResponse.class,
+            required = true, description = "The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM " +
+            "(vm is marked as Stopped even when command fails to be send to the backend).  The caller knows the VM is stopped.")
+    private Boolean forced;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm vm = _responseGenerator.findUserVmById(getId());
+        if (vm != null) {
+            return vm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are
+// tracked
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_STOP;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "stopping user vm: " + getId();
+    }
+
+    @Override
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.VirtualMachine;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return getId();
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    @Override
+    public void execute() throws ServerApiException, ConcurrentOperationException {
+        UserContext.current().setEventDetails("Vm Id: " + getId());
+        UserVm result;
+
+        if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
+            result = _bareMetalVmService.stopVirtualMachine(getId(), isForced());
+        } else {
+            result = _userVmService.stopVirtualMachine(getId(), isForced());
+        }
+
+        if (result != null) {
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to stop vm");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/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
new file mode 100644
index 0000000..7f1e7ef
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
@@ -0,0 +1,132 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+
+@APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " +
+        "new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. " +
+        "Therefore, stop the VM manually before issuing this call.", responseObject=UserVmResponse.class)
+public class UpdateVMCmd extends BaseCmd{
+    public static final Logger s_logger = Logger.getLogger(UpdateVMCmd.class.getName());
+    private static final String s_name = "updatevirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.DISPLAY_NAME, type=CommandType.STRING, description="user generated name")
+    private String displayName;
+
+    @Parameter(name=ApiConstants.GROUP, type=CommandType.STRING, description="group of the virtual machine")
+    private String group;
+
+    @Parameter(name=ApiConstants.HA_ENABLE, type=CommandType.BOOLEAN, description="true if high-availability is enabled for the virtual machine, false otherwise")
+    private Boolean haEnable;
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name=ApiConstants.OS_TYPE_ID, type=CommandType.UUID, entityType=GuestOSResponse.class,
+            description="the ID of the OS type that best represents this VM.")
+    private Long osTypeId;
+
+    @Parameter(name=ApiConstants.USER_DATA, type=CommandType.STRING, description="an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Currently only HTTP GET is supported. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding.", length=2048)
+    private String userData;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public Boolean getHaEnable() {
+        return haEnable;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getUserData() {
+        return userData;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException,
+            InsufficientCapacityException, ServerApiException {
+        UserContext.current().setEventDetails("Vm Id: "+getId());
+        UserVm result = _userVmService.updateVirtualMachine(this);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update vm");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
new file mode 100644
index 0000000..f2c3882
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpgradeVMCmd.java
@@ -0,0 +1,104 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vm;
+
+import org.apache.cloudstack.api.*;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+
+import org.apache.cloudstack.api.response.DiskOfferingResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.uservm.UserVm;
+
+@APICommand(name = "changeServiceForVirtualMachine", responseObject=UserVmResponse.class, description="Changes the service offering for a virtual machine. " +
+                                            "The virtual machine must be in a \"Stopped\" state for " +
+                                            "this command to take effect.")
+public class UpgradeVMCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(UpgradeVMCmd.class.getName());
+    private static final String s_name = "changeserviceforvirtualmachineresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=UserVmResponse.class,
+            required=true, description="The ID of the virtual machine")
+    private Long id;
+
+    @Parameter(name=ApiConstants.SERVICE_OFFERING_ID, type=CommandType.UUID, entityType=DiskOfferingResponse.class,
+            required=true, description="the service offering ID to apply to the virtual machine")
+    private Long serviceOfferingId;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    public static String getResultObjectName() {
+        return "virtualmachine";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
+        if (userVm != null) {
+            return userVm.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute(){
+        UserContext.current().setEventDetails("Vm Id: "+getId());
+
+        ServiceOffering serviceOffering = _configService.getServiceOffering(serviceOfferingId);
+        if (serviceOffering == null) {
+            throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId);
+        }
+
+        UserVm result = _userVmService.upgradeVirtualMachine(this);
+        if (result != null){
+            UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to upgrade vm");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
new file mode 100644
index 0000000..9c2c602
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/CreateVMGroupCmd.java
@@ -0,0 +1,105 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vmgroup;
+
+import org.apache.cloudstack.api.*;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.ProjectAccountResponse;
+import com.cloud.user.UserContext;
+import com.cloud.vm.InstanceGroup;
+
+@APICommand(name = "createInstanceGroup", description = "Creates a vm group", responseObject = InstanceGroupResponse.class)
+public class CreateVMGroupCmd extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateVMGroupCmd.class.getName());
+
+    private static final String s_name = "createinstancegroupresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the instance group")
+    private String groupName;
+
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING,
+            description = "the account of the instance group. The account parameter must be used with the domainId parameter.")
+    private String accountName;
+
+    @Parameter(name = ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+            description = "the domain ID of account owning the instance group")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType=ProjectAccountResponse.class,
+            description = "The project of the instance group")
+    private Long projectId;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public Long getDomainId() {
+        return domainId;
+    }
+
+    public Long getProjectId() {
+        return projectId;
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return UserContext.current().getCaller().getId();
+        }
+
+        return accountId;
+    }
+
+    @Override
+    public void execute() {
+        InstanceGroup result = _userVmService.createVmGroup(this);
+        if (result != null) {
+            InstanceGroupResponse response = _responseGenerator.createInstanceGroupResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create vm instance group");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java
new file mode 100644
index 0000000..47c2f76
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/DeleteVMGroupCmd.java
@@ -0,0 +1,79 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vmgroup;
+
+import org.apache.cloudstack.api.*;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import com.cloud.user.Account;
+import com.cloud.vm.InstanceGroup;
+
+@APICommand(name = "deleteInstanceGroup", description="Deletes a vm group", responseObject=SuccessResponse.class)
+public class DeleteVMGroupCmd extends BaseCmd{
+    public static final Logger s_logger = Logger.getLogger(DeleteVMGroupCmd.class.getName());
+    private static final String s_name = "deleteinstancegroupresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=InstanceGroupResponse.class,
+            required=true, description="the ID of the instance group")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        InstanceGroup group = _entityMgr.findById(InstanceGroup.class, getId());
+        if (group != null) {
+            return group.getAccountId();
+        }
+
+        return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+    }
+
+    @Override
+    public void execute(){
+        boolean result = _userVmService.deleteVmGroup(this);
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete vm group");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c4c9d2d8/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java
new file mode 100644
index 0000000..8a581b0
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/user/vmgroup/ListVMGroupsCmd.java
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.vmgroup;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.InstanceGroupResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+
+@APICommand(name = "listInstanceGroups", description="Lists vm groups", responseObject=InstanceGroupResponse.class)
+public class ListVMGroupsCmd extends BaseListProjectAndAccountResourcesCmd {
+    public static final Logger s_logger = Logger.getLogger(ListVMGroupsCmd.class.getName());
+
+    private static final String s_name = "listinstancegroupsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=InstanceGroupResponse.class,
+            description="list instance groups by ID")
+    private Long id;
+
+    @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list instance groups by name")
+    private String groupName;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute(){
+        ListResponse<InstanceGroupResponse> response = _queryService.searchForVmGroups(this);
+        response.setResponseName(getCommandName());
+        this.setResponseObject(response);
+    }
+}


Mime
View raw message