From b963bb1e6d6b49d585a7937071c5b2eb8371ba11 Mon Sep 17 00:00:00 2001 From: Rajani Karuturi Date: Tue, 2 Dec 2014 12:15:42 +0530 Subject: [PATCH] volume upload: added getUploadParamsForVolume and getUploadParamsForTemplate api --- .../api/AbstractGetUploadParamsCommand.java | 89 +++++++++ .../apache/cloudstack/api/ApiConstants.java | 1 + .../template/GetUploadParamsForTemplate.java | 177 ++++++++++++++++++ .../user/volume/GetUploadParamsForVolume.java | 88 +++++++++ .../api/response/GetUploadParamsResponse.java | 79 ++++++++ client/tomcatconf/commands.properties.in | 4 + .../cloud/server/ManagementServerImpl.java | 5 +- 7 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 api/src/org/apache/cloudstack/api/AbstractGetUploadParamsCommand.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplate.java create mode 100644 api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolume.java create mode 100644 api/src/org/apache/cloudstack/api/response/GetUploadParamsResponse.java diff --git a/api/src/org/apache/cloudstack/api/AbstractGetUploadParamsCommand.java b/api/src/org/apache/cloudstack/api/AbstractGetUploadParamsCommand.java new file mode 100644 index 00000000000..cd5fb1400c2 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/AbstractGetUploadParamsCommand.java @@ -0,0 +1,89 @@ +/* + * 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; + +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.GetUploadParamsResponse; +import org.apache.cloudstack.api.response.ProjectResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; + +import java.net.URL; +import java.util.UUID; + +public abstract class AbstractGetUploadParamsCommand extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(AbstractGetUploadParamsCommand.class.getName()); + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the volume/template") + private String name; + + @Parameter(name = ApiConstants.FORMAT, type = CommandType.STRING, required = true, description = "the format for the volume/template. Possible values include QCOW2, OVA, " + + "and VHD.") + private String format; + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the zone the volume/template is " + + "to be hosted on") + private Long zoneId; + + @Parameter(name = ApiConstants.CHECKSUM, type = CommandType.STRING, description = "the MD5 checksum value of this volume/template") + private String checksum; + + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional accountName. Must be used with domainId.") + private String accountName; + + @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId. If the account parameter is used, " + + "domainId must also be used.") + private Long domainId; + + @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Upload volume/template for the project") + private Long projectId; + + public String getName() { + return name; + } + + public String getFormat() { + return format; + } + + public Long getZoneId() { + return zoneId; + } + + public String getChecksum() { + return checksum; + } + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public Long getProjectId() { + return projectId; + } + + public GetUploadParamsResponse createGetUploadParamsResponse(UUID id, URL postURL, String metadata, String timeout, String signature) { + return new GetUploadParamsResponse(id, postURL, metadata, timeout, signature); + } +} diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 762ad7097fc..066df9d3f31 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -613,6 +613,7 @@ public class ApiConstants { public static final String REGION_LEVEL_VPC = "regionlevelvpc"; public static final String STRECHED_L2_SUBNET = "strechedl2subnet"; public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans"; + public static final String METADATA = "metadata"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplate.java b/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplate.java new file mode 100644 index 00000000000..2b7ee32c2b0 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/template/GetUploadParamsForTemplate.java @@ -0,0 +1,177 @@ +/* + * 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.template; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.Map; +import java.util.UUID; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.AbstractGetUploadParamsCommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.GetUploadParamsResponse; +import org.apache.cloudstack.api.response.GuestOSResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + +@APICommand(name = "getUploadParamsForTemplate", description = "upload an existing template into the CloudStack cloud. ", responseObject = GetUploadParamsResponse.class, since = + "4.6.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class GetUploadParamsForTemplate extends AbstractGetUploadParamsCommand { + public static final Logger s_logger = Logger.getLogger(GetUploadParamsForTemplate.class.getName()); + + private static final String s_name = "postuploadtemplateresponse"; + + @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "the display text of the template. This is usually used for display purposes.", length = 4096) + private String displayText; + + @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = true, description = "the target hypervisor for the template") + private String hypervisor; + + @Parameter(name = ApiConstants.OS_TYPE_ID, type = CommandType.UUID, entityType = GuestOSResponse.class, required = true, description = "the ID of the OS Type that best represents the OS of this template.") + private Long osTypeId; + + @Parameter(name = ApiConstants.BITS, type = CommandType.INTEGER, description = "32 or 64 bits support. 64 by default") + private Integer bits; + + @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, description = "Template details in key/value pairs.") + private Map details; + + @Parameter(name = ApiConstants.IS_DYNAMICALLY_SCALABLE, type = CommandType.BOOLEAN, description = "true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory") + private Boolean isDynamicallyScalable; + + @Parameter(name = ApiConstants.IS_EXTRACTABLE, type = CommandType.BOOLEAN, description = "true if the template or its derivatives are extractable; default is false") + private Boolean extractable; + + @Parameter(name = ApiConstants.IS_FEATURED, type = CommandType.BOOLEAN, description = "true if this template is a featured template, false otherwise") + private Boolean featured; + + @Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN, description = "true if the template is available to all accounts; default is true") + private Boolean publicTemplate; + + @Parameter(name = ApiConstants.ROUTING, type = CommandType.BOOLEAN, description = "true if the template type is routing i.e., if template is used to deploy router") + private Boolean isRoutingType; + + @Parameter(name = ApiConstants.PASSWORD_ENABLED, type = CommandType.BOOLEAN, description = "true if the template supports the password reset feature; default is false") + private Boolean passwordEnabled; + + @Parameter(name = ApiConstants.REQUIRES_HVM, type = CommandType.BOOLEAN, description = "true if this template requires HVM") + private Boolean requiresHvm; + + @Parameter(name = ApiConstants.SSHKEY_ENABLED, type = CommandType.BOOLEAN, description = "true if the template supports the sshkey upload feature; default is false") + private Boolean sshKeyEnabled; + + @Parameter(name = ApiConstants.TEMPLATE_TAG, type = CommandType.STRING, description = "the tag for this template.") + private String templateTag; + + public String getDisplayText() { + return displayText; + } + + public String getHypervisor() { + return hypervisor; + } + + public Long getOsTypeId() { + return osTypeId; + } + + public Integer getBits() { + return bits; + } + + public Map getDetails() { + if (details == null || details.isEmpty()) { + return null; + } + Collection paramsCollection = details.values(); + Map params = (Map)(paramsCollection.toArray())[0]; + return params; + } + + public Boolean getIsDynamicallyScalable() { + return isDynamicallyScalable; + } + + public Boolean getExtractable() { + return extractable; + } + + public Boolean getFeatured() { + return featured; + } + + public Boolean getPublicTemplate() { + return publicTemplate; + } + + public Boolean getIsRoutingType() { + return isRoutingType; + } + + public Boolean getPasswordEnabled() { + return passwordEnabled; + } + + public Boolean getRequiresHvm() { + return requiresHvm; + } + + public Boolean getSshKeyEnabled() { + return sshKeyEnabled; + } + + public String getTemplateTag() { + return templateTag; + } + + @Override + public void execute() throws ServerApiException { + // TODO Auto-generated method stub + try { + GetUploadParamsResponse response = createGetUploadParamsResponse( + UUID.fromString("C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"), + new URL("https://1-2-3-4.xyz.com/upload/C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"), + "TKPFeuz2nHmE/kcREEu24mnj1MrLdzOeJIHXR9HLIGgk56bkRJHaD0RRL2lds1rKKhrro4/PuleEh4YhRinhxaAmPpU4e55eprG8gTCX0ItyFAtlZViVdKXMew5Dfp4Qg8W9I1/IsDJd2Kas9/ftDQLiemAlPt0uS7Ou6asOCpifnBaKvhM4UGEjHSnni1KhBzjgEyDW3Y42HKJSSv58Sgmxl9LCewBX8vtn9tXKr+j4afj7Jlh7DFhyo9HOPC5ogR4hPBKqP7xF9tHxAyq6YqfBzsng3Xwe+Pb8TU1kFHg1l2DM4tY6ooW2h8lOhWUkrJu4hOAOeTeRtCjW3H452NKoeA1M8pKWuqMo5zRMti2u2hNZs0YY2yOy8oWMMG+lG0hvIlajqEU=", + "2014-10-17T12:00:00+0530", "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"); + response.setResponseName(getCommandName()); + setResponseObject(response); + } catch (MalformedURLException e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "malformedurl exception: " + e.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = _accountService.finalyzeAccountId(getAccountName(), getDomainId(), getProjectId(), true); + if (accountId == null) { + return CallContext.current().getCallingAccount().getId(); + } + return accountId; + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolume.java b/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolume.java new file mode 100644 index 00000000000..062c00868a6 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/volume/GetUploadParamsForVolume.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.volume; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.UUID; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.AbstractGetUploadParamsCommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DiskOfferingResponse; +import org.apache.cloudstack.api.response.GetUploadParamsResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; + +@APICommand(name = "getUploadParamsForVolume", description = "Upload a data disk to the cloudstack cloud.", responseObject = GetUploadParamsResponse.class, since = "4.6.0", + requestHasSensitiveInfo= false, responseHasSensitiveInfo = false) +public class GetUploadParamsForVolume extends AbstractGetUploadParamsCommand { + public static final Logger s_logger = Logger.getLogger(GetUploadParamsForVolume.class.getName()); + + private static final String s_name = "postuploadvolumeresponse"; + + @Parameter(name = ApiConstants.IMAGE_STORE_UUID, type = CommandType.STRING, description = "Image store uuid") + private String imageStoreUuid; + + @Parameter(name = ApiConstants.DISK_OFFERING_ID, required = false, type = CommandType.UUID, entityType = DiskOfferingResponse.class, description = "the ID of the disk " + + "offering. This must be a custom sized offering since during upload of volume/template size is unknown.") + private Long diskOfferingId; + + public String getImageStoreUuid() { + return imageStoreUuid; + } + + public Long getDiskOfferingId() { + return diskOfferingId; + } + + @Override + public void execute() throws ServerApiException { + // TODO Auto-generated method stub + try { + GetUploadParamsResponse response = createGetUploadParamsResponse( + UUID.fromString("C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"), + new URL("https://1-2-3-4.xyz.com/upload/C7D351D2-F167-4CC8-A9FF-3BECB0A625C4"), + "TKPFeuz2nHmE/kcREEu24mnj1MrLdzOeJIHXR9HLIGgk56bkRJHaD0RRL2lds1rKKhrro4/PuleEh4YhRinhxaAmPpU4e55eprG8gTCX0ItyFAtlZViVdKXMew5Dfp4Qg8W9I1/IsDJd2Kas9/ftDQLiemAlPt0uS7Ou6asOCpifnBaKvhM4UGEjHSnni1KhBzjgEyDW3Y42HKJSSv58Sgmxl9LCewBX8vtn9tXKr+j4afj7Jlh7DFhyo9HOPC5ogR4hPBKqP7xF9tHxAyq6YqfBzsng3Xwe+Pb8TU1kFHg1l2DM4tY6ooW2h8lOhWUkrJu4hOAOeTeRtCjW3H452NKoeA1M8pKWuqMo5zRMti2u2hNZs0YY2yOy8oWMMG+lG0hvIlajqEU=", + "2014-10-17T12:00:00+0530", "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"); + response.setResponseName(getCommandName()); + setResponseObject(response); + + } catch (MalformedURLException e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "malformedurl exception: " + e.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = _accountService.finalyzeAccountId(getAccountName(), getDomainId(), getProjectId(), true); + if (accountId == null) { + return CallContext.current().getCallingAccount().getId(); + } + return accountId; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/GetUploadParamsResponse.java b/api/src/org/apache/cloudstack/api/response/GetUploadParamsResponse.java new file mode 100644 index 00000000000..e379643e596 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/GetUploadParamsResponse.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.response; + +import java.net.URL; +import java.util.UUID; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class GetUploadParamsResponse extends BaseResponse { + + @SerializedName(ApiConstants.ID) + @Param(description = "the template/volume ID") + private UUID id; + + @Param(name = ApiConstants.URL, description = "POST url to upload the file to") + private URL postURL; + + @SerializedName(ApiConstants.METADATA) + @Param(description = "encrypted data to be sent in the POST request.") + private String metadata; + + @SerializedName(ApiConstants.TIMEOUT) + @Param(description = "the timestamp after which the signature expires") + private String timeout; + + @SerializedName(ApiConstants.SIGNATURE) + @Param(description = "signature to be sent in the POST request.") + private String signature; + + public GetUploadParamsResponse(UUID id, URL postURL, String metadata, String timeout, String signature) { + this.id = id; + this.postURL = postURL; + this.metadata = metadata; + this.timeout = timeout; + this.signature = signature; + setObjectName("getuploadparams"); + } + + public void setId(UUID id) { + this.id = id; + } + + public void setPostURL(URL postURL) { + this.postURL = postURL; + } + + public void setMetadata(String metadata) { + this.metadata = metadata; + } + + public void setTimeout(String timeout) { + this.timeout = timeout; + } + + public void setSignature(String signature) { + this.signature = signature; + } +} diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index ce84e697109..924c51439de 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -775,3 +775,7 @@ listOpenDaylightControllers=1 ### GloboDNS commands addGloboDnsHost=1 + +### volume/template post upload +getUploadParamsForVolume=15 +getUploadParamsForTemplate=15 diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index e089cd14ecb..4bbee0fd8a2 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -38,6 +38,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.api.command.user.snapshot.UpdateSnapshotPolicyCmd; +import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplate; +import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolume; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.ControlledEntity; @@ -2994,7 +2996,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(UpdateVPCCmdByAdmin.class); cmdList.add(UpdateLBStickinessPolicyCmd.class); cmdList.add(UpdateLBHealthCheckPolicyCmd.class); - + cmdList.add(GetUploadParamsForTemplate.class); + cmdList.add(GetUploadParamsForVolume.class); return cmdList; }