Return-Path: X-Original-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E88A8E616 for ; Fri, 8 Feb 2013 01:51:10 +0000 (UTC) Received: (qmail 12086 invoked by uid 500); 8 Feb 2013 01:51:10 -0000 Delivered-To: apmail-incubator-cloudstack-commits-archive@incubator.apache.org Received: (qmail 12057 invoked by uid 500); 8 Feb 2013 01:51:10 -0000 Mailing-List: contact cloudstack-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: cloudstack-dev@incubator.apache.org Delivered-To: mailing list cloudstack-commits@incubator.apache.org Received: (qmail 12050 invoked by uid 99); 8 Feb 2013 01:51:10 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 Feb 2013 01:51:10 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 6F1723A0DA; Fri, 8 Feb 2013 01:51:10 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: prachidamle@apache.org To: cloudstack-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: git commit: refs/heads/4.1 - CLOUDSTACK-1116 [EC2 Query API] Support for ModifyImageAttribute and ResetImageAttribute Message-Id: <20130208015110.6F1723A0DA@tyr.zones.apache.org> Date: Fri, 8 Feb 2013 01:51:10 +0000 (UTC) Updated Branches: refs/heads/4.1 e9c923aee -> c92f1f983 CLOUDSTACK-1116 [EC2 Query API] Support for ModifyImageAttribute and ResetImageAttribute https://reviews.apache.org/r/9213 Add support for EC2 ApiI's ModifyImageAttribute and ResetImageAttribute. Attributes supported are Description and LaunchPermission. Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/c92f1f98 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/c92f1f98 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/c92f1f98 Branch: refs/heads/4.1 Commit: c92f1f9839322a68b42a9f90b20542e471e78c24 Parents: e9c923a Author: Prachi Damle Authored: Thu Feb 7 17:22:16 2013 -0800 Committer: Prachi Damle Committed: Thu Feb 7 17:42:27 2013 -0800 ---------------------------------------------------------------------- .../com/cloud/bridge/service/EC2RestServlet.java | 107 ++++++++++++--- .../cloud/bridge/service/EC2SoapServiceImpl.java | 30 +++-- .../cloud/bridge/service/core/ec2/EC2Engine.java | 71 ++++------- .../service/core/ec2/EC2ImageLaunchPermission.java | 53 +++++++ .../service/core/ec2/EC2ModifyImageAttribute.java | 39 ++---- 5 files changed, 193 insertions(+), 107 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c92f1f98/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java ---------------------------------------------------------------------- diff --git a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java index 57a32a4..4612b60 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java +++ b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java @@ -87,6 +87,7 @@ import com.amazon.ec2.DetachVolumeResponse; import com.amazon.ec2.DisassociateAddressResponse; import com.amazon.ec2.GetPasswordDataResponse; import com.amazon.ec2.ImportKeyPairResponse; +import com.amazon.ec2.LaunchPermissionItemType; import com.amazon.ec2.ModifyImageAttributeResponse; import com.amazon.ec2.RebootInstancesResponse; import com.amazon.ec2.RegisterImageResponse; @@ -123,10 +124,13 @@ import com.cloud.bridge.service.core.ec2.EC2Engine; import com.cloud.bridge.service.core.ec2.EC2Filter; import com.cloud.bridge.service.core.ec2.EC2GroupFilterSet; import com.cloud.bridge.service.core.ec2.EC2Image; +import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute; +import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission; import com.cloud.bridge.service.core.ec2.EC2ImportKeyPair; import com.cloud.bridge.service.core.ec2.EC2InstanceFilterSet; import com.cloud.bridge.service.core.ec2.EC2IpPermission; import com.cloud.bridge.service.core.ec2.EC2KeyPairFilterSet; +import com.cloud.bridge.service.core.ec2.EC2ModifyImageAttribute; import com.cloud.bridge.service.core.ec2.EC2RebootInstances; import com.cloud.bridge.service.core.ec2.EC2RegisterImage; import com.cloud.bridge.service.core.ec2.EC2ReleaseAddress; @@ -1021,38 +1025,105 @@ public class EC2RestServlet extends HttpServlet { serializeResponse(response, EC2response); } - private void modifyImageAttribute( HttpServletRequest request, HttpServletResponse response ) + private void modifyImageAttribute( HttpServletRequest request, HttpServletResponse response ) throws ADBException, XMLStreamException, IOException { - EC2Image image = new EC2Image(); + EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute(); - // -> its interesting to note that the SOAP API docs has description but the REST API docs do not - String[] imageId = request.getParameterValues( "ImageId" ); - if ( null != imageId && 0 < imageId.length ) - image.setId( imageId[0] ); - else { response.sendError(530, "Missing ImageId parameter" ); return; } + String[] imageId = request.getParameterValues( "ImageId" ); + if ( imageId != null && imageId.length > 0 ) + ec2request.setImageId( imageId[0]); + else { + response.sendError(530, "Missing ImageId parameter" ); + return; + } - String[] description = request.getParameterValues( "Description" ); - if ( null != description && 0 < description.length ) - image.setDescription( description[0] ); - else { response.sendError(530, "Missing Description parameter" ); return; } + String[] description = request.getParameterValues( "Description.Value" ); + if ( description != null && description.length > 0 ) { + ec2request.setAttribute(ImageAttribute.description); + ec2request.setDescription(description[0]); + } else { + //add all launch permissions to ec2request + ec2request = addLaunchPermImageAttribute(request, ec2request); + if (ec2request.getLaunchPermissionSet().length > 0) + ec2request.setAttribute(ImageAttribute.launchPermission); + else { + response.sendError(530, "Missing Attribute parameter - Description/LaunchPermission should be provided" ); + return; + } + } // -> execute the request - ModifyImageAttributeResponse EC2response = EC2SoapServiceImpl.toModifyImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( image )); + ModifyImageAttributeResponse EC2response = EC2SoapServiceImpl.toModifyImageAttributeResponse( + ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( ec2request )); serializeResponse(response, EC2response); } + private EC2ModifyImageAttribute addLaunchPermImageAttribute(HttpServletRequest request, EC2ModifyImageAttribute ec2request) { + String[] users = {".UserId", ".Group"}; + String[] operations = {"LaunchPermission.Add.", "LaunchPermission.Remove."}; + int nCount = 1; + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + List launchPermissionList = new ArrayList(); + do { + String[] launchPermissionAddGroup = request.getParameterValues( operations[j] + nCount + users[i] ); + if (launchPermissionAddGroup != null && launchPermissionAddGroup.length > 0) + launchPermissionList.add(launchPermissionAddGroup[0]); + else + break; + nCount++; + } while (true); + if (nCount != 1) { + EC2ImageLaunchPermission ec2LaunchPermission = new EC2ImageLaunchPermission(); + if (operations[j].contains("Add")) + ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.add); + else + ec2LaunchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.remove); + for (String launchPerm : launchPermissionList) { + ec2LaunchPermission.addLaunchPermission(launchPerm); + } + ec2request.addLaunchPermission(ec2LaunchPermission); + nCount = 1; + } + } + } + + return ec2request; + } + private void resetImageAttribute( HttpServletRequest request, HttpServletResponse response ) throws ADBException, XMLStreamException, IOException { - EC2Image image = new EC2Image(); + EC2ModifyImageAttribute ec2request = new EC2ModifyImageAttribute(); String[] imageId = request.getParameterValues( "ImageId" ); - if ( null != imageId && 0 < imageId.length ) - image.setId( imageId[0] ); - else { response.sendError(530, "Missing ImageId parameter" ); return; } + if ( imageId != null && imageId.length > 0) + ec2request.setImageId(imageId[0]); + else { + response.sendError(530, "Missing ImageId parameter" ); + return; + } + + String[] attribute = request.getParameterValues( "Attribute" ); + if ( attribute != null && attribute.length > 0 ) { + if (attribute[0].equalsIgnoreCase("launchPermission")) + ec2request.setAttribute(ImageAttribute.launchPermission); + else { + response.sendError(501, "Unsupported Attribute - only launchPermission supported" ); + return; + } + } else { + response.sendError(530, "Missing Attribute parameter" ); + return; + } + + EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission(); + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.reset); + ec2request.addLaunchPermission(launchPermission); // -> execute the request - image.setDescription( "" ); - ResetImageAttributeResponse EC2response = EC2SoapServiceImpl.toResetImageAttributeResponse( ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( image )); + ResetImageAttributeResponse EC2response = EC2SoapServiceImpl.toResetImageAttributeResponse( + ServiceProvider.getInstance().getEC2Engine().modifyImageAttribute( ec2request )); serializeResponse(response, EC2response); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c92f1f98/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java ---------------------------------------------------------------------- diff --git a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java index b2451c6..6fae480 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java +++ b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java @@ -47,6 +47,7 @@ import com.cloud.bridge.service.core.ec2.EC2DescribeInstances; import com.cloud.bridge.service.core.ec2.EC2DescribeInstancesResponse; import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairs; import com.cloud.bridge.service.core.ec2.EC2DescribeKeyPairsResponse; +import com.cloud.bridge.service.core.ec2.EC2ImageLaunchPermission; import com.cloud.bridge.service.core.ec2.EC2ResourceTag; import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroups; import com.cloud.bridge.service.core.ec2.EC2DescribeSecurityGroupsResponse; @@ -595,31 +596,32 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { request.setImageId(miat.getImageId()); request.setAttribute(ImageAttribute.launchPermission); if(launchPermOp.getAdd() != null){ - request.setLaunchPermOperation(EC2ModifyImageAttribute.Operation.add); - setAccountOrGroupList(launchPermOp.getAdd().getItem(), request); + setAccountOrGroupList(launchPermOp.getAdd().getItem(), request, "add"); }else if(launchPermOp.getRemove() != null){ - request.setLaunchPermOperation(EC2ModifyImageAttribute.Operation.remove); - setAccountOrGroupList(launchPermOp.getRemove().getItem(), request); + setAccountOrGroupList(launchPermOp.getRemove().getItem(), request, "remove"); } return toModifyImageAttributeResponse( engine.modifyImageAttribute( request )); } throw new EC2ServiceException( ClientError.Unsupported, "Unsupported - can only modify image description or launchPermission"); } - private void setAccountOrGroupList(LaunchPermissionItemType[] items, EC2ModifyImageAttribute request){ - - List launchPermissionAccountsOrGroupList = new ArrayList(); - + private void setAccountOrGroupList(LaunchPermissionItemType[] items, EC2ModifyImageAttribute request, String operation){ + EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission(); + + if (operation.equalsIgnoreCase("add")) + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.add); + else + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.remove); + for (LaunchPermissionItemType lpItem : items) { if(lpItem.getGroup() != null){ - launchPermissionAccountsOrGroupList.add(lpItem.getGroup()); + launchPermission.addLaunchPermission(lpItem.getGroup()); }else if(lpItem.getUserId() != null){ - launchPermissionAccountsOrGroupList.add(lpItem.getUserId()); + launchPermission.addLaunchPermission(lpItem.getUserId()); } } - - request.setLaunchPermissionAccountsOrGroupList(launchPermissionAccountsOrGroupList); + request.addLaunchPermission(launchPermission); } /** * Did not find a matching service offering so for now we just return disabled @@ -702,7 +704,9 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { if(elementType != null){ request.setImageId( riat.getImageId()); request.setAttribute(ImageAttribute.launchPermission); - request.setLaunchPermOperation(EC2ModifyImageAttribute.Operation.reset); + EC2ImageLaunchPermission launchPermission = new EC2ImageLaunchPermission(); + launchPermission.setLaunchPermOp(EC2ImageLaunchPermission.Operation.reset); + request.addLaunchPermission(launchPermission); return toResetImageAttributeResponse( engine.modifyImageAttribute( request )); } throw new EC2ServiceException( ClientError.Unsupported, "Unsupported - can only reset image launchPermission" ); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c92f1f98/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java ---------------------------------------------------------------------- diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index 8a5a733..2f45b03 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -535,32 +535,6 @@ public class EC2Engine extends ManagerBase { } - /** REST API calls this method. - * Modify an existing template - * - * @param request - * @return - */ - public boolean modifyImageAttribute( EC2Image request ) - { - // TODO: This is incomplete - EC2DescribeImagesResponse images = new EC2DescribeImagesResponse(); - - try { - images = listTemplates( request.getId(), images ); - EC2Image[] imageSet = images.getImageSet(); - - CloudStackTemplate resp = getApi().updateTemplate(request.getId(), null, request.getDescription(), null, imageSet[0].getName(), null, null); - if (resp != null) { - return true; - } - return false; - } catch( Exception e ) { - logger.error( "EC2 ModifyImage - ", e); - throw new EC2ServiceException(ServerError.InternalError, e.getMessage()); - } - } - /** * Modify an existing template @@ -572,32 +546,35 @@ public class EC2Engine extends ManagerBase { { try { if(request.getAttribute().equals(ImageAttribute.launchPermission)){ - - String accounts = ""; - Boolean isPublic = null; - EC2ModifyImageAttribute.Operation operation = request.getLaunchPermOperation(); - - List accountOrGroupList = request.getLaunchPermissionAccountsList(); - if(accountOrGroupList != null && !accountOrGroupList.isEmpty()){ - boolean first = true; - for(String accountOrGroup : accountOrGroupList){ - if("all".equalsIgnoreCase(accountOrGroup)){ - if(operation.equals(EC2ModifyImageAttribute.Operation.add)){ - isPublic = true; + EC2ImageLaunchPermission[] launchPermissions = request.getLaunchPermissionSet(); + for (EC2ImageLaunchPermission launchPermission : launchPermissions) { + String accounts = ""; + Boolean isPublic = null; + EC2ImageLaunchPermission.Operation operation = launchPermission.getLaunchPermOp(); + List accountOrGroupList = launchPermission.getLaunchPermissionList(); + if(accountOrGroupList != null && !accountOrGroupList.isEmpty()){ + boolean first = true; + for(String accountOrGroup : accountOrGroupList){ + if("all".equalsIgnoreCase(accountOrGroup)){ + if(operation.equals(EC2ImageLaunchPermission.Operation.add)){ + isPublic = true; + }else{ + isPublic = false; + } }else{ - isPublic = false; + if(!first){ + accounts = accounts + ","; + } + accounts = accounts + accountOrGroup; + first = false; } - }else{ - if(!first){ - accounts = accounts + ","; - } - accounts = accounts + accountOrGroup; - first = false; } } + CloudStackInfoResponse resp = getApi().updateTemplatePermissions(request.getImageId(), accounts, null, null, isPublic, operation.toString()); + if (!resp.getSuccess()) + return false; } - CloudStackInfoResponse resp = getApi().updateTemplatePermissions(request.getImageId(), accounts, null, null, isPublic, operation.toString()); - return resp.getSuccess(); + return true; }else if(request.getAttribute().equals(ImageAttribute.description)){ CloudStackTemplate resp = getApi().updateTemplate(request.getImageId(), null, request.getDescription(), null, null, null, null); if (resp != null) { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c92f1f98/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ImageLaunchPermission.java ---------------------------------------------------------------------- diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ImageLaunchPermission.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ImageLaunchPermission.java new file mode 100644 index 0000000..552ffbe --- /dev/null +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ImageLaunchPermission.java @@ -0,0 +1,53 @@ +// 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 com.cloud.bridge.service.core.ec2; + +import java.util.ArrayList; +import java.util.List; + +public class EC2ImageLaunchPermission { + + private Operation launchPermOperation; + public enum Operation{ + add, + remove, + reset; + } + + private List launchPermissionList = new ArrayList(); + + public EC2ImageLaunchPermission() { + launchPermOperation = null; + } + + public void addLaunchPermission(String launchPermission) { + launchPermissionList.add(launchPermission); + } + + public List getLaunchPermissionList() { + return launchPermissionList; + } + + public void setLaunchPermOp( Operation launchPermOperation ) { + this.launchPermOperation = launchPermOperation; + } + + public Operation getLaunchPermOp() { + return this.launchPermOperation; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/c92f1f98/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java ---------------------------------------------------------------------- diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java index 16f5ef7..e88d2d1 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2ModifyImageAttribute.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.bridge.service.core.ec2; - +import java.util.ArrayList; import java.util.List; import com.cloud.bridge.service.core.ec2.EC2ImageAttributes.ImageAttribute; @@ -28,15 +28,7 @@ public class EC2ModifyImageAttribute { private String description; private Boolean isPublic = null; - private Operation launchPermOperation = null; - public enum Operation{ - add, - remove, - reset; - } - - private List launchPermissionAccountsOrGroupList; - + private List launchPermissionList = new ArrayList(); public EC2ModifyImageAttribute() { } @@ -65,31 +57,20 @@ public class EC2ModifyImageAttribute { return this.description; } - public void setLaunchPermissionAccountsOrGroupList(List launchPermissionAccountsOrGroupList) { - this.launchPermissionAccountsOrGroupList = launchPermissionAccountsOrGroupList; - } - - public List getLaunchPermissionAccountsList() { - return launchPermissionAccountsOrGroupList; - } - - public void setLaunchPermOperation( Operation launchPermOperation ) { - this.launchPermOperation = launchPermOperation; - } - - public Operation getLaunchPermOperation() { - return this.launchPermOperation; - } - - public void setIsPublic(Boolean isPublic) { this.isPublic = isPublic; } - public Boolean getIsPublic() { return isPublic; } - + + public void addLaunchPermission( EC2ImageLaunchPermission param ) { + launchPermissionList.add( param ); + } + + public EC2ImageLaunchPermission[] getLaunchPermissionSet() { + return launchPermissionList.toArray(new EC2ImageLaunchPermission[0]); + } }