From a50c09283613b2f6a6f4fbe105348e4f2b46feac Mon Sep 17 00:00:00 2001 From: Richard Downer Date: Wed, 1 Feb 2012 17:03:00 +0000 Subject: [PATCH] Add the EC2 API call "GetPasswordData" to retrieve the encrypted Windows Administrator password. --- .../org/jclouds/ec2/domain/PasswordData.java | 129 ++++++++++++++++++ .../ec2/services/WindowsAsyncClient.java | 13 ++ .../jclouds/ec2/services/WindowsClient.java | 11 ++ .../xml/GetPasswordDataResponseHandler.java | 58 ++++++++ 4 files changed, 211 insertions(+) create mode 100644 apis/ec2/src/main/java/org/jclouds/ec2/domain/PasswordData.java create mode 100644 apis/ec2/src/main/java/org/jclouds/ec2/xml/GetPasswordDataResponseHandler.java diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/PasswordData.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/PasswordData.java new file mode 100644 index 0000000000..cea5639dd5 --- /dev/null +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/PasswordData.java @@ -0,0 +1,129 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.ec2.domain; + +import java.util.Date; + +/** + * Holds the encrypted Windows Administrator password for an instance. + * + * @author Richard Downer + */ +public class PasswordData { + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String requestId; + private String instanceId; + private Date timestamp; + private String passwordData; + + private Builder() {} + + public Builder requestId(String requestId) { + this.requestId = requestId; + return this; + } + + public Builder instanceId(String instanceId) { + this.instanceId = instanceId; + return this; + } + + public Builder timestamp(Date timestamp) { + this.timestamp = timestamp; + return this; + } + + public Builder passwordData(String passwordData) { + this.passwordData = passwordData; + return this; + } + + public PasswordData build() { + return new PasswordData(requestId, instanceId, timestamp, passwordData); + } + } + + private String requestId; + private String instanceId; + private Date timestamp; + private String passwordData; + + public PasswordData(String requestId, String instanceId, Date timestamp, String passwordData) { + this.requestId = requestId; + this.instanceId = instanceId; + this.timestamp = timestamp; + this.passwordData = passwordData; + } + + public String getRequestId() { + return requestId; + } + + public String getInstanceId() { + return instanceId; + } + + public Date getTimestamp() { + return timestamp; + } + + public String getPasswordData() { + return passwordData; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PasswordData that = (PasswordData) o; + + if (instanceId != null ? !instanceId.equals(that.instanceId) : that.instanceId != null) return false; + if (passwordData != null ? !passwordData.equals(that.passwordData) : that.passwordData != null) return false; + if (requestId != null ? !requestId.equals(that.requestId) : that.requestId != null) return false; + if (timestamp != null ? !timestamp.equals(that.timestamp) : that.timestamp != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = requestId != null ? requestId.hashCode() : 0; + result = 31 * result + (instanceId != null ? instanceId.hashCode() : 0); + result = 31 * result + (timestamp != null ? timestamp.hashCode() : 0); + result = 31 * result + (passwordData != null ? passwordData.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "PasswordData{" + + "requestId='" + requestId + '\'' + + ", instanceId='" + instanceId + '\'' + + ", timestamp=" + timestamp + + ", passwordData='" + passwordData + '\'' + + '}'; + } +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsAsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsAsyncClient.java index 5710656611..c5e2383c73 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsAsyncClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsAsyncClient.java @@ -23,6 +23,8 @@ import static org.jclouds.aws.reference.FormParameters.VERSION; import java.util.Set; +import org.jclouds.ec2.domain.PasswordData; +import org.jclouds.ec2.xml.GetPasswordDataResponseHandler; import org.jclouds.javax.annotation.Nullable; import javax.ws.rs.FormParam; import javax.ws.rs.POST; @@ -96,4 +98,15 @@ public interface WindowsAsyncClient { @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @BinderParam(BindBundleIdsToIndexedFormParams.class) String... bundleTaskIds); + /** + * @see WindowsClient#getPasswordData + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "GetPasswordData") + @XMLResponseParser(GetPasswordDataResponseHandler.class) + ListenableFuture getPasswordData( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @FormParam("InstanceId") String instanceId); + } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsClient.java index ae04093cea..e22284b118 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/WindowsClient.java @@ -21,6 +21,7 @@ package org.jclouds.ec2.services; import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jclouds.ec2.domain.PasswordData; import org.jclouds.javax.annotation.Nullable; import org.jclouds.ec2.domain.BundleTask; @@ -109,4 +110,14 @@ public interface WindowsClient { * /> */ Set describeBundleTasksInRegion(@Nullable String region, String... bundleTaskIds); + + /** + * + * Retrieves the encrypted administrator password for the instances running Windows. + * + * @param region The region where the instance is based + * @param instanceId The ID of the instance to query + * @see + */ + PasswordData getPasswordData(@Nullable String region, String instanceId); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/GetPasswordDataResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/GetPasswordDataResponseHandler.java new file mode 100644 index 0000000000..3cdd7d80e9 --- /dev/null +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/GetPasswordDataResponseHandler.java @@ -0,0 +1,58 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.ec2.xml; + +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.PasswordData; +import org.jclouds.http.functions.ParseSax; + +import javax.inject.Inject; + +/** + * @author Richard Downer + */ +public class GetPasswordDataResponseHandler extends ParseSax.HandlerWithResult { + + private StringBuilder currentText = new StringBuilder(); + private PasswordData.Builder builder = PasswordData.builder(); + @Inject protected DateService dateService; + + @Override + public PasswordData getResult() { + return builder.build(); + } + + public void endElement(String uri, String name, String qName) { + if (qName.equals("requestId")) { + builder.requestId(currentText.toString().trim()); + } else if (qName.equals("instanceId")) { + builder.instanceId(currentText.toString().trim()); + } else if (qName.equals("timestamp")) { + builder.timestamp(dateService.iso8601DateParse(currentText.toString().trim())); + } else if (qName.equals("passwordData")) { + builder.passwordData(currentText.toString().trim()); + } + currentText = new StringBuilder(); + } + + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + +}