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/4e4edc9e Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/4e4edc9e Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/4e4edc9e Branch: refs/heads/ui-plugins Commit: 4e4edc9e42f69b10314d0b09629546acc4db333a Parents: 951cba9 Author: Prachi Damle <[email protected]> Authored: Thu Feb 7 17:22:16 2013 -0800 Committer: Prachi Damle <[email protected]> Committed: Thu Feb 7 17:22:16 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/4e4edc9e/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<String> launchPermissionList = new ArrayList<String>(); + 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/4e4edc9e/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<String> launchPermissionAccountsOrGroupList = new ArrayList<String>(); - + 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/4e4edc9e/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<String> 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<String> 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/4e4edc9e/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<String> launchPermissionList = new ArrayList<String>(); + + public EC2ImageLaunchPermission() { + launchPermOperation = null; + } + + public void addLaunchPermission(String launchPermission) { + launchPermissionList.add(launchPermission); + } + + public List<String> 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/4e4edc9e/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<String> launchPermissionAccountsOrGroupList; - + private List<EC2ImageLaunchPermission> launchPermissionList = new ArrayList<EC2ImageLaunchPermission>(); public EC2ModifyImageAttribute() { } @@ -65,31 +57,20 @@ public class EC2ModifyImageAttribute { return this.description; } - public void setLaunchPermissionAccountsOrGroupList(List<String> launchPermissionAccountsOrGroupList) { - this.launchPermissionAccountsOrGroupList = launchPermissionAccountsOrGroupList; - } - - public List<String> 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]); + } }
