-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'enhancement/log-viewer-widget' into feature/381
- Loading branch information
Showing
33 changed files
with
995 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
cogboard-app/src/main/kotlin/com/cognifide/cogboard/ssh/SSHClient.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package com.cognifide.cogboard.ssh | ||
|
||
import com.cognifide.cogboard.CogboardConstants | ||
import com.cognifide.cogboard.ssh.auth.SSHAuthData | ||
import com.cognifide.cogboard.ssh.session.SessionStrategyFactory | ||
import com.jcraft.jsch.ChannelExec | ||
import com.jcraft.jsch.JSch | ||
import com.jcraft.jsch.JSchException | ||
import com.jcraft.jsch.Session | ||
import io.vertx.core.AbstractVerticle | ||
import io.vertx.core.buffer.Buffer | ||
import io.vertx.core.eventbus.MessageConsumer | ||
import io.vertx.core.json.JsonObject | ||
import io.vertx.core.logging.Logger | ||
import io.vertx.core.logging.LoggerFactory | ||
import java.io.InputStream | ||
|
||
class SSHClient : AbstractVerticle() { | ||
private lateinit var session: Session | ||
private lateinit var jsch: JSch | ||
private lateinit var channel: ChannelExec | ||
private lateinit var sshInputStream: InputStream | ||
private lateinit var consumer: MessageConsumer<JsonObject> | ||
override fun start() { | ||
registerSSHCommand() | ||
super.start() | ||
} | ||
|
||
override fun stop() { | ||
consumer.unregister() | ||
super.stop() | ||
} | ||
|
||
private fun registerSSHCommand() { | ||
consumer = vertx.eventBus() | ||
.consumer<JsonObject>(CogboardConstants.Event.SSH_COMMAND) | ||
.handler { message -> | ||
message.body()?.let { | ||
tryToConnect(it) | ||
} | ||
} | ||
} | ||
|
||
private fun tryToConnect(config: JsonObject) { | ||
val eventBusAddress = config.getString(CogboardConstants.Props.EVENT_ADDRESS) | ||
try { | ||
connect(config) | ||
} catch (e: JSchException) { | ||
LOGGER.error(e.message) | ||
vertx.eventBus().send(eventBusAddress, e) | ||
} | ||
} | ||
|
||
private fun connect(config: JsonObject) { | ||
val authData = SSHAuthData(config) | ||
createSSHChannel(authData) | ||
executeCommandAndSendResult(config) | ||
} | ||
|
||
private fun createSSHChannel(authData: SSHAuthData) { | ||
with(authData) { | ||
initSSHSession(authData) | ||
if (session.isConnected) { | ||
createChannel(createCommand()) | ||
} | ||
} | ||
} | ||
|
||
private fun initSSHSession(authData: SSHAuthData) { | ||
jsch = JSch() | ||
jsch.setKnownHosts("~/.ssh/known_hosts") | ||
val session = SessionStrategyFactory(jsch).create(authData).initSession() | ||
session.connect(CogboardConstants.Props.SSH_TIMEOUT) | ||
} | ||
|
||
private fun createChannel(command: String) { | ||
channel = session.openChannel("exec") as ChannelExec | ||
channel.setCommand(command) | ||
channel.inputStream = null | ||
sshInputStream = channel.inputStream | ||
channel.connect(CogboardConstants.Props.SSH_TIMEOUT) | ||
} | ||
|
||
private fun executeCommandAndSendResult(config: JsonObject) { | ||
val eventBusAddress = config.getString(CogboardConstants.Props.EVENT_ADDRESS) | ||
val responseBuffer = Buffer.buffer() | ||
responseBuffer.appendBytes(sshInputStream.readAllBytes()) | ||
vertx.eventBus().send(eventBusAddress, responseBuffer) | ||
channel.disconnect() | ||
session.disconnect() | ||
} | ||
|
||
companion object { | ||
val LOGGER: Logger = LoggerFactory.getLogger(SSHClient::class.java) | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
cogboard-app/src/main/kotlin/com/cognifide/cogboard/ssh/auth/AuthenticationType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.cognifide.cogboard.ssh.auth | ||
|
||
enum class AuthenticationType { | ||
BASIC, | ||
TOKEN, | ||
SSH_KEY | ||
} |
49 changes: 49 additions & 0 deletions
49
cogboard-app/src/main/kotlin/com/cognifide/cogboard/ssh/auth/SSHAuthData.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.cognifide.cogboard.ssh.auth | ||
|
||
import com.cognifide.cogboard.CogboardConstants | ||
import com.cognifide.cogboard.ssh.auth.AuthenticationType.BASIC | ||
import com.cognifide.cogboard.ssh.auth.AuthenticationType.TOKEN | ||
import com.cognifide.cogboard.ssh.auth.AuthenticationType.SSH_KEY | ||
import io.vertx.core.json.Json | ||
import io.vertx.core.json.JsonArray | ||
import io.vertx.core.json.JsonObject | ||
|
||
class SSHAuthData(private val config: JsonObject) { | ||
val user = config.getString(CogboardConstants.Props.USER) ?: "" | ||
val password = config.getString(CogboardConstants.Props.PASSWORD) ?: "" | ||
val token = config.getString(CogboardConstants.Props.TOKEN) ?: "" | ||
val key = config.getString(CogboardConstants.Props.SSH_KEY) ?: "" | ||
val host = config.getString(CogboardConstants.Props.SSH_HOST) ?: "" | ||
val authenticationType = fromConfigAuthenticationType() | ||
|
||
private fun fromConfigAuthenticationType(): AuthenticationType { | ||
val authTypesString = config.getString(CogboardConstants.Props.AUTHENTICATION_TYPES) | ||
|
||
val authTypes = authTypesString?.let { Json.decodeValue(authTypesString) } ?: JsonArray() | ||
|
||
return (authTypes as JsonArray) | ||
.map { AuthenticationType.valueOf(it.toString()) } | ||
.firstOrNull { hasAuthTypeCorrectCredentials(it) } ?: BASIC | ||
} | ||
|
||
private fun hasAuthTypeCorrectCredentials(authType: AuthenticationType): Boolean = | ||
when { | ||
authType == TOKEN && user.isNotBlank() && token.isNotBlank() -> true | ||
authType == SSH_KEY && key.isNotBlank() -> true | ||
else -> authType == BASIC && user.isNotBlank() && password.isNotBlank() | ||
} | ||
|
||
fun getAuthenticationString(): String = | ||
when (authenticationType) { | ||
BASIC -> config.getString(CogboardConstants.Props.PASSWORD) | ||
TOKEN -> config.getString(CogboardConstants.Props.TOKEN) | ||
SSH_KEY -> config.getString(CogboardConstants.Props.SSH_KEY) | ||
} | ||
|
||
fun createCommand(): String { | ||
val logLines = config.getString(CogboardConstants.Props.LOG_LINES) ?: "0" | ||
val logFilePath = config.getString(CogboardConstants.Props.LOG_FILE_PATH) ?: "" | ||
|
||
return "cat $logFilePath | tail -$logLines" | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
cogboard-app/src/main/kotlin/com/cognifide/cogboard/ssh/session/SessionStrategyFactory.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.cognifide.cogboard.ssh.session | ||
|
||
import com.cognifide.cogboard.ssh.auth.AuthenticationType.BASIC | ||
import com.cognifide.cogboard.ssh.auth.AuthenticationType.TOKEN | ||
import com.cognifide.cogboard.ssh.auth.AuthenticationType.SSH_KEY | ||
import com.cognifide.cogboard.ssh.auth.SSHAuthData | ||
import com.cognifide.cogboard.ssh.session.strategy.BasicAuthSessionStrategy | ||
import com.cognifide.cogboard.ssh.session.strategy.SSHKeyAuthSessionStrategy | ||
import com.cognifide.cogboard.ssh.session.strategy.SessionStrategy | ||
import com.jcraft.jsch.JSch | ||
|
||
class SessionStrategyFactory(private val jsch: JSch) { | ||
fun create(authData: SSHAuthData): SessionStrategy = | ||
when (authData.authenticationType) { | ||
BASIC, TOKEN -> { | ||
BasicAuthSessionStrategy(jsch, authData) | ||
} | ||
SSH_KEY -> { | ||
SSHKeyAuthSessionStrategy(jsch, authData) | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...p/src/main/kotlin/com/cognifide/cogboard/ssh/session/strategy/BasicAuthSessionStrategy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.cognifide.cogboard.ssh.session.strategy | ||
|
||
import com.cognifide.cogboard.ssh.auth.SSHAuthData | ||
import com.jcraft.jsch.JSch | ||
import com.jcraft.jsch.Session | ||
|
||
class BasicAuthSessionStrategy(jsch: JSch, authData: SSHAuthData) : SessionStrategy(jsch, authData) { | ||
|
||
override fun initSession(): Session { | ||
val session = jsch.getSession(authData.user, authData.host) | ||
session.setPassword(securityString) | ||
|
||
return session | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
.../src/main/kotlin/com/cognifide/cogboard/ssh/session/strategy/SSHKeyAuthSessionStrategy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.cognifide.cogboard.ssh.session.strategy | ||
|
||
import com.cognifide.cogboard.ssh.auth.SSHAuthData | ||
import com.jcraft.jsch.JSch | ||
import com.jcraft.jsch.Session | ||
|
||
class SSHKeyAuthSessionStrategy(jSch: JSch, authData: SSHAuthData) : SessionStrategy(jSch, authData) { | ||
override fun initSession(): Session { | ||
if (authData.password == "") { | ||
jsch.addIdentity(securityString) | ||
} else { | ||
jsch.addIdentity(securityString, authData.password) | ||
} | ||
val session = jsch.getSession(authData.user, authData.host) | ||
session.setConfig("PreferredAuthentications", "publickey") | ||
|
||
return session | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
cogboard-app/src/main/kotlin/com/cognifide/cogboard/ssh/session/strategy/SessionStrategy.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.cognifide.cogboard.ssh.session.strategy | ||
|
||
import com.cognifide.cogboard.ssh.auth.SSHAuthData | ||
import com.jcraft.jsch.JSch | ||
import com.jcraft.jsch.Session | ||
|
||
abstract class SessionStrategy(protected val jsch: JSch, protected val authData: SSHAuthData) { | ||
protected val securityString: String | ||
get() = authData.getAuthenticationString() | ||
|
||
abstract fun initSession(): Session | ||
} |
52 changes: 52 additions & 0 deletions
52
cogboard-app/src/main/kotlin/com/cognifide/cogboard/widget/SSHWidget.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.cognifide.cogboard.widget | ||
|
||
import com.cognifide.cogboard.CogboardConstants.Props | ||
import com.cognifide.cogboard.CogboardConstants.Event | ||
import com.cognifide.cogboard.config.service.BoardsConfigService | ||
import io.vertx.core.Vertx | ||
import io.vertx.core.eventbus.MessageConsumer | ||
import io.vertx.core.json.JsonObject | ||
import java.nio.Buffer | ||
|
||
abstract class SSHWidget( | ||
vertx: Vertx, | ||
config: JsonObject, | ||
serv: BoardsConfigService | ||
) : AsyncWidget(vertx, config, serv) { | ||
val sshKey: String = config.endpointProp(Props.SSH_KEY) | ||
val host: String = config.endpointProp(Props.SSH_HOST) | ||
val logPath: String = config.endpointProp(Props.LOG_FILE_PATH) | ||
val logLines: String = config.endpointProp(Props.LOG_LINES) | ||
private lateinit var sshConsumer: MessageConsumer<Buffer> | ||
|
||
fun registerForSSH(eventBusAddress: String) { | ||
sshConsumer = vertx.eventBus() | ||
.consumer<Buffer>(eventBusAddress) | ||
.handler { | ||
handleSSHResponse(it.body()) | ||
} | ||
} | ||
|
||
abstract fun handleSSHResponse(body: Buffer?) | ||
|
||
fun unregisterFromSSH() { | ||
if (::sshConsumer.isInitialized) { | ||
sshConsumer.unregister() | ||
} | ||
} | ||
|
||
fun sendRequestForLogs(config: JsonObject) { | ||
ensureConfigIsPrepared(config) | ||
vertx.eventBus().send(Event.SSH_COMMAND, config) | ||
} | ||
|
||
private fun ensureConfigIsPrepared(config: JsonObject) { | ||
config.getString(Props.USER) ?: config.put(Props.USER, user) | ||
config.getString(Props.PASSWORD) ?: config.put(Props.PASSWORD, password) | ||
config.getString(Props.TOKEN) ?: config.put(Props.TOKEN, token) | ||
config.getString(Props.SSH_KEY) ?: config.put(Props.SSH_KEY, sshKey) | ||
config.getString(Props.SSH_HOST) ?: config.put(Props.SSH_HOST, host) | ||
config.getString(Props.LOG_FILE_PATH) ?: config.put(Props.LOG_FILE_PATH, logPath) | ||
config.getString(Props.LOG_LINES) ?: config.put(Props.LOG_LINES, logLines) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.