summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSelvasundaram <selvam@gluster.com>2011-07-18 22:11:44 +0530
committerSelvasundaram <selvam@gluster.com>2011-07-18 22:11:44 +0530
commit948ef913fae74a9b67f0901d7bbf9153c52bfffb (patch)
tree921cc444fe33260acafd6b4ab8655644b561a557 /src
parent691f4b7519a7758de9316766d9963d68cdd50924 (diff)
Import SSH keys feature
Diffstat (limited to 'src')
-rw-r--r--src/com.gluster.storage.management.client/.classpath1
-rw-r--r--src/com.gluster.storage.management.client/META-INF/MANIFEST.MF1
-rw-r--r--src/com.gluster.storage.management.client/build.properties3
-rw-r--r--src/com.gluster.storage.management.client/lib/jersey-1.5/jersey-multipart-1.5.jarbin0 -> 49330 bytes
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java51
-rw-r--r--src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/KeysClient.java20
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java20
-rw-r--r--src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ImportSshKeysAction.java35
-rw-r--r--src/com.gluster.storage.management.server/.classpath1
-rw-r--r--src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jersey-multipart-1.5.jarbin0 -> 49330 bytes
-rw-r--r--src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/mimepull-1.3.jarbin0 -> 38683 bytes
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/KeysResource.java70
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java2
13 files changed, 147 insertions, 57 deletions
diff --git a/src/com.gluster.storage.management.client/.classpath b/src/com.gluster.storage.management.client/.classpath
index 218503d5..b90a101e 100644
--- a/src/com.gluster.storage.management.client/.classpath
+++ b/src/com.gluster.storage.management.client/.classpath
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
+ <classpathentry exported="true" kind="lib" path="lib/jersey-1.5/jersey-multipart-1.5.jar"/>
<classpathentry exported="true" kind="lib" path="keystore/"/>
<classpathentry exported="true" kind="lib" path="lib/jersey-1.5/jersey-client-1.5.jar" sourcepath="/home/selvam/sources/jersey/jersey-client-1.5-sources.jar"/>
<classpathentry exported="true" kind="lib" path="lib/jersey-1.5/jersey-core-1.5.jar" sourcepath="/home/selvam/sources/jersey/jersey-core-1.5-sources.jar"/>
diff --git a/src/com.gluster.storage.management.client/META-INF/MANIFEST.MF b/src/com.gluster.storage.management.client/META-INF/MANIFEST.MF
index 56cfe32e..dcd16136 100644
--- a/src/com.gluster.storage.management.client/META-INF/MANIFEST.MF
+++ b/src/com.gluster.storage.management.client/META-INF/MANIFEST.MF
@@ -12,4 +12,5 @@ Export-Package: com.gluster.storage.management.client,
Bundle-ClassPath: .,
lib/jersey-1.5/jersey-client-1.5.jar,
lib/jersey-1.5/jersey-core-1.5.jar,
+ lib/jersey-1.5/jersey-multipart-1.5.jar,
keystore/
diff --git a/src/com.gluster.storage.management.client/build.properties b/src/com.gluster.storage.management.client/build.properties
index 4dded7a7..bc0c59d7 100644
--- a/src/com.gluster.storage.management.client/build.properties
+++ b/src/com.gluster.storage.management.client/build.properties
@@ -3,7 +3,8 @@ output.. = bin/
bin.includes = .,\
META-INF/,\
lib/,\
- keystore/
+ keystore/,\
+ lib/jersey-1.5/jersey-multipart-1.5.jar
src.includes = src/,\
lib/,\
keystore/,\
diff --git a/src/com.gluster.storage.management.client/lib/jersey-1.5/jersey-multipart-1.5.jar b/src/com.gluster.storage.management.client/lib/jersey-1.5/jersey-multipart-1.5.jar
new file mode 100644
index 00000000..1c134f05
--- /dev/null
+++ b/src/com.gluster.storage.management.client/lib/jersey-1.5/jersey-multipart-1.5.jar
Binary files differ
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java
index 92037741..64a9a653 100644
--- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java
+++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/AbstractClient.java
@@ -35,7 +35,7 @@ import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.representation.Form;
import com.sun.jersey.client.urlconnection.HTTPSProperties;
import com.sun.jersey.core.util.MultivaluedMapImpl;
-
+import com.sun.jersey.multipart.FormDataMultiPart;
public abstract class AbstractClient {
private static final String HTTP_HEADER_AUTH = "Authorization";
@@ -66,7 +66,7 @@ public abstract class AbstractClient {
this.clusterName = clusterName;
setSecurityToken(securityToken);
- createClient();
+ createClient();
// this must be after setting clusterName as sub-classes may refer to cluster name in the getResourcePath method
resource = client.resource(ClientUtil.getServerBaseURI()).path(getResourcePath());
@@ -143,10 +143,10 @@ public abstract class AbstractClient {
}
private GlusterRuntimeException createGlusterException(Exception e) {
- if(e instanceof GlusterRuntimeException) {
- return (GlusterRuntimeException)e;
+ if (e instanceof GlusterRuntimeException) {
+ return (GlusterRuntimeException) e;
}
-
+
if (e instanceof UniformInterfaceException) {
UniformInterfaceException uie = (UniformInterfaceException) e;
if ((uie.getResponse().getStatus() == Response.Status.UNAUTHORIZED.getStatusCode())) {
@@ -177,9 +177,9 @@ public abstract class AbstractClient {
InputStream inputStream = response.getEntityInputStream();
FileOutputStream outputStream = new FileOutputStream(filePath);
-
+
int c;
- while((c = inputStream.read()) != -1) {
+ while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
inputStream.close();
@@ -188,13 +188,14 @@ public abstract class AbstractClient {
throw new GlusterRuntimeException("Error while downloading resource [" + res.getURI().getPath() + "]", e);
}
}
-
-
-/* public void uploadResource(WebResource res, FormDataMultiPart form) {
- ClientResponse response = res.header(HTTP_HEADER_AUTH, authHeader).type(MediaType.MULTIPART_FORM_DATA)
- .accept(MediaType.TEXT_PLAIN).header(name, value)post(form);
+
+ public void uploadResource(WebResource res, FormDataMultiPart form) {
+ try {
+ res.header(HTTP_HEADER_AUTH, authHeader).type(MediaType.MULTIPART_FORM_DATA_TYPE).post(String.class, form);
+ } catch (Exception e) {
+ throw new GlusterRuntimeException("Error while importing resource [" + e.getMessage() + "]", e);
+ }
}
-*/
/**
* Fetches the default resource (the one returned by {@link AbstractClient#getResourcePath()}) by dispatching a GET
@@ -306,7 +307,7 @@ public abstract class AbstractClient {
protected void postRequest(String subResourceName, Form form) {
postRequest(resource.path(subResourceName), form);
}
-
+
private ClientResponse putRequest(WebResource resource, Form form) {
try {
ClientResponse response = prepareFormRequestBuilder(resource).put(ClientResponse.class, form);
@@ -315,7 +316,7 @@ public abstract class AbstractClient {
setSecurityToken(null);
throw new GlusterRuntimeException("Invalid credentials!");
}
- if(response.getStatus() >= 300) {
+ if (response.getStatus() >= 300) {
throw new GlusterRuntimeException(response.getEntity(String.class));
}
return response;
@@ -325,10 +326,10 @@ public abstract class AbstractClient {
}
public Builder prepareFormRequestBuilder(WebResource resource) {
- return resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
- .header(HTTP_HEADER_AUTH, authHeader).accept(MediaType.APPLICATION_XML);
+ return resource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).header(HTTP_HEADER_AUTH, authHeader)
+ .accept(MediaType.APPLICATION_XML);
}
-
+
/**
* Submits given Form using PUT method to the given sub-resource and returns the object received as response
*
@@ -340,8 +341,7 @@ public abstract class AbstractClient {
protected void putRequest(String subResourceName, Form form) {
putRequest(resource.path(subResourceName), form);
}
-
-
+
protected URI putRequestURI(String subResourceName, Form form) {
ClientResponse response = putRequest(resource.path(subResourceName), form);
return response.getLocation();
@@ -373,13 +373,12 @@ public abstract class AbstractClient {
private void deleteResource(WebResource resource, MultivaluedMap<String, String> queryParams) {
try {
- resource.queryParams(queryParams).header(HTTP_HEADER_AUTH, authHeader)
- .delete();
+ resource.queryParams(queryParams).header(HTTP_HEADER_AUTH, authHeader).delete();
} catch (UniformInterfaceException e) {
throw new GlusterRuntimeException(e.getResponse().getEntity(String.class));
}
}
-
+
protected void deleteResource(MultivaluedMap<String, String> queryParams) {
deleteResource(resource, queryParams);
}
@@ -415,8 +414,10 @@ public abstract class AbstractClient {
}
/**
- * @param uri The URI to be fetched using GET API
- * @param responseClass Expected type of response object
+ * @param uri
+ * The URI to be fetched using GET API
+ * @param responseClass
+ * Expected type of response object
* @return Object of the given class
*/
protected <T> T fetchResource(URI uri, Class<T> responseClass) {
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/KeysClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/KeysClient.java
index dfadd67c..51fda466 100644
--- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/KeysClient.java
+++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/KeysClient.java
@@ -20,9 +20,13 @@
*/
package com.gluster.storage.management.client;
-import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import javax.ws.rs.core.MediaType;
import com.gluster.storage.management.core.constants.RESTConstants;
+import com.sun.jersey.multipart.FormDataMultiPart;
public class KeysClient extends AbstractClient {
@@ -30,10 +34,6 @@ public class KeysClient extends AbstractClient {
super();
}
- public KeysClient(String clusterName) {
- super(clusterName);
- }
-
@Override
public String getResourcePath() {
return RESTConstants.RESOURCE_KEYS;
@@ -43,7 +43,13 @@ public class KeysClient extends AbstractClient {
downloadResource(resource, filePath);
}
- public void importSshKeys(File keysFile) {
-
+ public void importSshKeys(String keysFile) {
+ FormDataMultiPart form = new FormDataMultiPart();
+ try {
+ form.field("file", new FileInputStream(keysFile), MediaType.TEXT_PLAIN_TYPE);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ uploadResource(resource, form);
}
}
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java
index 0f8121e6..ef7d0979 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java
@@ -52,17 +52,10 @@ public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDe
// Real action code must be executed using Display#asyncExec.
// Otherwise the system can hang when opening new dialog boxes on linux platform
try {
- PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
- public void run(final IProgressMonitor monitor) {
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- monitor.beginTask(action.getDescription(), 1);
- performAction(action);
- monitor.worked(1);
- monitor.done();
- }
- });
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ performAction(action);
}
});
} catch (final Exception e) {
@@ -102,10 +95,7 @@ public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDe
}
protected Shell getShell() {
- if(window == null) {
- return Display.getDefault().getActiveShell();
- }
- return window.getShell();
+ return getWindow().getShell();
}
protected IWorkbenchWindow getWindow() {
diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ImportSshKeysAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ImportSshKeysAction.java
index 8cedc920..a166f509 100644
--- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ImportSshKeysAction.java
+++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/ImportSshKeysAction.java
@@ -1,17 +1,44 @@
package com.gluster.storage.management.gui.actions;
import org.eclipse.jface.action.IAction;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+
+import com.gluster.storage.management.client.KeysClient;
public class ImportSshKeysAction extends AbstractActionDelegate {
-
@Override
protected void performAction(IAction action) {
-
- }
+ final KeysClient client = new KeysClient();
+
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
+ dialog.setText("Open");
+ dialog.setFilterNames(new String[] { "ssh-keys (*.tar)" });
+ dialog.setFilterExtensions(new String[] { "*.tar" });
+
+ String selectedFile = dialog.open();
+ if (selectedFile == null) {
+ return;
+ }
+
+ String title = "Import SSH Keys";
+ try {
+ client.importSshKeys(selectedFile);
+ showInfoDialog(title, "SSH keys imported successfully!");
+ } catch (Exception e) {
+ showErrorDialog(title, e.getMessage());
+ }
+ }
+ });
+ }
@Override
public void dispose() {
}
-
}
diff --git a/src/com.gluster.storage.management.server/.classpath b/src/com.gluster.storage.management.server/.classpath
index 59631d14..107e139d 100644
--- a/src/com.gluster.storage.management.server/.classpath
+++ b/src/com.gluster.storage.management.server/.classpath
@@ -10,5 +10,6 @@
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry combineaccessrules="false" kind="src" path="/com.gluster.storage.management.core"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry exported="true" kind="lib" path="/com.gluster.storage.management.client/lib/jersey-1.5/jersey-multipart-1.5.jar"/>
<classpathentry kind="output" path="WebContent/WEB-INF/classes"/>
</classpath>
diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jersey-multipart-1.5.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jersey-multipart-1.5.jar
new file mode 100644
index 00000000..1c134f05
--- /dev/null
+++ b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/jersey-multipart-1.5.jar
Binary files differ
diff --git a/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/mimepull-1.3.jar b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/mimepull-1.3.jar
new file mode 100644
index 00000000..48cc9295
--- /dev/null
+++ b/src/com.gluster.storage.management.server/WebContent/WEB-INF/lib/mimepull-1.3.jar
Binary files differ
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/KeysResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/KeysResource.java
index a589c2a2..36443a4c 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/KeysResource.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/KeysResource.java
@@ -23,10 +23,15 @@ package com.gluster.storage.management.server.resources.v1_0;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_KEYS;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Date;
+import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
@@ -34,14 +39,17 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
+import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
import com.gluster.storage.management.core.utils.FileUtil;
+import com.gluster.storage.management.core.utils.ProcessResult;
import com.gluster.storage.management.core.utils.ProcessUtil;
import com.gluster.storage.management.server.utils.SshUtil;
+import com.sun.jersey.multipart.FormDataParam;
@Path(RESOURCE_PATH_KEYS)
public class KeysResource extends AbstractResource {
+ ProcessUtil processUtil = new ProcessUtil();
-
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response exportSshkeys() {
@@ -65,25 +73,79 @@ public class KeysResource extends AbstractResource {
}
}
- public String createSskKeyZipFile() {
+ private String createSskKeyZipFile() {
String targetDir = System.getProperty("java.io.tmpdir");
String zipFile = targetDir + "ssh-keys.tar";
String sourcePemFile = SshUtil.PEM_FILE.getAbsolutePath();
String sourcePubKeyFile = SshUtil.PUBLIC_KEY_FILE.getAbsolutePath();
String targetPemFile = targetDir + File.separator + SshUtil.PEM_FILE.getName();
String targetPubKeyFile = targetDir + File.separator + SshUtil.PUBLIC_KEY_FILE.getName();
- ProcessUtil processUtil = new ProcessUtil();
// Copy keys to temp folder
processUtil.executeCommand("cp", sourcePemFile, targetPemFile);
processUtil.executeCommand("cp", sourcePubKeyFile, targetPubKeyFile);
// To zip the key files
- processUtil.executeCommand("tar", "cvf", zipFile, "-C", "/tmp", SshUtil.PEM_FILE.getName(), SshUtil.PUBLIC_KEY_FILE.getName());
+ processUtil.executeCommand("tar", "cvf", zipFile, "-C", "/tmp", SshUtil.PEM_FILE.getName(),
+ SshUtil.PUBLIC_KEY_FILE.getName());
// To remove the copied key files
processUtil.executeCommand("rm", "-f", targetPubKeyFile, targetPubKeyFile);
return zipFile;
}
+
+ @POST
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @SuppressWarnings({"deprecation" })
+ public Response importSshKeys(@FormDataParam("file") InputStream uploadedInputStream) {
+ File uploadedFile = new File(System.getProperty("java.io.tmpdir") + File.separator + "keys.tar");
+ Date today = new Date();
+ try {
+ writeToFile(uploadedInputStream, uploadedFile.getAbsolutePath());
+
+ // To backup existing SSH pem and public keys
+ if (SshUtil.PEM_FILE.isFile()) {
+ if (!SshUtil.PEM_FILE
+ .renameTo(new File(SshUtil.PEM_FILE.getAbsolutePath() + "-" + today.toString()))) {
+ throw new GlusterRuntimeException("Unable to backup pem key!");
+ }
+ }
+
+ if (SshUtil.PUBLIC_KEY_FILE.isFile()) {
+ if (!SshUtil.PUBLIC_KEY_FILE.renameTo(new File(SshUtil.PUBLIC_KEY_FILE.getAbsolutePath() + "-"
+ + today.toString()))) {
+ throw new GlusterRuntimeException("Unable to backup public key!");
+ }
+ }
+ // Extract SSH pem and public key files.
+ ProcessResult output = processUtil.executeCommand("tar", "xvf", uploadedFile.getName(), "-C",
+ SshUtil.SSH_AUTHORIZED_KEYS_DIR);
+ uploadedFile.delete();
+ if (output.isSuccess()) {
+ return createdResponse("SSH Key imported successfully");
+ } else {
+ return errorResponse(output.getOutput());
+ }
+ } catch (Exception e) {
+ return errorResponse(e.getMessage());
+ }
+ }
+
+ // save uploaded file to the file (with path)
+ private void writeToFile(InputStream inputStream, String toFile) {
+ try {
+ int read = 0;
+ byte[] bytes = new byte[1024];
+
+ OutputStream out = new FileOutputStream(new File(toFile));
+ while ((read = inputStream.read(bytes)) != -1) {
+ out.write(bytes, 0, read);
+ }
+ out.flush();
+ out.close();
+ } catch (IOException e) {
+ throw new GlusterRuntimeException(e.getMessage());
+ }
+ }
}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java
index 4771a230..746b8832 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/SshUtil.java
@@ -49,7 +49,7 @@ import com.gluster.storage.management.core.utils.ProcessResult;
@Component
public class SshUtil {
private static final String TEMP_DIR = "/tmp/";
- private static final String SSH_AUTHORIZED_KEYS_DIR = "/root/.ssh/";
+ public static final String SSH_AUTHORIZED_KEYS_DIR = "/root/.ssh/";
private static final String SSH_AUTHORIZED_KEYS_FILE = "authorized_keys";
private static final String SSH_AUTHORIZED_KEYS_PATH = SSH_AUTHORIZED_KEYS_DIR + SSH_AUTHORIZED_KEYS_FILE;
private LRUCache<String, Connection> sshConnCache = new LRUCache<String, Connection>(10);