From 335aca3f549d56b19e39d08f3107b9eb13b8ae52 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Sun, 28 Apr 2013 10:28:31 +0530 Subject: [PATCH] =changes #2 --- api/src/com/cloud/event/EventTypes.java | 4 + .../com/cloud/storage/VolumeApiService.java | 2 + .../apache/cloudstack/api/ApiConstants.java | 1 + .../command/user/network/AddNicDetailCmd.java | 9 +- .../user/network/ListNicDetailsCmd.java | 77 ++++++ .../user/network/RemoveNicDetailCmd.java | 6 +- .../user/volume/ListVolumeDetailCmd.java | 11 - .../user/volume/ListVolumeDetailsCmd.java | 2 +- .../command/user/volume/UpdateVolumeCmd.java | 31 +-- .../api/response/NicDetailResponse.java | 81 +++++++ .../api/response/VolumeDetailResponse.java | 2 +- .../apache/cloudstack/query/QueryService.java | 4 +- client/tomcatconf/commands.properties.in | 16 +- .../com/cloud/api/query/QueryManagerImpl.java | 36 ++- .../cloud/server/ManagementServerImpl.java | 2 + .../com/cloud/storage/VolumeManagerImpl.java | 20 ++ .../src/com/cloud/vm/UserVmManagerImpl.java | 14 +- server/src/com/cloud/vm/dao/NicDetailDao.java | 3 +- .../com/cloud/vm/dao/NicDetailDaoImpl.java | 11 +- test/integration/smoke/test_nicdetail.py | 224 ++++++++++++++++++ 20 files changed, 494 insertions(+), 62 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/command/user/network/ListNicDetailsCmd.java delete mode 100644 api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailCmd.java create mode 100644 api/src/org/apache/cloudstack/api/response/NicDetailResponse.java create mode 100644 test/integration/smoke/test_nicdetail.py diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 7737089f99b..afa441ebdde 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -103,6 +103,10 @@ public class EventTypes { public static final String EVENT_NIC_CREATE = "NIC.CREATE"; public static final String EVENT_NIC_DELETE = "NIC.DELETE"; public static final String EVENT_NIC_UPDATE = "NIC.UPDATE"; + public static final String EVENT_NIC_DETAIL_ADD = "NIC.DETAIL.ADD"; + public static final String EVENT_NIC_DETAIL_UPDATE = "NIC.DETAIL.UPDATE"; + public static final String EVENT_NIC_DETAIL_REMOVE = "NIC.DETAIL.REMOVE"; + // Load Balancers public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE"; diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 1f70c5b4e54..047d1242d7a 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -80,4 +80,6 @@ public interface VolumeApiService { void removeVolumeDetail(RemoveVolumeDetailCmd removeVolumeDetailCmd); void addVolumeDetail(AddVolumeDetailCmd addVolumeDetailCmd); + + Volume updateVolume(UpdateVolumeCmd updateVolumeCmd); } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 8ff4b0b44ac..4eca1c46c8f 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -57,6 +57,7 @@ public class ApiConstants { public static final String DISK_SIZE = "disksize"; public static final String DISPLAY_NAME = "displayname"; public static final String DISPLAY_NETWORK = "displaynetwork"; + public static final String DISPLAY_NIC = "displaynic"; public static final String DISPLAY_TEXT = "displaytext"; public static final String DISPLAY_VM = "displayvm"; public static final String DISPLAY_OFFERING = "displayoffering"; diff --git a/api/src/org/apache/cloudstack/api/command/user/network/AddNicDetailCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/AddNicDetailCmd.java index e5f7a0e80eb..230cd7e4163 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/AddNicDetailCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/AddNicDetailCmd.java @@ -91,16 +91,13 @@ public class AddNicDetailCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { - Volume volume = _responseGenerator.findVolumeById(getId()); - if (volume == null) { - return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked - } - return volume.getAccountId(); + Account caller = UserContext.current().getCaller(); + return caller.getAccountId(); } @Override public String getEventType() { - return EventTypes.EVENT_VOLUME_ATTACH; + return EventTypes.EVENT_NIC_CREATE; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNicDetailsCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNicDetailsCmd.java new file mode 100644 index 00000000000..84f3589efda --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNicDetailsCmd.java @@ -0,0 +1,77 @@ +// 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.network; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.*; +import org.apache.log4j.Logger; + +import java.util.List; + + +@APICommand(name = "listNicDetails", description="Lists all nic details.", responseObject=NicDetailResponse.class) +public class ListNicDetailsCmd extends BaseListTaggedResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListNicDetailsCmd.class.getName()); + + private static final String s_name = "listnicdetailsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=NicResponse.class, + required=true, description="the ID of the nic") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the nic detail") + private String name; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + + + @Override + public void execute(){ + ListResponse responses = new ListResponse(); + List nicDetailList = _queryService.searchForNicDetails(this); + responses.setResponses(nicDetailList); + responses.setResponseName(getCommandName()); + this.setResponseObject(responses); + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/network/RemoveNicDetailCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/RemoveNicDetailCmd.java index fe7503f57ee..abea5152dd2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/RemoveNicDetailCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/RemoveNicDetailCmd.java @@ -48,11 +48,11 @@ public class RemoveNicDetailCmd extends BaseAsyncCmd { private Long id; @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, - required=true, description="the name of the field") + required=false, description="the name of the field") private String name; @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, - required=true, description="the value of the field") + required=false, description="the value of the field") private String value; ///////////////////////////////////////////////////// @@ -100,7 +100,7 @@ public class RemoveNicDetailCmd extends BaseAsyncCmd { @Override public String getEventType() { - return EventTypes.EVENT_VOLUME_ATTACH; + return EventTypes.EVENT_NIC_DETAIL_REMOVE; } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailCmd.java deleted file mode 100644 index db53eb4a0b9..00000000000 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailCmd.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.apache.cloudstack.api.command.user.volume; - -/** - * Created with IntelliJ IDEA. - * User: nitinmehta - * Date: 24/04/13 - * Time: 5:18 PM - * To change this template use File | Settings | File Templates. - */ -public class ListVolumeDetailCmd { -} diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailsCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailsCmd.java index a0424b6957a..fc064cca1d6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ListVolumeDetailsCmd.java @@ -30,7 +30,7 @@ import java.util.List; @APICommand(name = "listVolumeDetails", description="Lists all volume details.", responseObject=VolumeDetailResponse.class) public class ListVolumeDetailsCmd extends BaseListTaggedResourcesCmd { - public static final Logger s_logger = Logger.getLogger(ListVolumesCmd.class.getName()); + public static final Logger s_logger = Logger.getLogger(ListVolumeDetailsCmd.class.getName()); private static final String s_name = "listvolumedetailsresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java index 1f35a432848..3453eef9187 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/UpdateVolumeCmd.java @@ -32,10 +32,10 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; import com.cloud.user.UserContext; -@APICommand(name = "updateVolumeDetail", description="Updates the volume.", responseObject=VolumeResponse.class) +@APICommand(name = "updateVolume", description="Updates the volume.", responseObject=VolumeResponse.class) public class UpdateVolumeCmd extends BaseAsyncCmd { - public static final Logger s_logger = Logger.getLogger(AttachVolumeCmd.class.getName()); - private static final String s_name = "addVolumeDetailresponse"; + public static final Logger s_logger = Logger.getLogger(UpdateVolumeCmd.class.getName()); + private static final String s_name = "addVolumeresponse"; ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -45,25 +45,16 @@ public class UpdateVolumeCmd extends BaseAsyncCmd { required=true, description="the ID of the disk volume") private Long id; - @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, - required=true, description="the name of the field") - private String name; - - @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, entityType=UserVmResponse.class, - required=true, description="the value of the field") - private String value; + @Parameter(name=ApiConstants.PATH, type=CommandType.STRING, + required=true, description="the path of the volume") + private String path; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - - public String getName() { - return name; - } - - public String getValue() { - return value; + public String getPath() { + return path; } public Long getId() { @@ -109,13 +100,13 @@ public class UpdateVolumeCmd extends BaseAsyncCmd { @Override public void execute(){ UserContext.current().setEventDetails("Volume Id: "+getId()); - /*Volume result = _volumeService.attachVolumeToVM(this); + Volume result = _volumeService.updateVolume(this); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(result); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to attach volume"); - } */ + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update volume"); + } } } diff --git a/api/src/org/apache/cloudstack/api/response/NicDetailResponse.java b/api/src/org/apache/cloudstack/api/response/NicDetailResponse.java new file mode 100644 index 00000000000..f8ddf1c8250 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/NicDetailResponse.java @@ -0,0 +1,81 @@ +// 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.response; + +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class NicDetailResponse extends BaseResponse{ + @SerializedName(ApiConstants.ID) + @Param(description = "ID of the nic") + private String id; + + @SerializedName(ApiConstants.NAME) + @Param(description = "name of the nic detail") + private String name; + + + @SerializedName(ApiConstants.VALUE) + @Param(description = "value of the nic detail") + private String value; + + @SerializedName(ApiConstants.DISPLAY_NIC) @Param(description="an optional field whether to the display the nic to the end user or not.") + private Boolean displayNic; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getName() { + + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getDisplayNic() { + return displayNic; + } + + public void setDisplayNic(Boolean displayNic) { + this.displayNic = displayNic; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/VolumeDetailResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeDetailResponse.java index 3a8fab9b300..04d280d0d9f 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeDetailResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeDetailResponse.java @@ -31,7 +31,7 @@ import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") public class VolumeDetailResponse extends BaseResponse{ - @SerializedName(ApiConstants.VOLUME_ID) + @SerializedName(ApiConstants.ID) @Param(description = "ID of the volume") private String id; diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index e821f3cd335..16c07672a16 100644 --- a/api/src/org/apache/cloudstack/query/QueryService.java +++ b/api/src/org/apache/cloudstack/query/QueryService.java @@ -25,6 +25,7 @@ import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd; +import org.apache.cloudstack.api.command.user.network.ListNicDetailsCmd; import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd; @@ -89,4 +90,5 @@ public interface QueryService { public List searchForVolumeDetails(ListVolumeDetailsCmd cmd); - } + List searchForNicDetails(ListNicDetailsCmd ListNicDetailsCmd); +} diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index c4d0fcfa551..9837d2428f1 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -269,10 +269,11 @@ listVolumes=15 extractVolume=15 migrateVolume=15 resizeVolume=15 -addVolumeDetail=15 -updateVolumeDetail=15 -removeVolumeDetail=15 -listVolumeDetails=15 +updateVolume=1 +addVolumeDetail=1 +updateVolumeDetail=1 +removeVolumeDetail=1 +listVolumeDetails=1 #### registration command: FIXME -- this really should be something in management server that #### generates a new key for the user and they just have to @@ -343,9 +344,10 @@ updateNetwork=15 addNicToVirtualMachine=15 removeNicFromVirtualMachine=15 updateDefaultNicForVirtualMachine=15 -addNicDetail=15 -updateNicDetail=15 -removeNicDetail=15 +addNicDetail=1 +updateNicDetail=1 +removeNicDetail=1 +listNicDetails=1 #### addIpToNic=15 diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index a1a4113e074..6f168a4f26d 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -22,6 +22,8 @@ import javax.ejb.Local; import javax.inject.Inject; import com.cloud.api.ApiDBUtils; +import com.cloud.vm.NicDetailVO; +import com.cloud.vm.dao.NicDetailDao; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; @@ -35,6 +37,7 @@ import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd; +import org.apache.cloudstack.api.command.user.network.ListNicDetailsCmd; import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd; @@ -48,7 +51,6 @@ import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.cloudstack.api.response.*; import org.apache.cloudstack.query.QueryService; -import org.apache.commons.collections.map.HashedMap; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -230,6 +232,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Inject private VolumeDetailsDao _volumeDetailDao; + @Inject + private NicDetailDao _nicDetailDao; + @Inject private HighAvailabilityManager _haMgr; @@ -1522,6 +1527,35 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { return volumeDetailResponseList; } + @Override + public List searchForNicDetails(ListNicDetailsCmd cmd){ + Long id = cmd.getId(); + String name = cmd.getName(); + + List nicDetailList; + if(name == null){ + nicDetailList = _nicDetailDao.findDetails(id); + }else { + NicDetailVO nicDetail = _nicDetailDao.findDetail(id, name); + nicDetailList = new LinkedList(); + nicDetailList.add(nicDetail); + } + + List nicDetailResponseList = new ArrayList(); + for(NicDetailVO nicDetail : nicDetailList){ + NicDetailResponse nicDetailResponse = new NicDetailResponse(); + //String uuid = ApiDBUtils.findN + nicDetailResponse.setName(nicDetail.getName()); + nicDetailResponse.setValue(nicDetail.getValue()); + nicDetailResponse.setObjectName("nicdetail"); + nicDetailResponseList.add(nicDetailResponse); + } + + return nicDetailResponseList; + + } + + private Pair, Integer> searchForVolumesInternal(ListVolumesCmd cmd) { diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 485790a509d..db3ed222781 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -2424,6 +2424,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AttachVolumeCmd.class); cmdList.add(CreateVolumeCmd.class); cmdList.add(DeleteVolumeCmd.class); + cmdList.add(UpdateVolumeCmd.class); cmdList.add(DetachVolumeCmd.class); cmdList.add(ExtractVolumeCmd.class); cmdList.add(ListVolumesCmd.class); @@ -2487,6 +2488,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AddNicDetailCmd.class); cmdList.add(UpdateNicDetailCmd.class); cmdList.add(RemoveNicDetailCmd.class); + cmdList.add(ListNicDetailsCmd.class); return cmdList; } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 73e96f4c8ae..356f676f6aa 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -880,6 +880,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if(displayVolumeEnabled == null){ displayVolumeEnabled = true; + } else{ + if(!_accountMgr.isRootAdmin(caller.getType())){ + throw new PermissionDeniedException( "Cannot update parameter displayvolume, only admin permitted "); + } } if (!validateVolumeSizeRange(size)) {// convert size from mb to gb @@ -1773,6 +1777,22 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return newVol; } + @Override + public Volume updateVolume(UpdateVolumeCmd cmd){ + Long volumeId = cmd.getId(); + String path = cmd.getPath(); + + if(path == null){ + throw new InvalidParameterValueException("Failed to update the volume as path was null"); + } + + VolumeVO volume = ApiDBUtils.findVolumeById(volumeId); + volume.setPath(path); + _volumeDao.update(volumeId, volume); + + return volume; + } + @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETAIL_UPDATE, eventDescription = "updating volume detail", async = true) public void updateVolumeDetails(UpdateVolumeDetailCmd cmd){ diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 5bc3a166896..d0feff80da6 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1576,6 +1576,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use Long id = cmd.getId(); Long osTypeId = cmd.getOsTypeId(); String userData = cmd.getUserData(); + Account caller = UserContext.current().getCaller(); // Input validation UserVmVO vmInstance = null; @@ -1608,6 +1609,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use if (isDisplayVmEnabled == null) { isDisplayVmEnabled = vmInstance.isDisplayVm(); + } else{ + if(!_accountMgr.isRootAdmin(caller.getType())){ + throw new PermissionDeniedException( "Cannot update parameter displayvm, only admin permitted "); + } } UserVmVO vm = _vmDao.findById(id); @@ -2251,7 +2256,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, String hostName, String displayName, Account owner, Long diskOfferingId, Long diskSize, List networkList, List securityGroupIdList, String group, HTTPMethod httpmethod, String userData, String sshKeyPair, HypervisorType hypervisor, Account caller, Map requestedIps, - IpAddresses defaultIps, Boolean displayvm, String keyboard, List affinityGroupIdList) + IpAddresses defaultIps, Boolean isDisplayVmEnabled, String keyboard, List affinityGroupIdList) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException { _accountMgr.checkAccess(caller, null, true, owner); @@ -2537,8 +2542,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use vm.setIsoId(template.getId()); } - if(displayvm != null){ - vm.setDisplayVm(displayvm); + if(isDisplayVmEnabled != null){ + if(!_accountMgr.isRootAdmin(caller.getType())){ + throw new PermissionDeniedException( "Cannot update parameter displayvm, only admin permitted "); + } + vm.setDisplayVm(isDisplayVmEnabled); }else { vm.setDisplayVm(true); } diff --git a/server/src/com/cloud/vm/dao/NicDetailDao.java b/server/src/com/cloud/vm/dao/NicDetailDao.java index ff6802bd376..6f51ffe7b95 100644 --- a/server/src/com/cloud/vm/dao/NicDetailDao.java +++ b/server/src/com/cloud/vm/dao/NicDetailDao.java @@ -16,13 +16,14 @@ // under the License. package com.cloud.vm.dao; +import java.util.List; import java.util.Map; import com.cloud.utils.db.GenericDao; import com.cloud.vm.NicDetailVO; public interface NicDetailDao extends GenericDao { - Map findDetails(long nicId); + List findDetails(long nicId); void persist(long nicId, Map details); diff --git a/server/src/com/cloud/vm/dao/NicDetailDaoImpl.java b/server/src/com/cloud/vm/dao/NicDetailDaoImpl.java index fd110359473..ae400cfe75b 100644 --- a/server/src/com/cloud/vm/dao/NicDetailDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDetailDaoImpl.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.vm.dao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -26,7 +24,6 @@ import com.cloud.vm.NicDetailVO; import org.springframework.stereotype.Component; import javax.ejb.Local; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -68,17 +65,17 @@ public class NicDetailDaoImpl extends GenericDaoBase implemen } @Override - public Map findDetails(long nicId) { + public List findDetails(long nicId) { SearchCriteria sc = NicSearch.create(); sc.setParameters("nicId", nicId); List results = search(sc, null); - Map details = new HashMap(results.size()); + /*Map details = new HashMap(results.size()); for (NicDetailVO result : results) { details.put(result.getName(), result.getValue()); - } + } */ - return details; + return results; } @Override diff --git a/test/integration/smoke/test_nicdetail.py b/test/integration/smoke/test_nicdetail.py new file mode 100644 index 00000000000..3d8b1d62a47 --- /dev/null +++ b/test/integration/smoke/test_nicdetail.py @@ -0,0 +1,224 @@ +# 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. +""" P1 tests for Scaling up Vm +""" +#Import Local Modules +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.remoteSSHClient import remoteSSHClient +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * +from nose.plugins.attrib import attr +#Import System modules +import time + +_multiprocess_shared_ = True +class Services: + """Test VM Life Cycle Services + """ + + def __init__(self): + self.services = { + + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended in create account to + # ensure unique username generated each time + "password": "password", + }, + "small": + # Create a small virtual machine instance with disk offering + { + "displayname": "testserver", + "username": "root", # VM creds for SSH + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "storagetype": "shared", + "disksize": 1 + }, + "service_offerings": + { + "small": + { + # Small service offering ID to for change VM + # service offering from medium to small + "name": "SmallInstance", + "displaytext": "SmallInstance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256, + }, + "big": + { + # Big service offering ID to for change VM + "name": "BigInstance", + "displaytext": "BigInstance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 512, + } + }, + #Change this + "template": { + "displaytext": "xs", + "name": "xs", + "passwordenabled": False, + }, + "diskdevice": '/dev/xvdd', + # Disk device where ISO is attached to instance + "mount_dir": "/mnt/tmp", + "sleep": 60, + "timeout": 10, + #Migrate VM to hostid + "ostype": 'CentOS 5.6 (64-bit)', + # CentOS 5.3 (64-bit) + } + +class TestNicDetail(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super(TestNicDetail, cls).getClsTestClient().getApiClient() + cls.services = Services().services + + # Get Zone, Domain and templates + domain = get_domain(cls.api_client, cls.services) + zone = get_zone(cls.api_client, cls.services) + cls.services['mode'] = zone.networktype + + # Set Zone + + # Create account, service offerings, vm. + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=domain.id + ) + + cls.nic = "163738c7-ce3a-481d-ac68-4a8337043415"; + #how does it work + cls._cleanup = [ + cls.account + ] + + @classmethod + def tearDownClass(cls): + cls.api_client = super(TestNicDetail, cls).getClsTestClient().getApiClient() + cleanup_resources(cls.api_client, cls._cleanup) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + #Clean up, terminate the created ISOs + cleanup_resources(self.apiclient, self.cleanup) + return + + @attr(tags = ["advanced", "xenserver"]) + def test_01_updatenicdetail(self): + """Test nic detail + """ + # Validate the following + # Scale up the vm and see if it scales to the new svc offering and is finally in running state + + self.debug("Testing ADD nic detail Nic-ID: %s " % ( + self.nic + )) + + cmd = addNicDetail.addNicDetailCmd() + cmd.name = self.nic + cmd.value = self.nic + cmd.id = self.nic + self.apiclient.addNicDetail(cmd) + + listNicDetailCmd = listNicDetails.listNicDetailsCmd() + listNicDetailCmd.id = self.nic + listNicDetailResponse = self.api_client.listVirtualMachines(listNicDetailCmd) + + self.assertNotEqual(len(listNicDetailResponse), 0, "Check if the list API \ + returns a non-empty response") + + nicdetail = listNicDetailResponse[0] + + #self.assertEqual(nicdetail.id, self.nic, "Check if the Nic returned is the same as the one we asked for") + + + self.assertEqual(nicdetail.name, self.nic, "Check if Nic has right name") + + self.assertEqual(nicdetail.value, self.nic, "Check if Nic has right value") + + #updatenicdetail + self.debug("Testing UPDATE nic detail Nic-ID: %s " % ( + self.nic + )) + cmd = updateNicDetail.updateNicDetailCmd() + cmd.name = self.nic + cmd.value = self.disk_offering.id + cmd.id = self.nic + self.apiclient.addNicDetail(cmd) + + listNicDetailCmd = listNicDetails.listNicDetailsCmd() + listNicDetailCmd.id = self.nic + listNicDetailResponse = self.api_client.listVirtualMachines(listNicDetailCmd) + + self.assertNotEqual(len(listNicDetailResponse), 0, "Check if the list API \ + returns a non-empty response") + + nicdetail = listNicDetailResponse[0] + + #self.assertEqual(nicdetail.id, self.nic, "Check if the Nic returned is the same as the one we asked for") + + + self.assertEqual(nicdetail.name, self.nic, "Check if Nic has right name") + + self.assertEqual(nicdetail.value, self.disk_offering.id, "Check if Nic has right value") + + + #remove detail + self.debug("Testing REMOVE nic detail Nic-ID: %s " % ( + self.nic + )) + cmd = removeNicDetail.removeNicDetailCmd() + cmd.name = self.nic + cmd.id = self.nic + self.apiclient.removeNicDetail(cmd) + + listNicDetailCmd = listNicDetails.listNicDetailsCmd() + listNicDetailCmd.id = self.nic + listNicDetailResponse = self.api_client.listVirtualMachines(listNicDetailCmd) + + self.assertEqual(listNicDetailResponse, None, "Check if the list API \ + returns a non-empty response") + + + return