diff --git a/deployment/pom.xml b/deployment/pom.xml index 7cc5c5f..96d2e03 100644 --- a/deployment/pom.xml +++ b/deployment/pom.xml @@ -23,6 +23,20 @@ quarkus-junit5-internal test + + io.quarkus + quarkus-devservices-deployment + + + org.testcontainers + testcontainers + + + junit + junit + + + diff --git a/deployment/src/main/java/io/quarkus/jsch/deployment/JSchBuildTimeConfig.java b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchBuildTimeConfig.java new file mode 100644 index 0000000..22f61a9 --- /dev/null +++ b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchBuildTimeConfig.java @@ -0,0 +1,18 @@ +package io.quarkus.jsch.deployment; + +import io.quarkus.runtime.annotations.ConfigDocSection; +import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; + +@ConfigMapping(prefix = "quarkus.jsch") +@ConfigRoot(phase = ConfigPhase.BUILD_TIME) +public interface JSchBuildTimeConfig { + + /** + * The JSch DevService configuration. + */ + @ConfigDocSection + JSchDevServiceConfig devservice(); + +} diff --git a/deployment/src/main/java/io/quarkus/jsch/deployment/JSchDevServiceConfig.java b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchDevServiceConfig.java new file mode 100644 index 0000000..15522ea --- /dev/null +++ b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchDevServiceConfig.java @@ -0,0 +1,45 @@ +package io.quarkus.jsch.deployment; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.smallrye.config.WithDefault; + +@ConfigGroup +public interface JSchDevServiceConfig { + + /** + * Enable the JSch DevService. + */ + @WithDefault("true") + boolean enabled(); + + /** + * The image to use for the JSch DevService. + */ + @WithDefault("linuxserver/openssh-server") + String image(); + + /** + * The port to use for the JSch DevService. + */ + @WithDefault("2222") + int port(); + + /** + * The username to use for the JSch DevService. + */ + @WithDefault("quarkus") + String username(); + + /** + * The password to use for the JSch DevService. + */ + @WithDefault("quarkus") + String password(); + + /** + * Whether to reuse the container for the JSch DevService. + */ + @WithDefault("false") + boolean reuse(); + +} diff --git a/deployment/src/main/java/io/quarkus/jsch/deployment/JSchDevServiceProcessor.java b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchDevServiceProcessor.java new file mode 100644 index 0000000..c713d1d --- /dev/null +++ b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchDevServiceProcessor.java @@ -0,0 +1,44 @@ +package io.quarkus.jsch.deployment; + +import java.util.Map; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; + +import io.quarkus.deployment.IsNormal; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.BuildSteps; +import io.quarkus.deployment.builditem.DevServicesResultBuildItem; +import io.quarkus.deployment.dev.devservices.GlobalDevServicesConfig; + +@BuildSteps(onlyIfNot = IsNormal.class, onlyIf = GlobalDevServicesConfig.Enabled.class) +public class JSchDevServiceProcessor { + + @BuildStep + DevServicesResultBuildItem startDevServices(JSchBuildTimeConfig config) { + if (!config.devservice().enabled()) { + return null; + } + + DockerImageName dockerImageName = DockerImageName.parse(config.devservice().image()); + GenericContainer container = new GenericContainer<>(dockerImageName) + .withEnv("USER_NAME", config.devservice().username()) + .withEnv("USER_PASSWORD", config.devservice().password()) + .withEnv("PASSWORD_ACCESS", "true") + .withExposedPorts(config.devservice().port()) + .withReuse(config.devservice().reuse()); + + container.start(); + + Map configOverrides = Map.of( + "quarkus.jsch.session.host", container.getHost(), + "quarkus.jsch.session.port", container.getMappedPort(config.devservice().port()).toString(), + "quarkus.jsch.session.username", config.devservice().username(), + "quarkus.jsch.session.password", config.devservice().password(), + "quarkus.jsch.session.config.StrictHostKeyChecking", "no"); + + return new DevServicesResultBuildItem.RunningDevService(JSchProcessor.FEATURE, container.getContainerId(), + container::close, configOverrides) + .toBuildItem(); + } +} diff --git a/deployment/src/main/java/io/quarkus/jsch/deployment/JSchProcessor.java b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchProcessor.java index 978bf0c..a8da945 100644 --- a/deployment/src/main/java/io/quarkus/jsch/deployment/JSchProcessor.java +++ b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchProcessor.java @@ -1,15 +1,39 @@ package io.quarkus.jsch.deployment; +import java.util.Collection; +import java.util.List; +import java.util.function.Supplier; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.context.RequestScoped; + +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.DotName; +import org.jboss.jandex.IndexView; + +import com.jcraft.jsch.Session; + +import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem; +import io.quarkus.arc.deployment.SyntheticBeanBuildItem; +import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.ShutdownContextBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem; +import io.quarkus.jsch.JSchSession; +import io.quarkus.jsch.JSchSessions; +import io.quarkus.jsch.runtime.JSchSessionRecorder; import io.quarkus.jsch.runtime.PortWatcherRunTime; class JSchProcessor { - private static final String FEATURE = "jsch"; + public static final String FEATURE = "jsch"; @BuildStep FeatureBuildItem feature() { @@ -131,4 +155,65 @@ ReflectiveClassBuildItem reflection() { "com.jcraft.jsch.UserAuthPublicKey") .fields().methods().build(); } + + @BuildStep + void registerAdditionalBeans(BuildProducer additionalBeans) { + additionalBeans.produce(AdditionalBeanBuildItem.builder() + .addBeanClass(JSchSessions.class) + .setUnremovable() + .setDefaultScope(DotName.createSimple(Dependent.class)) + .build()); + + additionalBeans.produce(AdditionalBeanBuildItem.builder() + .addBeanClass(JSchSession.class) + .build()); + } + + @BuildStep + void produceSessions( + BuildProducer jschSessionBuildItemBuildProducer, + BeanArchiveIndexBuildItem indexBuildItem) { + IndexView index = indexBuildItem.getIndex(); + Collection jschSessionAnnotations = index.getAnnotations(JSchSession.class); + + if (jschSessionAnnotations.isEmpty()) { + // No @JschSession annotations found + return; + } + + for (AnnotationInstance annotation : jschSessionAnnotations) { + AnnotationValue value = annotation.value(); + String name = value != null ? value.asString() : JSchSession.DEFAULT_SESSION_NAME; + jschSessionBuildItemBuildProducer.produce(new JSchSessionBuildItem(name)); + } + } + + @Record(ExecutionTime.RUNTIME_INIT) + @BuildStep + void sessionRecorder(JSchSessionRecorder recorder, + List sessionBuildItems, + ShutdownContextBuildItem shutdown, + BuildProducer syntheticBeans) { + if (sessionBuildItems.isEmpty()) { + return; + } + + for (JSchSessionBuildItem sessionBuildItem : sessionBuildItems) { + // create session + Supplier sessionSupplier = recorder.jschSessionSupplier(sessionBuildItem.name()); + SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem + .configure(Session.class) + .scope(RequestScoped.class) + .setRuntimeInit() + .unremovable() + .supplier(sessionSupplier); + + configurator.addQualifier() + .annotation(JSchSession.class) + .addValue("value", sessionBuildItem.name()) + .done(); + + syntheticBeans.produce(configurator.done()); + } + } } diff --git a/deployment/src/main/java/io/quarkus/jsch/deployment/JSchSessionBuildItem.java b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchSessionBuildItem.java new file mode 100644 index 0000000..d3f054d --- /dev/null +++ b/deployment/src/main/java/io/quarkus/jsch/deployment/JSchSessionBuildItem.java @@ -0,0 +1,38 @@ +package io.quarkus.jsch.deployment; + +import io.quarkus.builder.item.MultiBuildItem; + +/** + * A build item that registers a JSch session created by annotation. + */ +public final class JSchSessionBuildItem extends MultiBuildItem { + + private final String name; + + public JSchSessionBuildItem(String name) { + this.name = name; + } + + public String name() { + return name; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof JSchSessionBuildItem)) { + return false; + } + + JSchSessionBuildItem other = (JSchSessionBuildItem) obj; + return name.equals(other.name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} diff --git a/deployment/src/test/java/io/quarkiverse/jsch/test/JschDevModeTest.java b/deployment/src/test/java/io/quarkiverse/jsch/test/JSchDevModeTest.java similarity index 96% rename from deployment/src/test/java/io/quarkiverse/jsch/test/JschDevModeTest.java rename to deployment/src/test/java/io/quarkiverse/jsch/test/JSchDevModeTest.java index 574651f..5af3c93 100644 --- a/deployment/src/test/java/io/quarkiverse/jsch/test/JschDevModeTest.java +++ b/deployment/src/test/java/io/quarkiverse/jsch/test/JSchDevModeTest.java @@ -8,7 +8,7 @@ import io.quarkus.test.QuarkusDevModeTest; -public class JschDevModeTest { +public class JSchDevModeTest { // Start hot reload (DevMode) test with your extension loaded @RegisterExtension diff --git a/deployment/src/test/java/io/quarkiverse/jsch/test/JschTest.java b/deployment/src/test/java/io/quarkiverse/jsch/test/JSchTest.java similarity index 97% rename from deployment/src/test/java/io/quarkiverse/jsch/test/JschTest.java rename to deployment/src/test/java/io/quarkiverse/jsch/test/JSchTest.java index bbd8b4d..69ddcae 100644 --- a/deployment/src/test/java/io/quarkiverse/jsch/test/JschTest.java +++ b/deployment/src/test/java/io/quarkiverse/jsch/test/JSchTest.java @@ -8,7 +8,7 @@ import io.quarkus.test.QuarkusUnitTest; -public class JschTest { +public class JSchTest { // Start unit test with your extension loaded @RegisterExtension diff --git a/docs/modules/ROOT/pages/includes/attributes.adoc b/docs/modules/ROOT/pages/includes/attributes.adoc index c6fbbad..28eff33 100644 --- a/docs/modules/ROOT/pages/includes/attributes.adoc +++ b/docs/modules/ROOT/pages/includes/attributes.adoc @@ -1,4 +1,4 @@ -:quarkus-version: 3.14.4 +:quarkus-version: 3.15.1 :quarkus-jsch-version: 3.0.11 :quarkus-org-url: https://github.com/quarkusio diff --git a/docs/modules/ROOT/pages/includes/quarkus-jsch.adoc b/docs/modules/ROOT/pages/includes/quarkus-jsch.adoc new file mode 100644 index 0000000..f6d9c5c --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-jsch.adoc @@ -0,0 +1,501 @@ +:summaryTableId: quarkus-jsch_quarkus-jsch +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +h|[[quarkus-jsch_section_quarkus-jsch-devservice]] [.section-name.section-level0]##link:#quarkus-jsch_section_quarkus-jsch-devservice[The JSch DevService configuration]## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-enabled]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-enabled[`quarkus.jsch.devservice.enabled`]## + +[.description] +-- +Enable the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-image]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-image[`quarkus.jsch.devservice.image`]## + +[.description] +-- +The image to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_IMAGE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_IMAGE+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`linuxserver/openssh-server` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-port[`quarkus.jsch.devservice.port`]## + +[.description] +-- +The port to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`2222` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-username[`quarkus.jsch.devservice.username`]## + +[.description] +-- +The username to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`quarkus` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-password[`quarkus.jsch.devservice.password`]## + +[.description] +-- +The password to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`quarkus` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-reuse]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-reuse[`quarkus.jsch.devservice.reuse`]## + +[.description] +-- +Whether to reuse the container for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_REUSE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_REUSE+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + + +h|[[quarkus-jsch_section_quarkus-jsch-session]] [.section-name.section-level0]##link:#quarkus-jsch_section_quarkus-jsch-session[JSch sessions]## +h|Type +h|Default + +a| [[quarkus-jsch_quarkus-jsch-session-host]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-host[`quarkus.jsch.session.host`]## + +`quarkus.jsch.session."session-name".host` + +[.description] +-- +The host to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`localhost` + +a| [[quarkus-jsch_quarkus-jsch-session-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-port[`quarkus.jsch.session.port`]## + +`quarkus.jsch.session."session-name".port` + +[.description] +-- +The port to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`22` + +a| [[quarkus-jsch_quarkus-jsch-session-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-username[`quarkus.jsch.session.username`]## + +`quarkus.jsch.session."session-name".username` + +[.description] +-- +The username to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-password[`quarkus.jsch.session.password`]## + +`quarkus.jsch.session."session-name".password` + +[.description] +-- +The password to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-key]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-key[`quarkus.jsch.session.key`]## + +`quarkus.jsch.session."session-name".key` + +[.description] +-- +The private key to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_KEY+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_KEY+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-passphrase]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-passphrase[`quarkus.jsch.session.passphrase`]## + +`quarkus.jsch.session."session-name".passphrase` + +[.description] +-- +The passphrase to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PASSPHRASE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PASSPHRASE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-config-config-name]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-config-config-name[`quarkus.jsch.session.config."config-name"`]## + +`quarkus.jsch.session."session-name".config."config-name"` + +[.description] +-- +The configuration to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_CONFIG__CONFIG_NAME_+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_CONFIG__CONFIG_NAME_+++` +endif::add-copy-button-to-env-var[] +-- +|Map +| + +a| [[quarkus-jsch_quarkus-jsch-session-mock]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-mock[`quarkus.jsch.session.mock`]## + +`quarkus.jsch.session."session-name".mock` + +[.description] +-- +Mock the JSch session in dev and test mode. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_MOCK+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_MOCK+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a| [[quarkus-jsch_quarkus-jsch-session-keep-alive-interval]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-keep-alive-interval[`quarkus.jsch.session.keep-alive-interval`]## + +`quarkus.jsch.session."session-name".keep-alive-interval` + +[.description] +-- +The keep alive interval to use for the JSch session. + +If zero is specified, any keep-alive message. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_KEEP_ALIVE_INTERVAL+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_KEEP_ALIVE_INTERVAL+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`0` + +h|[[quarkus-jsch_section_quarkus-jsch-session-proxy]] [.section-name.section-level1]##link:#quarkus-jsch_section_quarkus-jsch-session-proxy[The proxy to use for the JSch session]## +h|Type +h|Default + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-enabled]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-enabled[`quarkus.jsch.session.proxy.enabled`]## + +`quarkus.jsch.session."session-name".proxy.enabled` + +[.description] +-- +Enable the proxy for the JSch session. + +Defaults to `true` if host is set. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-host]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-host[`quarkus.jsch.session.proxy.host`]## + +`quarkus.jsch.session."session-name".proxy.host` + +[.description] +-- +The host to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-port[`quarkus.jsch.session.proxy.port`]## + +`quarkus.jsch.session."session-name".proxy.port` + +[.description] +-- +The port to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`80` + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-auth-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-auth-username[`quarkus.jsch.session.proxy.auth.username`]## + +`quarkus.jsch.session."session-name".proxy.auth.username` + +[.description] +-- +The username to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_AUTH_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_AUTH_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-auth-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-auth-password[`quarkus.jsch.session.proxy.auth.password`]## + +`quarkus.jsch.session."session-name".proxy.auth.password` + +[.description] +-- +The password to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_AUTH_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_AUTH_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + + + +h|[[quarkus-jsch_section_quarkus-jsch-proxy]] [.section-name.section-level0]##link:#quarkus-jsch_section_quarkus-jsch-proxy[The default proxy configuration to use for each JSch session]## +h|Type +h|Default + +a| [[quarkus-jsch_quarkus-jsch-proxy-enabled]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-enabled[`quarkus.jsch.proxy.enabled`]## + +[.description] +-- +Enable the proxy for the JSch session. + +Defaults to `true` if host is set. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a| [[quarkus-jsch_quarkus-jsch-proxy-host]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-host[`quarkus.jsch.proxy.host`]## + +[.description] +-- +The host to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-proxy-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-port[`quarkus.jsch.proxy.port`]## + +[.description] +-- +The port to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`80` + +a| [[quarkus-jsch_quarkus-jsch-proxy-auth-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-auth-username[`quarkus.jsch.proxy.auth.username`]## + +[.description] +-- +The username to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_AUTH_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_AUTH_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-proxy-auth-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-auth-password[`quarkus.jsch.proxy.auth.password`]## + +[.description] +-- +The password to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_AUTH_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_AUTH_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + + +|=== + + +:!summaryTableId: \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-jsch_quarkus.adoc b/docs/modules/ROOT/pages/includes/quarkus-jsch_quarkus.adoc new file mode 100644 index 0000000..4950abc --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-jsch_quarkus.adoc @@ -0,0 +1,14 @@ +:summaryTableId: quarkus-jsch_quarkus +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +|=== + + +:!summaryTableId: \ No newline at end of file diff --git a/docs/modules/ROOT/pages/includes/quarkus-jsch_quarkus.jsch.adoc b/docs/modules/ROOT/pages/includes/quarkus-jsch_quarkus.jsch.adoc new file mode 100644 index 0000000..f6d9c5c --- /dev/null +++ b/docs/modules/ROOT/pages/includes/quarkus-jsch_quarkus.jsch.adoc @@ -0,0 +1,501 @@ +:summaryTableId: quarkus-jsch_quarkus-jsch +[.configuration-legend] +icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime +[.configuration-reference.searchable, cols="80,.^10,.^10"] +|=== + +h|[.header-title]##Configuration property## +h|Type +h|Default + +h|[[quarkus-jsch_section_quarkus-jsch-devservice]] [.section-name.section-level0]##link:#quarkus-jsch_section_quarkus-jsch-devservice[The JSch DevService configuration]## +h|Type +h|Default + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-enabled]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-enabled[`quarkus.jsch.devservice.enabled`]## + +[.description] +-- +Enable the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-image]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-image[`quarkus.jsch.devservice.image`]## + +[.description] +-- +The image to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_IMAGE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_IMAGE+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`linuxserver/openssh-server` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-port[`quarkus.jsch.devservice.port`]## + +[.description] +-- +The port to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`2222` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-username[`quarkus.jsch.devservice.username`]## + +[.description] +-- +The username to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`quarkus` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-password[`quarkus.jsch.devservice.password`]## + +[.description] +-- +The password to use for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`quarkus` + +a|icon:lock[title=Fixed at build time] [[quarkus-jsch_quarkus-jsch-devservice-reuse]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-devservice-reuse[`quarkus.jsch.devservice.reuse`]## + +[.description] +-- +Whether to reuse the container for the JSch DevService. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_DEVSERVICE_REUSE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_DEVSERVICE_REUSE+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`false` + + +h|[[quarkus-jsch_section_quarkus-jsch-session]] [.section-name.section-level0]##link:#quarkus-jsch_section_quarkus-jsch-session[JSch sessions]## +h|Type +h|Default + +a| [[quarkus-jsch_quarkus-jsch-session-host]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-host[`quarkus.jsch.session.host`]## + +`quarkus.jsch.session."session-name".host` + +[.description] +-- +The host to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +|`localhost` + +a| [[quarkus-jsch_quarkus-jsch-session-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-port[`quarkus.jsch.session.port`]## + +`quarkus.jsch.session."session-name".port` + +[.description] +-- +The port to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`22` + +a| [[quarkus-jsch_quarkus-jsch-session-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-username[`quarkus.jsch.session.username`]## + +`quarkus.jsch.session."session-name".username` + +[.description] +-- +The username to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-password[`quarkus.jsch.session.password`]## + +`quarkus.jsch.session."session-name".password` + +[.description] +-- +The password to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-key]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-key[`quarkus.jsch.session.key`]## + +`quarkus.jsch.session."session-name".key` + +[.description] +-- +The private key to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_KEY+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_KEY+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-passphrase]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-passphrase[`quarkus.jsch.session.passphrase`]## + +`quarkus.jsch.session."session-name".passphrase` + +[.description] +-- +The passphrase to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PASSPHRASE+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PASSPHRASE+++` +endif::add-copy-button-to-env-var[] +-- +|string +| + +a| [[quarkus-jsch_quarkus-jsch-session-config-config-name]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-config-config-name[`quarkus.jsch.session.config."config-name"`]## + +`quarkus.jsch.session."session-name".config."config-name"` + +[.description] +-- +The configuration to use for the JSch session. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_CONFIG__CONFIG_NAME_+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_CONFIG__CONFIG_NAME_+++` +endif::add-copy-button-to-env-var[] +-- +|Map +| + +a| [[quarkus-jsch_quarkus-jsch-session-mock]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-mock[`quarkus.jsch.session.mock`]## + +`quarkus.jsch.session."session-name".mock` + +[.description] +-- +Mock the JSch session in dev and test mode. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_MOCK+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_MOCK+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +|`true` + +a| [[quarkus-jsch_quarkus-jsch-session-keep-alive-interval]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-keep-alive-interval[`quarkus.jsch.session.keep-alive-interval`]## + +`quarkus.jsch.session."session-name".keep-alive-interval` + +[.description] +-- +The keep alive interval to use for the JSch session. + +If zero is specified, any keep-alive message. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_KEEP_ALIVE_INTERVAL+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_KEEP_ALIVE_INTERVAL+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`0` + +h|[[quarkus-jsch_section_quarkus-jsch-session-proxy]] [.section-name.section-level1]##link:#quarkus-jsch_section_quarkus-jsch-session-proxy[The proxy to use for the JSch session]## +h|Type +h|Default + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-enabled]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-enabled[`quarkus.jsch.session.proxy.enabled`]## + +`quarkus.jsch.session."session-name".proxy.enabled` + +[.description] +-- +Enable the proxy for the JSch session. + +Defaults to `true` if host is set. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-host]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-host[`quarkus.jsch.session.proxy.host`]## + +`quarkus.jsch.session."session-name".proxy.host` + +[.description] +-- +The host to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-port[`quarkus.jsch.session.proxy.port`]## + +`quarkus.jsch.session."session-name".proxy.port` + +[.description] +-- +The port to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`80` + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-auth-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-auth-username[`quarkus.jsch.session.proxy.auth.username`]## + +`quarkus.jsch.session."session-name".proxy.auth.username` + +[.description] +-- +The username to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_AUTH_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_AUTH_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-session-proxy-auth-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-session-proxy-auth-password[`quarkus.jsch.session.proxy.auth.password`]## + +`quarkus.jsch.session."session-name".proxy.auth.password` + +[.description] +-- +The password to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_SESSION_PROXY_AUTH_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_SESSION_PROXY_AUTH_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + + + +h|[[quarkus-jsch_section_quarkus-jsch-proxy]] [.section-name.section-level0]##link:#quarkus-jsch_section_quarkus-jsch-proxy[The default proxy configuration to use for each JSch session]## +h|Type +h|Default + +a| [[quarkus-jsch_quarkus-jsch-proxy-enabled]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-enabled[`quarkus.jsch.proxy.enabled`]## + +[.description] +-- +Enable the proxy for the JSch session. + +Defaults to `true` if host is set. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_ENABLED+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_ENABLED+++` +endif::add-copy-button-to-env-var[] +-- +|boolean +| + +a| [[quarkus-jsch_quarkus-jsch-proxy-host]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-host[`quarkus.jsch.proxy.host`]## + +[.description] +-- +The host to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_HOST+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_HOST+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-proxy-port]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-port[`quarkus.jsch.proxy.port`]## + +[.description] +-- +The port to use for the JSch proxy. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_PORT+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_PORT+++` +endif::add-copy-button-to-env-var[] +-- +|int +|`80` + +a| [[quarkus-jsch_quarkus-jsch-proxy-auth-username]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-auth-username[`quarkus.jsch.proxy.auth.username`]## + +[.description] +-- +The username to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_AUTH_USERNAME+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_AUTH_USERNAME+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + +a| [[quarkus-jsch_quarkus-jsch-proxy-auth-password]] [.property-path]##link:#quarkus-jsch_quarkus-jsch-proxy-auth-password[`quarkus.jsch.proxy.auth.password`]## + +[.description] +-- +The password to use for the JSch proxy. + +`proxy.auth` is optional. + + +ifdef::add-copy-button-to-env-var[] +Environment variable: env_var_with_copy_button:+++QUARKUS_JSCH_PROXY_AUTH_PASSWORD+++[] +endif::add-copy-button-to-env-var[] +ifndef::add-copy-button-to-env-var[] +Environment variable: `+++QUARKUS_JSCH_PROXY_AUTH_PASSWORD+++` +endif::add-copy-button-to-env-var[] +-- +|string +|required icon:exclamation-circle[title=Configuration property is required] + + +|=== + + +:!summaryTableId: \ No newline at end of file diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index 69b7cf2..f4c755c 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -17,3 +17,30 @@ In your `pom.xml` file, add: {quarkus-jsch-version} ---- + +== Usage + +=== Create session by annotation + +[source,java] +---- +@RequestScoped +public class MyBean { + + // default session configurable by `quarkus.jsch.session.*` + @JschSession + Session defaultSession; + + // named session configurable by `quarkus.jsch.session.doudou.*` + @JschSession("doudou") + Session namedSession; + + public String getServerVersion() { + return defaultSession.getServerVersion(); + } +} +---- + +== Configuration + +include::./includes/quarkus-jsch.adoc[] diff --git a/integration-tests/src/main/java/io/quarkus/it/jsch/JSchResource.java b/integration-tests/src/main/java/io/quarkus/it/jsch/JSchResource.java index b4e6f6d..fd7f6af 100644 --- a/integration-tests/src/main/java/io/quarkus/it/jsch/JSchResource.java +++ b/integration-tests/src/main/java/io/quarkus/it/jsch/JSchResource.java @@ -1,5 +1,6 @@ package io.quarkus.it.jsch; +import jakarta.enterprise.context.RequestScoped; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; @@ -8,14 +9,25 @@ import jakarta.ws.rs.core.Response; import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; import com.jcraft.jsch.KeyPair; import com.jcraft.jsch.Session; +import io.quarkus.jsch.JSchSession; +import io.quarkus.jsch.JSchSessions; + @Path("/jsch") +@RequestScoped public class JSchResource { + @JSchSession("doudou") + Session namedSession; + + @JSchSession + Session defaultSession; + @GET - public Response connect(@QueryParam("host") String host, @QueryParam("port") int port) throws Exception { + public Response connect(@QueryParam("host") String host, @QueryParam("port") int port) throws JSchException { JSch jsch = new JSch(); Session session = jsch.getSession(null, host, port); session.setConfig("StrictHostKeyChecking", "no"); @@ -25,18 +37,51 @@ public Response connect(@QueryParam("host") String host, @QueryParam("port") int return Response.ok(serverVersion).build(); } + @GET + @Path("/session-default") + public Response connectSessionDefault() { + return Response.ok(defaultSession.getServerVersion()).build(); + } + + @GET + @Path("/session-named") + public Response connectSessionNamed() { + return Response.ok(namedSession.getServerVersion()).build(); + } + + @GET + @Path("/session-program") + public Response connectSessionProgram() { + Session localSession = JSchSessions.fromName("toto"); + return Response.ok(localSession.getServerVersion()).build(); + } + + @GET + @Path("/session-no-mock") + public Response connectSessionProgramNoMock() { + Session localSession = JSchSessions.fromName("no-mock"); + return Response.ok(localSession.getServerVersion()).build(); + } + + @GET + @Path("/session-not-found") + public Response connectSessionNotFound() { + Session localSession = JSchSessions.fromName("not-found"); + return Response.ok(localSession.getServerVersion()).build(); + } + @GET @Path("/keypair/decrypt") @Produces(MediaType.TEXT_PLAIN) public boolean decryptKeypair(@QueryParam("privateKey") String privateKey, - @QueryParam("passphrase") String passphrase) throws Exception { + @QueryParam("passphrase") String passphrase) throws JSchException { KeyPair keyPair = KeyPair.load(new JSch(), privateKey, null); return keyPair.decrypt(passphrase); } @GET @Path("/zlib") - public Response zlib(@QueryParam("host") String host, @QueryParam("port") int port) throws Exception { + public Response zlib(@QueryParam("host") String host, @QueryParam("port") int port) throws JSchException { JSch jsch = new JSch(); Session session = jsch.getSession(null, host, port); session.setConfig("StrictHostKeyChecking", "no"); diff --git a/integration-tests/src/main/resources/application.properties b/integration-tests/src/main/resources/application.properties index e69de29..5d44f48 100644 --- a/integration-tests/src/main/resources/application.properties +++ b/integration-tests/src/main/resources/application.properties @@ -0,0 +1,3 @@ +quarkus.test.native-image-profile=test +quarkus.jsch.session.not-found.mock=false +quarkus.jsch.session.not-found.host=none diff --git a/integration-tests/src/test/java/io/quarkus/it/jsch/JSchDevServiceTest.java b/integration-tests/src/test/java/io/quarkus/it/jsch/JSchDevServiceTest.java new file mode 100644 index 0000000..3603440 --- /dev/null +++ b/integration-tests/src/test/java/io/quarkus/it/jsch/JSchDevServiceTest.java @@ -0,0 +1,54 @@ +package io.quarkus.it.jsch; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.core.Is.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +class JSchDevServiceTest { + + @Test + void shouldConnectWithDefaultSession() { + given() + .log().all() + .get("/jsch/session-default") + .then() + .statusCode(is(200)); + } + + @Test + void shouldConnectWithNamedSession() { + given() + .get("/jsch/session-named") + .then() + .statusCode(is(200)); + } + + @Test + void shouldConnectWithProgSession() { + given() + .get("/jsch/session-program") + .then() + .statusCode(is(200)); + } + + @Test + void shouldConnectWithoutMockSession() { + given() + .get("/jsch/session-no-mock") + .then() + .statusCode(is(200)); + } + + @Test + void shouldNotConnect() { + given() + .get("/jsch/session-not-found") + .then() + .statusCode(is(500)); + } + +} diff --git a/integration-tests/src/test/java/io/quarkus/it/jsch/JSchDevServiceTestIT.java b/integration-tests/src/test/java/io/quarkus/it/jsch/JSchDevServiceTestIT.java new file mode 100644 index 0000000..5ab8917 --- /dev/null +++ b/integration-tests/src/test/java/io/quarkus/it/jsch/JSchDevServiceTestIT.java @@ -0,0 +1,7 @@ +package io.quarkus.it.jsch; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class JSchDevServiceTestIT extends JSchDevServiceTest { +} diff --git a/integration-tests/src/test/java/io/quarkus/it/jsch/JSchTest.java b/integration-tests/src/test/java/io/quarkus/it/jsch/JSchTest.java index 8067d35..92701d5 100644 --- a/integration-tests/src/test/java/io/quarkus/it/jsch/JSchTest.java +++ b/integration-tests/src/test/java/io/quarkus/it/jsch/JSchTest.java @@ -10,37 +10,21 @@ import java.nio.file.Path; import org.apache.sshd.server.SshServer; -import org.apache.sshd.server.auth.hostbased.AcceptAllHostBasedAuthenticator; -import org.apache.sshd.server.auth.password.AcceptAllPasswordAuthenticator; -import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator; -import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; -import org.apache.sshd.server.shell.UnknownCommandFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import com.jcraft.jsch.JSch; import com.jcraft.jsch.KeyPair; +import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest -public class JSchTest { - - private SshServer sshd; - - @BeforeEach - public void setupSSHDServer() throws Exception { - sshd = SshServer.setUpDefaultServer(); - sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Files.createTempFile("host", "key"))); - sshd.setHostBasedAuthenticator(AcceptAllHostBasedAuthenticator.INSTANCE); - sshd.setPasswordAuthenticator(AcceptAllPasswordAuthenticator.INSTANCE); - sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE); - sshd.setCommandFactory(UnknownCommandFactory.INSTANCE); - sshd.setHost("localhost"); - sshd.start(); - } +@QuarkusTestResource(SshServerResource.class) +class JSchTest { + + @WithSshTestServer + SshServer sshd; @Test void shouldConnect() { @@ -52,6 +36,50 @@ void shouldConnect() { .body(endsWith(sshd.getVersion())); } + @Test + void shouldConnectWithDefaultSession() { + given() + .get("/jsch/session-default") + .then() + .statusCode(is(200)) + .body(endsWith(sshd.getVersion())); + } + + @Test + void shouldConnectWithNamedSession() { + given() + .get("/jsch/session-named") + .then() + .statusCode(is(200)) + .body(endsWith(sshd.getVersion())); + } + + @Test + void shouldConnectWithProgSession() { + given() + .get("/jsch/session-program") + .then() + .statusCode(is(200)) + .body(endsWith(sshd.getVersion())); + } + + @Test + void shouldConnectWithoutMockSession() { + given() + .get("/jsch/session-no-mock") + .then() + .statusCode(is(200)) + .body(endsWith(sshd.getVersion())); + } + + @Test + void shouldNotConnect() { + given() + .get("/jsch/session-not-found") + .then() + .statusCode(is(500)); + } + @Test void shouldDecryptUsingKeyPair(@TempDir Path keypairDir) throws Exception { String passphrase = "password"; @@ -76,7 +104,7 @@ void shouldDecryptUsingKeyPair(@TempDir Path keypairDir) throws Exception { } @Test - void shouldDecryptOpenSSLKeyUsingKeyPair() throws Exception { + void shouldDecryptOpenSSLKeyUsingKeyPair() { String passphrase = "PrettyPlease"; String privateKeyPath = getClass().getClassLoader().getResource("openssh_private_key").getFile(); given().queryParam("privateKey", privateKeyPath) @@ -96,11 +124,4 @@ void shouldSupportZLibCompression() { .statusCode(is(200)) .body(endsWith(sshd.getVersion())); } - - @AfterEach - void stopServer() throws Exception { - if (sshd != null) { - sshd.stop(true); - } - } } diff --git a/integration-tests/src/test/java/io/quarkus/it/jsch/SshServerResource.java b/integration-tests/src/test/java/io/quarkus/it/jsch/SshServerResource.java new file mode 100644 index 0000000..c61c4a6 --- /dev/null +++ b/integration-tests/src/test/java/io/quarkus/it/jsch/SshServerResource.java @@ -0,0 +1,58 @@ +package io.quarkus.it.jsch; + +import java.nio.file.Files; +import java.util.Map; + +import org.apache.sshd.server.SshServer; +import org.apache.sshd.server.auth.hostbased.AcceptAllHostBasedAuthenticator; +import org.apache.sshd.server.auth.password.AcceptAllPasswordAuthenticator; +import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator; +import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; +import org.apache.sshd.server.shell.UnknownCommandFactory; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +public class SshServerResource implements QuarkusTestResourceLifecycleManager { + + private SshServer sshd; + + @Override + public Map start() { + try { + sshd = SshServer.setUpDefaultServer(); + sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Files.createTempFile("host", "key"))); + sshd.setHostBasedAuthenticator(AcceptAllHostBasedAuthenticator.INSTANCE); + sshd.setPasswordAuthenticator(AcceptAllPasswordAuthenticator.INSTANCE); + sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE); + sshd.setCommandFactory(UnknownCommandFactory.INSTANCE); + sshd.setHost("localhost"); + sshd.start(); + + return Map.of( + "quarkus.jsch.session.host", sshd.getHost(), + "quarkus.jsch.session.port", Integer.toString(sshd.getPort()), + "quarkus.jsch.session.config.StrictHostKeyChecking", "no", + "quarkus.jsch.session.no-mock.host", sshd.getHost(), + "quarkus.jsch.session.no-mock.port", Integer.toString(sshd.getPort()), + "quarkus.jsch.session.no-mock.mock", "false", + "quarkus.jsch.session.no-mock.config.StrictHostKeyChecking", "no"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void stop() { + try { + sshd.stop(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void inject(TestInjector testInjector) { + testInjector.injectIntoFields(sshd, new TestInjector.AnnotatedAndMatchesType(WithSshTestServer.class, SshServer.class)); + } + +} diff --git a/integration-tests/src/test/java/io/quarkus/it/jsch/WithSshTestServer.java b/integration-tests/src/test/java/io/quarkus/it/jsch/WithSshTestServer.java new file mode 100644 index 0000000..fd19f1f --- /dev/null +++ b/integration-tests/src/test/java/io/quarkus/it/jsch/WithSshTestServer.java @@ -0,0 +1,11 @@ +package io.quarkus.it.jsch; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.FIELD }) +public @interface WithSshTestServer { +} diff --git a/runtime/src/main/java/io/quarkus/jsch/JSchSession.java b/runtime/src/main/java/io/quarkus/jsch/JSchSession.java new file mode 100644 index 0000000..c77c79c --- /dev/null +++ b/runtime/src/main/java/io/quarkus/jsch/JSchSession.java @@ -0,0 +1,24 @@ +package io.quarkus.jsch; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.inject.Qualifier; + +/** + * Create named session with Quarkus properties. + */ +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.FIELD }) +public @interface JSchSession { + + public static final String DEFAULT_SESSION_NAME = ""; + + /** + * The session name. + */ + String value() default DEFAULT_SESSION_NAME; +} diff --git a/runtime/src/main/java/io/quarkus/jsch/JSchSessions.java b/runtime/src/main/java/io/quarkus/jsch/JSchSessions.java new file mode 100644 index 0000000..deadcea --- /dev/null +++ b/runtime/src/main/java/io/quarkus/jsch/JSchSessions.java @@ -0,0 +1,155 @@ +package io.quarkus.jsch; + +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import jakarta.annotation.PreDestroy; + +import org.eclipse.microprofile.config.ConfigProvider; + +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.ProxyHTTP; +import com.jcraft.jsch.Session; +import com.jcraft.jsch.Slf4jLogger; + +import io.quarkus.arc.Arc; +import io.quarkus.jsch.runtime.JSchProxyConfig; +import io.quarkus.jsch.runtime.JSchRuntimeConfig; +import io.quarkus.jsch.runtime.JSchSessionRuntimeConfig; +import io.quarkus.runtime.LaunchMode; +import io.quarkus.runtime.configuration.ConfigurationException; +import io.smallrye.config.SmallRyeConfig; + +public class JSchSessions { + + private final ConcurrentHashMap sessions = new ConcurrentHashMap<>(); + + public JSchSessions() { + JSch.setLogger(new Slf4jLogger()); + } + + /** + * Get a session by name + * + * @param sessionName the session name + * @return the session + */ + public static Session fromName(String sessionName) { + return Arc.container().instance(JSchSessions.class).get().getSession(sessionName); + } + + /** + * Disconnect all sessions + */ + public static void shutdown() { + Arc.container().instance(JSchSessions.class).get().disconnect(); + } + + /** + * Get or create a session by name + * + * @param sessionName the session name + * @return the session + */ + public Session getSession(String sessionName) { + return sessions.computeIfAbsent(sessionName, this::createSession); + } + + /** + * Disconnect all sessions + */ + @PreDestroy + public void disconnect() { + sessions.values().forEach(Session::disconnect); + } + + private Session createSession(String sessionName) { + try { + JSchSessionRuntimeConfig config = getConfig(sessionName); + JSch jsch = new JSch(); + String baseProperty = this.getBaseProperty(sessionName); + Session session = jsch.getSession(config.username().orElse(null), config.host(), config.port()); + session.setServerAliveInterval(config.keepAliveInterval()); + + proxyConfig(config).ifPresent(c -> { + ProxyHTTP proxy = new ProxyHTTP(c.host(), c.port().orElse(JSchProxyConfig.DEFAULT_PORT)); + c.auth().ifPresent(a -> proxy.setUserPasswd(a.username(), a.password())); + session.setProxy(proxy); + }); + + config.password().ifPresent(session::setPassword); + + config.key().ifPresent(k -> { + try { + if (config.passphrase().isPresent()) { + jsch.addIdentity(k, config.passphrase().get()); + } else { + jsch.addIdentity(k); + } + } catch (Exception e) { + throw new ConfigurationException("Failed to add identity", e, Set.of( + baseProperty + "key", + baseProperty + "passphrase")); + } + }); + + config.config().forEach(session::setConfig); + session.connect(); + + return session; + } catch (JSchException e) { + throw new ConfigurationException("Failed to create session: " + sessionName, e); + } + } + + private String getBaseProperty(String sessionName) { + String baseProperty = "quarkus.jsch.sessions."; + if (!sessionName.equals(JSchSession.DEFAULT_SESSION_NAME)) { + baseProperty += sessionName + "."; + } + + return baseProperty; + } + + private JSchSessionRuntimeConfig getConfig(String sessionName) { + JSchRuntimeConfig configs = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class) + .getConfigMapping(JSchRuntimeConfig.class); + + if (isDevOrTest() && !JSchSession.DEFAULT_SESSION_NAME.equals(sessionName)) { + // return the default session except if the mock flag is set to false + JSchSessionRuntimeConfig c = configs.sessions().get(sessionName); + if (c == null || c.mock()) { + return configs.sessions().get(JSchSession.DEFAULT_SESSION_NAME); + } + + return c; + } + return configs.sessions().computeIfAbsent(sessionName, n -> { + throw new ConfigurationException("Session not found: " + sessionName); + }); + } + + private Optional proxyConfig(JSchSessionRuntimeConfig sessionConfig) { + JSchRuntimeConfig runtimeConfig = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class) + .getConfigMapping(JSchRuntimeConfig.class); + + Optional proxyConfig = sessionConfig.proxy(); + + if (proxyConfig.isEmpty()) { + proxyConfig = runtimeConfig.proxy(); + } + + if (proxyConfig.isEmpty() || !proxyConfig.get().enabled().orElse(true)) { + return Optional.empty(); + } + + return proxyConfig; + } + + private boolean isDevOrTest() { + return LaunchMode.current().isDevOrTest() + || "test".equals(ConfigProvider.getConfig().getValue("quarkus.profile", String.class)); + } +} diff --git a/runtime/src/main/java/io/quarkus/jsch/runtime/JSchProxyConfig.java b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchProxyConfig.java new file mode 100644 index 0000000..47ad893 --- /dev/null +++ b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchProxyConfig.java @@ -0,0 +1,59 @@ +package io.quarkus.jsch.runtime; + +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigDocDefault; +import io.quarkus.runtime.annotations.ConfigGroup; + +@ConfigGroup +public interface JSchProxyConfig { + + public static final Boolean DEFAULT_ENABLED = true; + public static final Integer DEFAULT_PORT = 80; + + /** + * Enable the proxy for the JSch session. + * + *

+ * Defaults to {@code true} if host is set. + */ + Optional enabled(); + + /** + * The host to use for the JSch proxy. + */ + String host(); + + /** + * The port to use for the JSch proxy. + */ + @ConfigDocDefault("80") + Optional port(); + + /** + * The username to use for the JSch proxy. + */ + Optional auth(); + + @ConfigGroup + interface Auth { + + /** + * The username to use for the JSch proxy. + * + *

+ * {@code proxy.auth} is optional. + */ + String username(); + + /** + * The password to use for the JSch proxy. + * + *

+ * {@code proxy.auth} is optional. + */ + String password(); + + } + +} diff --git a/runtime/src/main/java/io/quarkus/jsch/runtime/JSchRuntimeConfig.java b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchRuntimeConfig.java new file mode 100644 index 0000000..635402e --- /dev/null +++ b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchRuntimeConfig.java @@ -0,0 +1,36 @@ +package io.quarkus.jsch.runtime; + +import java.util.Map; +import java.util.Optional; + +import io.quarkus.jsch.JSchSession; +import io.quarkus.runtime.annotations.ConfigDocMapKey; +import io.quarkus.runtime.annotations.ConfigDocSection; +import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefaults; +import io.smallrye.config.WithName; +import io.smallrye.config.WithUnnamedKey; + +@ConfigMapping(prefix = "quarkus.jsch") +@ConfigRoot(phase = ConfigPhase.RUN_TIME) +public interface JSchRuntimeConfig { + + /** + * JSch sessions. + */ + @ConfigDocMapKey("session-name") + @WithDefaults + @WithUnnamedKey(JSchSession.DEFAULT_SESSION_NAME) + @WithName("session") + @ConfigDocSection + Map sessions(); + + /** + * The default proxy configuration to use for each JSch session. + */ + @ConfigDocSection + Optional proxy(); + +} diff --git a/runtime/src/main/java/io/quarkus/jsch/runtime/JSchSessionRecorder.java b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchSessionRecorder.java new file mode 100644 index 0000000..2e9733a --- /dev/null +++ b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchSessionRecorder.java @@ -0,0 +1,17 @@ +package io.quarkus.jsch.runtime; + +import java.util.function.Supplier; + +import com.jcraft.jsch.Session; + +import io.quarkus.jsch.JSchSessions; +import io.quarkus.runtime.annotations.Recorder; + +@Recorder +public class JSchSessionRecorder { + + public Supplier jschSessionSupplier(String sessionName) { + return () -> JSchSessions.fromName(sessionName); + } + +} diff --git a/runtime/src/main/java/io/quarkus/jsch/runtime/JSchSessionRuntimeConfig.java b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchSessionRuntimeConfig.java new file mode 100644 index 0000000..f0eff1f --- /dev/null +++ b/runtime/src/main/java/io/quarkus/jsch/runtime/JSchSessionRuntimeConfig.java @@ -0,0 +1,71 @@ +package io.quarkus.jsch.runtime; + +import java.util.Map; +import java.util.Optional; + +import io.quarkus.runtime.annotations.ConfigDocMapKey; +import io.quarkus.runtime.annotations.ConfigDocSection; +import io.quarkus.runtime.annotations.ConfigGroup; +import io.smallrye.config.WithDefault; + +@ConfigGroup +public interface JSchSessionRuntimeConfig { + + /** + * The host to use for the JSch session. + */ + @WithDefault("localhost") + String host(); + + /** + * The port to use for the JSch session. + */ + @WithDefault("22") + int port(); + + /** + * The username to use for the JSch session. + */ + Optional username(); + + /** + * The password to use for the JSch session. + */ + Optional password(); + + /** + * The private key to use for the JSch session. + */ + Optional key(); + + /** + * The passphrase to use for the JSch session. + */ + Optional passphrase(); + + /** + * The configuration to use for the JSch session. + */ + @ConfigDocMapKey("config-name") + Map config(); + + /** + * Mock the JSch session in dev and test mode. + */ + @WithDefault("true") + boolean mock(); + + /** + * The keep alive interval to use for the JSch session. + *

+ * If zero is specified, any keep-alive message. + */ + @WithDefault("0") + int keepAliveInterval(); + + /** + * The proxy to use for the JSch session. + */ + @ConfigDocSection + Optional proxy(); +} diff --git a/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/runtime/src/main/resources/META-INF/quarkus-extension.yaml index 91d0833..d1486f2 100644 --- a/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -6,4 +6,6 @@ metadata: guide: https://quarkiverse.github.io/quarkiverse-docs/quarkus-jsch/dev/index.html categories: - "miscellaneous" + config: + - "quarkus.jsch." # status: "preview"