diff options
| author | Shireesh Anjal <shireesh@gluster.com> | 2011-06-01 21:01:28 +0530 |
|---|---|---|
| committer | Shireesh Anjal <shireesh@gluster.com> | 2011-06-02 16:43:16 +0530 |
| commit | 21681dbcefdaa854ca1f8ac210914438ca903443 (patch) | |
| tree | 9a39283d6a4b9c9bceeab7ab0c3755851b7b68df /src | |
| parent | 4507d18b193524c69186f1cfb26e99daa8d50fdc (diff) | |
Design changes - introducing cluster-server mapping on gateway
Diffstat (limited to 'src')
3 files changed, 136 insertions, 42 deletions
diff --git a/src/com.gluster.storage.management.server/.project b/src/com.gluster.storage.management.server/.project index 86d34a3b..259b3726 100644 --- a/src/com.gluster.storage.management.server/.project +++ b/src/com.gluster.storage.management.server/.project @@ -37,6 +37,5 @@ <nature>org.eclipse.wst.common.project.facet.core.nature</nature> <nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.wst.jsdt.core.jsNature</nature> - <nature>org.python.pydev.pythonNature</nature> </natures> </projectDescription> diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java index b364db29..15992608 100644 --- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java +++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/GlusterServersResource.java @@ -41,6 +41,7 @@ import org.springframework.stereotype.Component; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; import com.gluster.storage.management.core.model.Status; @@ -65,6 +66,9 @@ public class GlusterServersResource extends AbstractServersResource { @Autowired private PersistenceDao<ClusterInfo> clusterDao; + @Autowired + private SshUtil sshUtil; + protected void fetchServerDetails(GlusterServer server) { try { server.setStatus(SERVER_STATUS.ONLINE); @@ -170,6 +174,28 @@ public class GlusterServersResource extends AbstractServersResource { return new GlusterServerResponse(status, server); } + private Status performAddServer(String clusterName, String serverName) { + GlusterServer onlineServer = getOnlineServer(clusterName); + if(onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, + "No online server found in cluster [" + clusterName + "]"); + } + + Status status; + try { + status = glusterUtil.addServer(serverName, onlineServer.getName()); + } catch(ConnectionException e) { + onlineServer = getNewOnlineServer(clusterName); + if(onlineServer == null) { + return new Status(Status.STATUS_CODE_FAILURE, + "No online server found in cluster [" + clusterName + "]"); + } + status = glusterUtil.addServer(serverName, onlineServer.getName()); + } + + return status; + } + @POST @Produces(MediaType.TEXT_XML) public GlusterServerResponse addServer(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @@ -180,33 +206,51 @@ public class GlusterServersResource extends AbstractServersResource { + "] doesn't exist!"), null); } + boolean publicKeyInstalled = sshUtil.isPublicKeyInstalled(serverName); + if(!publicKeyInstalled && !sshUtil.hasDefaultPassword(serverName)) { + // public key not installed, default password doesn't work. return with error. + return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, + "Gluster Management Gateway uses the default password to set up keys on the server." + + CoreConstants.NEWLINE + "However it seems that the password on server [" + serverName + + "] has been changed manually." + CoreConstants.NEWLINE + + "Please reset it back to the standard default password and try again."), null); + } + if(!cluster.getServers().isEmpty()) { - GlusterServer onlineServer = getOnlineServer(clusterName); - if(onlineServer == null) { - return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, - "No online server found in cluster [" + clusterName + "]"), null); - } - - Status status; - try { - status = glusterUtil.addServer(serverName, onlineServer.getName()); - } catch(ConnectionException e) { - onlineServer = getNewOnlineServer(clusterName); - if(onlineServer == null) { - return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, - "No online server found in cluster [" + clusterName + "]"), null); - } - status = glusterUtil.addServer(serverName, onlineServer.getName()); - } - - if (!status.isSuccess()) { + Status status = performAddServer(clusterName, serverName); + if(!status.isSuccess()) { return new GlusterServerResponse(status, null); } } else { - // this is the first server to be added to the cluster, which means - // no gluster operation required. just add it to the cluster-server mapping + // this is the first server to be added to the cluster, which means no + // gluster CLI operation required. just add it to the cluster-server mapping } + // fetch server details + GlusterServerResponse serverResponse = getGlusterServer(clusterName, serverName); + + try { + // install public key (this will also disable password based ssh login) + sshUtil.installPublicKey(serverName); + } catch(Exception e) { + return new GlusterServerResponse(new Status(Status.STATUS_CODE_PART_SUCCESS, + "Public key could not be installed! Error: [" + e.getMessage() + + "]"), serverResponse.getGlusterServer()); + } + + try { + addServerToCluster(clusterName, serverName); + } catch (Exception e){ + return new GlusterServerResponse(new Status(Status.STATUS_CODE_PART_SUCCESS, + "Exception while trying to save cluster-server mapping [" + clusterName + "][" + serverName + + "]: [" + e.getMessage() + "]"), serverResponse.getGlusterServer()); + } + + return serverResponse; + } + + private void addServerToCluster(String clusterName, String serverName) { + ClusterInfo cluster; EntityTransaction txn = clusterDao.startTransaction(); // Inside a transaction, we must fetch the ClusterInfo object again. cluster = getCluster(clusterName); @@ -215,13 +259,8 @@ public class GlusterServersResource extends AbstractServersResource { txn.commit(); } catch (Exception e) { txn.rollback(); - return new GlusterServerResponse(new Status(Status.STATUS_CODE_FAILURE, - "Exception while trying to save cluster-server mapping [" + clusterName + "][" + serverName - + "]: [" + e.getMessage() + "]"), null); + throw new GlusterRuntimeException("Couldn't commit transaction! Error: " + e.getMessage(), e); } - - // TODO: Install ssh key on new server - return getGlusterServer(clusterName, serverName); } private ClusterInfo getCluster(String clusterName) { 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 cac71f9c..04639ba9 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 @@ -20,6 +20,8 @@ package com.gluster.storage.management.server.utils; import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; @@ -30,12 +32,14 @@ import org.springframework.stereotype.Component; import ch.ethz.ssh2.ChannelCondition; import ch.ethz.ssh2.Connection; +import ch.ethz.ssh2.SCPClient; import ch.ethz.ssh2.Session; import ch.ethz.ssh2.StreamGobbler; import com.gluster.storage.management.core.constants.CoreConstants; import com.gluster.storage.management.core.exceptions.ConnectionException; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.utils.FileUtil; import com.gluster.storage.management.core.utils.LRUCache; import com.gluster.storage.management.core.utils.ProcessResult; @@ -44,13 +48,78 @@ 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/"; + 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); - private static final File PEM_FILE = new File(CoreConstants.USER_HOME + "/" + ".ssh/id_rsa"); + private static final File PEM_FILE = new File(CoreConstants.USER_HOME + File.separator + ".ssh/id_rsa"); + private static final File PUBLIC_KEY_FILE = new File(CoreConstants.USER_HOME + File.separator + ".ssh/id_rsa.pub"); + // TODO: Make user name configurable private static final String USER_NAME = "root"; // TODO: Make default password configurable private static final String DEFAULT_PASSWORD = "syst3m"; + public boolean hasDefaultPassword(String serverName) { + try { + getConnectionWithPassword(serverName); + return true; + } catch(ConnectionException e) { + return false; + } + } + + public boolean isPublicKeyInstalled(String serverName) { + try { + getConnection(serverName); + return true; + } catch(ConnectionException e) { + return false; + } + } + + public synchronized void installPublicKey(String serverName) { + Connection conn = getConnectionWithPassword(serverName); + SCPClient scpClient = new SCPClient(conn); + + // delete file if it exists + File localTempFile = new File(TEMP_DIR + SSH_AUTHORIZED_KEYS_FILE); + if(localTempFile.exists()) { + localTempFile.delete(); + } + try { + + // get authorized_keys from server + scpClient.get(SSH_AUTHORIZED_KEYS_PATH, TEMP_DIR); + } catch (IOException e) { + // file doesn't exist. it will get created. + } + + byte[] publicKeyData; + try { + publicKeyData = new FileUtil().readFileAsByteArray(PUBLIC_KEY_FILE); + } catch (Exception e) { + throw new GlusterRuntimeException("Couldn't load public key file [" + PUBLIC_KEY_FILE + "]", e); + } + + try { + // append it + FileOutputStream outputStream = new FileOutputStream(localTempFile, true); + outputStream.write(CoreConstants.NEWLINE.getBytes()); + outputStream.write(publicKeyData); + outputStream.close(); + } catch (Exception e) { + throw new GlusterRuntimeException("Couldnt append file [" + localTempFile + "] with public key!", e); + } + + try { + scpClient.put(localTempFile.getAbsolutePath(), SSH_AUTHORIZED_KEYS_FILE, SSH_AUTHORIZED_KEYS_DIR, "0600"); + } catch (IOException e) { + throw new GlusterRuntimeException("Couldn't add public key to server [" + serverName + "]", e); + } + } + private Connection getConnectionWithPassword(String serverName) { Connection conn = createConnection(serverName); authenticateWithPassword(conn); @@ -254,17 +323,4 @@ public class SshUtil { conn.close(); } } - - public static void main(String[] args) { - SshUtil sshUtil = new SshUtil(); - System.out.println(new Date()); - ProcessResult result = sshUtil.executeRemote("dev.gluster.com", "/bin/pwd"); - System.out.println(result.getOutput()); - result = sshUtil.executeRemote("dev.gluster.com", "/bin/pwd1"); - System.out.println(new Date() + " - " + result.getExitValue() + " - " + result.getOutput()); - result = sshUtil.executeRemote("dev.gluster.com", "/bin/ls -lrt"); - System.out.println(new Date() + " - " + result.getExitValue() + " - " + result.getOutput()); - - sshUtil.cleanup(); - } } |
