diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClient.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClient.java index 7e3f21912f7..ca33af75962 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClient.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClient.java @@ -26,6 +26,13 @@ public interface SshServiceClient { */ Promise> getPairs(String service); + /** + * Gets ssh pair of given service and specific name + * @param service the service name + * @param name the identifier of one the pair + */ + Promise getPair(String service, String name); + /** * Generates new ssh key pair with given service and name */ diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClientImpl.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClientImpl.java index ee512ee9f48..6254647d84b 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClientImpl.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/ssh/SshServiceClientImpl.java @@ -16,7 +16,6 @@ import org.eclipse.che.api.ssh.shared.dto.GenerateSshPairRequest; import org.eclipse.che.api.ssh.shared.dto.SshPairDto; import org.eclipse.che.ide.MimeType; -import org.eclipse.che.ide.api.ssh.SshServiceClient; import org.eclipse.che.ide.dto.DtoFactory; import org.eclipse.che.ide.rest.AsyncRequestFactory; import org.eclipse.che.ide.rest.DtoUnmarshallerFactory; @@ -47,6 +46,18 @@ protected SshServiceClientImpl(@RestContext String baseUrl, this.sshApi = baseUrl + "/ssh"; } + /** + * Gets ssh pair of given service and specific name + * @param service the service name + * @param name the identifier of one the pair + */ + @Override + public Promise getPair(String service, String name) { + return asyncRequestFactory.createGetRequest(sshApi + "/" + service + "/" + name) + .header(HTTPHeader.ACCEPT, MimeType.APPLICATION_JSON) + .send(unmarshallerFactory.newUnmarshaller(SshPairDto.class)); + } + @Override public Promise> getPairs(String service) { return asyncRequestFactory.createGetRequest(sshApi + "/" + service) diff --git a/plugins/plugin-machine/che-plugin-machine-ext-client/pom.xml b/plugins/plugin-machine/che-plugin-machine-ext-client/pom.xml index f1b2fac2762..374e5042212 100644 --- a/plugins/plugin-machine/che-plugin-machine-ext-client/pom.xml +++ b/plugins/plugin-machine/che-plugin-machine-ext-client/pom.xml @@ -61,6 +61,10 @@ org.eclipse.che.core che-core-api-model + + org.eclipse.che.core + che-core-api-ssh-shared + org.eclipse.che.core che-core-api-user-shared diff --git a/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.java b/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.java index 86138c3152a..d62bec34b63 100644 --- a/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.java +++ b/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.java @@ -470,8 +470,13 @@ public interface MachineLocalizationConstant extends Messages { String failedToGetProcesses(String machineId); @Key("ssh.connect.info") - String sshConnectInfo(String machineName, String machineHost, String machinePort); + String sshConnectInfo(String machineName, String machineHost, String machinePort, String workspaceName, String userName, String sshKeyDetails); + @Key("ssh.connect.ssh.key.available") + String sshConnectInfoPrivateKey(String privateKey); + + @Key("ssh.connect.ssh.key.not.available") + String sshConnectInfoNoPrivateKey(); @Key("macro.current.project.relpath.description") String macroCurrentProjectRelpathDescription(); diff --git a/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenter.java b/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenter.java index e57ffe60ec8..b3cdb95078c 100644 --- a/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenter.java +++ b/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenter.java @@ -30,7 +30,9 @@ import org.eclipse.che.api.machine.shared.dto.MachineProcessDto; import org.eclipse.che.api.promises.client.Operation; import org.eclipse.che.api.promises.client.OperationException; +import org.eclipse.che.api.promises.client.Promise; import org.eclipse.che.api.promises.client.PromiseError; +import org.eclipse.che.api.ssh.shared.dto.SshPairDto; import org.eclipse.che.commons.annotation.Nullable; import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.command.CommandImpl; @@ -46,6 +48,7 @@ import org.eclipse.che.ide.api.outputconsole.OutputConsole; import org.eclipse.che.ide.api.parts.WorkspaceAgent; import org.eclipse.che.ide.api.parts.base.BasePresenter; +import org.eclipse.che.ide.api.ssh.SshServiceClient; import org.eclipse.che.ide.api.workspace.event.EnvironmentOutputEvent; import org.eclipse.che.ide.api.workspace.event.WorkspaceStartedEvent; import org.eclipse.che.ide.api.workspace.event.WorkspaceStoppedEvent; @@ -117,6 +120,7 @@ public class ProcessesPanelPresenter extends BasePresenter implements ProcessesP private final MachineLocalizationConstant localizationConstant; private final MachineResources resources; private final MachineServiceClient machineServiceClient; + private final SshServiceClient sshServiceClient; private final WorkspaceAgent workspaceAgent; private final AppContext appContext; private final NotificationManager notificationManager; @@ -148,11 +152,13 @@ public ProcessesPanelPresenter(ProcessesPanelView view, CommandConsoleFactory commandConsoleFactory, DialogFactory dialogFactory, ConsoleTreeContextMenuFactory consoleTreeContextMenuFactory, - CommandTypeRegistry commandTypeRegistry) { + CommandTypeRegistry commandTypeRegistry, + SshServiceClient sshServiceClient) { this.view = view; this.localizationConstant = localizationConstant; this.resources = resources; this.machineServiceClient = machineServiceClient; + this.sshServiceClient = sshServiceClient; this.workspaceAgent = workspaceAgent; this.appContext = appContext; this.notificationManager = notificationManager; @@ -409,23 +415,55 @@ public void onPreviewSsh(String machineId) { Machine machine = (Machine)machineTreeNode.getData(); - OutputConsole defaultConsole = commandConsoleFactory.create("SSH"); + final OutputConsole defaultConsole = commandConsoleFactory.create("SSH"); addCommandOutput(machineId, defaultConsole); - String machineName = machine.getConfig().getName(); + final String machineName = machine.getConfig().getName(); String sshServiceAddress = getSshServerAddress(machine); - String machineHost = ""; - String sshPort = SSH_PORT; + final String machineHost; + final String sshPort; if (sshServiceAddress != null) { String[] parts = sshServiceAddress.split(":"); machineHost = parts[0]; - sshPort = (parts.length == 2) ? parts[1] : sshPort; + sshPort = (parts.length == 2) ? parts[1] : SSH_PORT; + } else { + sshPort = SSH_PORT; + machineHost = ""; } - if (defaultConsole instanceof DefaultOutputConsole) { - ((DefaultOutputConsole)defaultConsole).enableAutoScroll(false); - ((DefaultOutputConsole)defaultConsole).printText(localizationConstant.sshConnectInfo(machineName, machineHost, sshPort)); + // user + final String userName; + String user = machine.getRuntime().getProperties().get("config.user"); + if (isNullOrEmpty(user)) { + userName = "root"; + } else { + userName = user; } + + // ssh key + final String workspaceName = appContext.getWorkspace().getConfig().getName(); + Promise sshPairDtoPromise = sshServiceClient.getPair("workspace", machine.getWorkspaceId()); + + sshPairDtoPromise.then(new Operation() { + @Override + public void apply(SshPairDto sshPairDto) throws OperationException { + if (defaultConsole instanceof DefaultOutputConsole) { + ((DefaultOutputConsole)defaultConsole).enableAutoScroll(false); + ((DefaultOutputConsole)defaultConsole).printText(localizationConstant.sshConnectInfo(machineName, machineHost, sshPort, workspaceName, userName, localizationConstant.sshConnectInfoPrivateKey(sshPairDto.getPrivateKey()))); + } + + } + } + ).catchError(new Operation() { + @Override + public void apply(PromiseError arg) throws OperationException { + if (defaultConsole instanceof DefaultOutputConsole) { + ((DefaultOutputConsole)defaultConsole).enableAutoScroll(false); + ((DefaultOutputConsole)defaultConsole).printText(localizationConstant.sshConnectInfo(machineName, machineHost, sshPort, workspaceName, userName, localizationConstant.sshConnectInfoNoPrivateKey())); + } + } + }); + } @Override diff --git a/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/resources/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.properties b/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/resources/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.properties index fc381119b1f..d1b67aaa83b 100644 --- a/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/resources/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.properties +++ b/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/resources/org/eclipse/che/ide/extension/machine/client/MachineLocalizationConstant.properties @@ -196,23 +196,18 @@ failed.to.find.machine=Failed to find machine {0} failed.to.get.processes=Failed to get processes from machine {0} ssh.connect.info=You can connect your SSH client to ''{0}'' with:\ +\n\n[ALL OS]\ +\nche ssh {3} {0}\ \n\n[LINUX | OSX]\ -\nssh user@{1} -p {2} [-i /path/to/your/private/ssh/key]\ +\nssh {4}@{1} -p {2} [-i /path/to/your/private/ssh/key]\ \n\n[WINDOWS]\ -\nputty -ssh -l user -P {2} {1} [-i /path/to/your/private/ssh/key]\ -\n\nUSERNAME: user\ -\nPASSWORD: secret\ -\n\nNOTES:\ -\n1. You can login with user / password, but it is not recommended.\ -\n2. Use an SSH key pair to securely authenticate.\ -\n3. You can generate new SSH key pairs at `Profile -> Preferences -> SSH -> Machine`\ -\n4. Or, you can upload your own public key.\ -\n5. You must restart your workspace for the keys to take affect.\ -\n6. You can verify your key by opening a terminal and viewing `/home/user/.ssh/authorized_keys`\ -\n\nWINDOWS USERS:\ -\n1. Download Putty and add it to your %PATH% environment.\ -\n2. Use PuttyGen to convert SSH keys generated by Che to putty PPK files.\ -\n3. Use the Putty .ppk file as the key reference. +\nputty -ssh -l {4} -P {2} {1} [-i /path/to/your/private/ssh/key]\ +\n\n[PARAMETERS]\ +\n\n{5} +ssh.connect.ssh.key.available=Workspace Private Key:\ +\n{0} +ssh.connect.ssh.key.not.available=There is no workspace key. A key can be generated in the dashboard in the workspace details / ssh tab + ################ Macros's descriptions ############# macro.current.project.relpath.description=The path to the currently selected project relative to /projects. Effectively removes the /projects path from any project reference diff --git a/plugins/plugin-machine/che-plugin-machine-ext-client/src/test/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenterTest.java b/plugins/plugin-machine/che-plugin-machine-ext-client/src/test/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenterTest.java index 5b2a6e95fea..65d10ee72a0 100644 --- a/plugins/plugin-machine/che-plugin-machine-ext-client/src/test/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenterTest.java +++ b/plugins/plugin-machine/che-plugin-machine-ext-client/src/test/java/org/eclipse/che/ide/extension/machine/client/processes/panel/ProcessesPanelPresenterTest.java @@ -33,18 +33,18 @@ import org.eclipse.che.ide.api.machine.MachineEntity; import org.eclipse.che.ide.api.machine.MachineManager; import org.eclipse.che.ide.api.machine.MachineServiceClient; +import org.eclipse.che.ide.api.machine.events.MachineStateEvent; import org.eclipse.che.ide.api.machine.events.WsAgentStateEvent; import org.eclipse.che.ide.api.notification.NotificationManager; import org.eclipse.che.ide.api.notification.StatusNotification; import org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode; import org.eclipse.che.ide.api.outputconsole.OutputConsole; import org.eclipse.che.ide.api.parts.WorkspaceAgent; -import org.eclipse.che.ide.api.workspace.event.EnvironmentOutputEvent; +import org.eclipse.che.ide.api.ssh.SshServiceClient; import org.eclipse.che.ide.extension.machine.client.MachineLocalizationConstant; import org.eclipse.che.ide.extension.machine.client.MachineResources; import org.eclipse.che.ide.extension.machine.client.inject.factories.EntityFactory; import org.eclipse.che.ide.extension.machine.client.inject.factories.TerminalFactory; -import org.eclipse.che.ide.api.machine.events.MachineStateEvent; import org.eclipse.che.ide.extension.machine.client.outputspanel.console.CommandConsoleFactory; import org.eclipse.che.ide.extension.machine.client.outputspanel.console.CommandOutputConsole; import org.eclipse.che.ide.extension.machine.client.perspective.terminal.TerminalPresenter; @@ -60,7 +60,6 @@ import org.mockito.Mock; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import static org.eclipse.che.ide.extension.machine.client.processes.ProcessTreeNode.ProcessNodeType.COMMAND_NODE; @@ -99,33 +98,35 @@ public class ProcessesPanelPresenterTest { @Mock private DialogFactory dialogFactory; @Mock - private WorkspaceAgent workspaceAgent; + private WorkspaceAgent workspaceAgent; + @Mock + private NotificationManager notificationManager; @Mock - private NotificationManager notificationManager; + private MachineLocalizationConstant localizationConstant; @Mock - private MachineLocalizationConstant localizationConstant; + private TerminalFactory terminalFactory; @Mock - private TerminalFactory terminalFactory; + private ProcessesPanelView view; @Mock - private ProcessesPanelView view; + private MachineResources resources; @Mock - private MachineResources resources; + private AppContext appContext; @Mock - private AppContext appContext; + private MachineServiceClient machineService; @Mock - private MachineServiceClient machineService; + private SshServiceClient sshService; @Mock - private EventBus eventBus; + private EventBus eventBus; @Mock - private WorkspaceDto workspace; + private WorkspaceDto workspace; @Mock - private OutputConsole outputConsole; + private OutputConsole outputConsole; @Mock - private MachineManager machineManager; + private MachineManager machineManager; @Mock - private EntityFactory entityFactory; + private EntityFactory entityFactory; @Mock - private WorkspaceRuntimeDto workspaceRuntime; + private WorkspaceRuntimeDto workspaceRuntime; @Mock private Promise> processesPromise; @@ -168,7 +169,8 @@ public void setUp() { commandConsoleFactory, dialogFactory, consoleTreeContextMenuFactory, - commandTypeRegistry); + commandTypeRegistry, + sshService); } @Test