Skip to content
Snippets Groups Projects
Commit 9de45b7a authored by Lukasz Lopatowski's avatar Lukasz Lopatowski
Browse files

Merge branch '251-remove-nmaas-helm-interaction' into 'develop'

Resolve "Remove nmaas-helm interaction"

See merge request !133
parents 2c59277d b833f949
No related branches found
No related tags found
1 merge request!133Resolve "Remove nmaas-helm interaction"
Pipeline #93179 passed
Showing
with 159 additions and 316 deletions
...@@ -4,20 +4,39 @@ COPY . /build/ ...@@ -4,20 +4,39 @@ COPY . /build/
WORKDIR /build/ WORKDIR /build/
RUN chmod +x ./gradlew \ RUN chmod +x ./gradlew \
&& ./gradlew -Dorg.gradle.daemon=false build && ./gradlew -Dorg.gradle.daemon=false build -x test
FROM eclipse-temurin:17-jre-alpine FROM eclipse-temurin:17-jre-alpine
LABEL maintainer=nmaas@lists.geant.org LABEL maintainer=nmaas@lists.geant.org
ARG USERNAME=nmaas
ARG USER_UID=1000
ARG USER_GID=1000
# Note: Latest version of kubectl may be found at https://github.com/kubernetes/kubernetes/releases
ARG KUBE_LATEST_VERSION="v1.16.3"
# Note: Latest version of helm may be found at https://github.com/kubernetes/helm/releases
ARG HELM_VERSION="v3.9.3"
COPY --from=builder /build/build/libs/*.jar /nmaas/platform/ COPY --from=builder /build/build/libs/*.jar /nmaas/platform/
COPY docker/run_platform.sh /nmaas/scripts/run_platform.sh COPY docker/docker_entrypoint.sh /nmaas/scripts/docker_entrypoint.sh
COPY docker/logback.xml /nmaas/platform/config/logback.xml COPY docker/logback.xml /nmaas/platform/config/logback.xml
COPY docker/do-ntp.sh /etc/periodic/hourly/do-ntp.sh COPY docker/do-ntp.sh /etc/periodic/hourly/do-ntp.sh
COPY docker/ssh-config /root/.ssh/config
RUN addgroup -g $USER_GID $USERNAME \
&& adduser --disabled-password -u $USER_UID -G $USERNAME $USERNAME
RUN apk --no-cache add gettext postgresql-client \ RUN apk --no-cache add gettext postgresql-client \
&& mkdir /nmaas/files \ && mkdir /nmaas/files \
&& chmod +x /nmaas/scripts/run_platform.sh && chmod +x /nmaas/scripts/docker_entrypoint.sh \
&& wget -q https://storage.googleapis.com/kubernetes-release/release/${KUBE_LATEST_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl \
&& chmod +x /usr/local/bin/kubectl \
&& wget -q https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz -O - | tar -xzO linux-amd64/helm > /usr/local/bin/helm \
&& chmod +x /usr/local/bin/helm
RUN chown -R $USERNAME:$USERNAME /nmaas/files
USER $USERNAME
ENTRYPOINT /nmaas/scripts/docker_entrypoint.sh
CMD /nmaas/scripts/run_platform.sh && tail -f /dev/null CMD ls /home
\ No newline at end of file \ No newline at end of file
...@@ -2,7 +2,7 @@ plugins { ...@@ -2,7 +2,7 @@ plugins {
id 'java' id 'java'
id 'idea' id 'idea'
id 'jacoco' id 'jacoco'
id 'org.springframework.boot' version '3.4.3' id 'org.springframework.boot' version '3.4.4'
id 'io.spring.dependency-management' version '1.1.7' id 'io.spring.dependency-management' version '1.1.7'
id 'com.gorylenko.gradle-git-properties' version '2.4.2' id 'com.gorylenko.gradle-git-properties' version '2.4.2'
id 'org.sonarqube' version '6.0.1.5171' id 'org.sonarqube' version '6.0.1.5171'
...@@ -13,7 +13,7 @@ repositories { ...@@ -13,7 +13,7 @@ repositories {
mavenCentral() mavenCentral()
} }
version = '1.7.0' version = '1.8.0-SNAPSHOT'
group = 'net.geant.nmaas' group = 'net.geant.nmaas'
java { java {
...@@ -30,11 +30,11 @@ gitProperties { ...@@ -30,11 +30,11 @@ gitProperties {
protobuf { protobuf {
protoc { protoc {
artifact = 'com.google.protobuf:protoc:4.29.3' artifact = 'com.google.protobuf:protoc:4.30.2'
} }
plugins { plugins {
grpc { grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.69.1' artifact = 'io.grpc:protoc-gen-grpc-java:1.71.0'
} }
} }
generateProtoTasks { generateProtoTasks {
...@@ -125,21 +125,17 @@ dependencies { ...@@ -125,21 +125,17 @@ dependencies {
implementation 'ch.qos.logback:logback-core:1.5.17' implementation 'ch.qos.logback:logback-core:1.5.17'
// SSH library
implementation('com.hierynomus:sshj:0.32.0')
implementation('com.fasterxml.jackson.datatype:jackson-datatype-jsr310')
// Kubernetes API client // Kubernetes API client
implementation('io.fabric8:kubernetes-client:6.13.5') implementation('io.fabric8:kubernetes-client:6.13.5')
implementation('com.google.protobuf:protobuf-java:4.29.3') implementation('com.google.protobuf:protobuf-java:4.30.2')
implementation('io.grpc:grpc-netty-shaded:1.69.1') implementation('io.grpc:grpc-netty-shaded:1.71.0')
implementation('io.grpc:grpc-protobuf:1.69.1') implementation('io.grpc:grpc-protobuf:1.71.0')
implementation('io.grpc:grpc-stub:1.69.1') implementation('io.grpc:grpc-stub:1.71.0')
implementation('com.opencsv:opencsv:5.9') implementation('com.opencsv:opencsv:5.9')
testImplementation('org.mockito:mockito-inline:5.2.0') testImplementation('org.mockito:mockito-core:5.16.1')
testImplementation('org.springframework.boot:spring-boot-starter-test') testImplementation('org.springframework.boot:spring-boot-starter-test')
integrationTestImplementation('org.springframework.boot:spring-boot-starter-test') integrationTestImplementation('org.springframework.boot:spring-boot-starter-test')
......
#!/bin/sh #!/bin/sh
export HELM_HOME=/home/nmaas/.helm
mkdir -p $HELM_HOME
helm repo add nmaas https://artifactory.software.geant.org/artifactory/nmaas-helm
helm repo add influxdata https://helm.influxdata.com/
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add jenkins https://charts.jenkins.io
cat >> /home/nmaas/.profile <<EOF
export HELM_HOME=$HELM_HOME
export HELM_HOST=$HELM_HOST
export TILLER_NAMESPACE=$TILLER_NAMESPACE
export KUBERNETES_SERVICE_HOST=kubernetes.default
export KUBERNETES_SERVICE_PORT=443
EOF
DIR=/nmaas/platform DIR=/nmaas/platform
FILE=$(ls $DIR | grep .jar) FILE=$(ls $DIR | grep .jar)
cd $DIR cd $DIR
mkdir -p /root/.ssh
cp /nmaas/.ssh/id_rsa /root/.ssh/id_rsa
chmod 600 /root/.ssh/id_rsa
mkdir -p /nmaas/files/upload mkdir -p /nmaas/files/upload
mkdir -p /nmaas/files/log mkdir -p /nmaas/files/log
...@@ -14,10 +29,11 @@ until PGPASSWORD=${POSTGRESQL_PASSWORD} psql -h "${POSTGRESQL_HOST}" -p ${POSTGR ...@@ -14,10 +29,11 @@ until PGPASSWORD=${POSTGRESQL_PASSWORD} psql -h "${POSTGRESQL_HOST}" -p ${POSTGR
done done
if PGPASSWORD=${POSTGRESQL_PASSWORD} psql -h "${POSTGRESQL_HOST}" -p ${POSTGRESQL_PORT} -U "${POSTGRESQL_USERNAME}" -lqt | cut -d \| -f 1 | grep -qw ${POSTGRESQL_DBNAME}; then if PGPASSWORD=${POSTGRESQL_PASSWORD} psql -h "${POSTGRESQL_HOST}" -p ${POSTGRESQL_PORT} -U "${POSTGRESQL_USERNAME}" -lqt | cut -d \| -f 1 | grep -qw ${POSTGRESQL_DBNAME}; then
echo "Database is already setup" echo "Database is already exists"
else else
echo "Database is being created..." echo "Database needs to be created. Creating ..."
PGPASSWORD=${POSTGRESQL_PASSWORD} createdb ${POSTGRESQL_DBNAME} -h "${POSTGRESQL_HOST}" -p ${POSTGRESQL_PORT} -U "${POSTGRESQL_USERNAME}" ${POSTGRESQL_DBNAME} PGPASSWORD=${POSTGRESQL_PASSWORD} createdb ${POSTGRESQL_DBNAME} -h "${POSTGRESQL_HOST}" -p ${POSTGRESQL_PORT} -U "${POSTGRESQL_USERNAME}" ${POSTGRESQL_DBNAME}
fi fi
java -Djava.security.egd=file:/dev/./urandom -Dlogging.config=/nmaas/platform/config/logback.xml -jar $FILE echo "Running nmaas-platform ..."
java -Djava.security.egd=file:/dev/./urandom -Dlogging.config=/nmaas/platform/config/logback.xml -jar $FILE
\ No newline at end of file
Host nmaas-helm
Hostname nmaas-helm
IdentityFile ~/.ssh/id_rsa
User helm
...@@ -86,8 +86,6 @@ spring.security.oauth2.client.provider.keycloak.user-info-uri=http://localhost:8 ...@@ -86,8 +86,6 @@ spring.security.oauth2.client.provider.keycloak.user-info-uri=http://localhost:8
helm.update.async.enabled=false helm.update.async.enabled=false
helm.update.async.cron=0 * * * * ? helm.update.async.cron=0 * * * * ?
helm.address=10.134.241.6
helm.username=nmaas
helm.useLocalCharts=true helm.useLocalCharts=true
helm.repositoryName=nmaas-test helm.repositoryName=nmaas-test
helm.repositoryUrl=https://nmaas-test.helm.repository helm.repositoryUrl=https://nmaas-test.helm.repository
......
package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes; package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm.HelmKServiceManager; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm.HelmKServiceManager;
import net.geant.nmaas.scheduling.ScheduleManager; import net.geant.nmaas.scheduling.ScheduleManager;
import net.geant.nmaas.utils.ssh.CommandExecutionException; import net.geant.nmaas.utils.bash.CommandExecutionException;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
......
package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm; package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm;
import net.geant.nmaas.utils.ssh.Command; import net.geant.nmaas.utils.bash.Command;
public abstract class HelmCommand implements Command { public abstract class HelmCommand implements Command {
...@@ -24,7 +24,7 @@ public abstract class HelmCommand implements Command { ...@@ -24,7 +24,7 @@ public abstract class HelmCommand implements Command {
} }
protected static void addTlsOptionIfRequired(String helmVersion, boolean enableTls, StringBuilder sb) { protected static void addTlsOptionIfRequired(String helmVersion, boolean enableTls, StringBuilder sb) {
if(HELM_VERSION_2.equals(helmVersion) && enableTls){ if (HELM_VERSION_2.equals(helmVersion) && enableTls) {
sb.append(SPACE).append(TLS); sb.append(SPACE).append(TLS);
} }
} }
......
...@@ -10,9 +10,9 @@ import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.co ...@@ -10,9 +10,9 @@ import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.co
import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm.commands.HelmUpgradeCommand; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm.commands.HelmUpgradeCommand;
import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm.commands.HelmVersionCommand; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.components.helm.commands.HelmVersionCommand;
import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.entities.KubernetesTemplate; import net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.entities.KubernetesTemplate;
import net.geant.nmaas.utils.ssh.CommandExecutionException; import net.geant.nmaas.utils.bash.CommandExecutionException;
import net.geant.nmaas.utils.ssh.SingleCommandExecutor; import net.geant.nmaas.utils.bash.CommandExecutor;
import net.geant.nmaas.utils.ssh.SshConnectionException; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -25,15 +25,12 @@ import static net.geant.nmaas.nmservice.deployment.containerorchestrators.kubern ...@@ -25,15 +25,12 @@ import static net.geant.nmaas.nmservice.deployment.containerorchestrators.kubern
@Component @Component
public class HelmCommandExecutor { public class HelmCommandExecutor {
@Autowired
CommandExecutor commandExecutor;
@Value("${helm.version:v3}") @Value("${helm.version:v3}")
String helmVersion; String helmVersion;
@Value("${helm.address}")
String helmAddress;
@Value("${helm.username}")
String helmUsername;
@Value("${helm.useLocalCharts}") @Value("${helm.useLocalCharts}")
Boolean useLocalCharts; Boolean useLocalCharts;
...@@ -73,9 +70,8 @@ public class HelmCommandExecutor { ...@@ -73,9 +70,8 @@ public class HelmCommandExecutor {
enableTls enableTls
); );
} }
singleCommandExecutor().executeSingleCommand(command); commandExecutor.execute(command);
} catch (SshConnectionException } catch (CommandExecutionException e) {
| CommandExecutionException e) {
throw new CommandExecutionException("Failed to execute helm install command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm install command -> " + e.getMessage());
} }
} }
...@@ -105,9 +101,8 @@ public class HelmCommandExecutor { ...@@ -105,9 +101,8 @@ public class HelmCommandExecutor {
} else { } else {
throw new CommandExecutionException("Unknown Helm version in use: " + helmVersion); throw new CommandExecutionException("Unknown Helm version in use: " + helmVersion);
} }
singleCommandExecutor().executeSingleCommand(command); commandExecutor.execute(command);
} catch (SshConnectionException } catch (CommandExecutionException e) {
| CommandExecutionException e) {
throw new CommandExecutionException("Failed to execute helm delete command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm delete command -> " + e.getMessage());
} }
} }
...@@ -124,16 +119,15 @@ public class HelmCommandExecutor { ...@@ -124,16 +119,15 @@ public class HelmCommandExecutor {
releaseName, releaseName,
enableTls enableTls
); );
String output = singleCommandExecutor().executeSingleCommandAndReturnOutput(command); String output = commandExecutor.executeWithOutput(command);
return parseStatus(output); return parseStatus(output);
} catch (SshConnectionException } catch (CommandExecutionException e) {
| CommandExecutionException e) {
throw new CommandExecutionException("Failed to execute helm status command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm status command -> " + e.getMessage());
} }
} }
HelmPackageStatus parseStatus(String output) { HelmPackageStatus parseStatus(String output) {
if(HELM_VERSION_2.equals(helmVersion) && output.contains("STATUS: DEPLOYED")) { if (HELM_VERSION_2.equals(helmVersion) && output.contains("STATUS: DEPLOYED")) {
return HelmPackageStatus.DEPLOYED; return HelmPackageStatus.DEPLOYED;
} else if (HelmCommand.HELM_VERSION_3.equals(helmVersion) && output.contains("STATUS: deployed")) { } else if (HelmCommand.HELM_VERSION_3.equals(helmVersion) && output.contains("STATUS: deployed")) {
return HelmPackageStatus.DEPLOYED; return HelmPackageStatus.DEPLOYED;
...@@ -149,10 +143,9 @@ public class HelmCommandExecutor { ...@@ -149,10 +143,9 @@ public class HelmCommandExecutor {
namespace, namespace,
enableTls enableTls
); );
String output = singleCommandExecutor().executeSingleCommandAndReturnOutput(command); String output = commandExecutor.executeWithOutput(command);
return Arrays.asList(output.split("\n")); return Arrays.asList(output.split("\n"));
} catch (SshConnectionException } catch (CommandExecutionException e) {
| CommandExecutionException e) {
throw new CommandExecutionException("Failed to execute helm list command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm list command -> " + e.getMessage());
} }
} }
...@@ -178,38 +171,32 @@ public class HelmCommandExecutor { ...@@ -178,38 +171,32 @@ public class HelmCommandExecutor {
enableTls enableTls
); );
} }
singleCommandExecutor().executeSingleCommand(command); commandExecutor.execute(command);
} catch (SshConnectionException e) { } catch (CommandExecutionException e) {
throw new CommandExecutionException("Failed to execute helm upgrade command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm upgrade command -> " + e.getMessage());
} }
} }
void executeVersionCommand() { void executeVersionCommand() {
try{ try {
singleCommandExecutor().executeSingleCommand( commandExecutor.execute(HelmVersionCommand.command(helmVersion, enableTls));
HelmVersionCommand.command(helmVersion, enableTls) } catch (CommandExecutionException e) {
);
} catch (SshConnectionException e) {
throw new CommandExecutionException("Failed to execute helm version command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm version command -> " + e.getMessage());
} }
} }
private SingleCommandExecutor singleCommandExecutor() {
return SingleCommandExecutor.getExecutor(helmAddress, helmUsername);
}
void executeHelmRepoUpdateCommand() { void executeHelmRepoUpdateCommand() {
try{ try {
singleCommandExecutor().executeSingleCommand(HelmRepoUpdateCommand.command()); commandExecutor.execute(HelmRepoUpdateCommand.command());
} catch (SshConnectionException e) { } catch (CommandExecutionException e) {
throw new CommandExecutionException("Failed to execute helm repository update command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm repository update command -> " + e.getMessage());
} }
} }
void executeHelmRepoAddCommand(String repoName, String repoUrl) { void executeHelmRepoAddCommand(String repoName, String repoUrl) {
try{ try {
singleCommandExecutor().executeSingleCommand(HelmRepoAddCommand.command(repoName, repoUrl)); commandExecutor.execute(HelmRepoAddCommand.command(repoName, repoUrl));
} catch (SshConnectionException e) { } catch (CommandExecutionException e) {
throw new CommandExecutionException("Failed to execute helm repository add command -> " + e.getMessage()); throw new CommandExecutionException("Failed to execute helm repository add command -> " + e.getMessage());
} }
} }
......
...@@ -18,7 +18,7 @@ import net.geant.nmaas.orchestration.Identifier; ...@@ -18,7 +18,7 @@ import net.geant.nmaas.orchestration.Identifier;
import net.geant.nmaas.orchestration.repositories.DomainTechDetailsRepository; import net.geant.nmaas.orchestration.repositories.DomainTechDetailsRepository;
import net.geant.nmaas.utils.logging.LogLevel; import net.geant.nmaas.utils.logging.LogLevel;
import net.geant.nmaas.utils.logging.Loggable; import net.geant.nmaas.utils.logging.Loggable;
import net.geant.nmaas.utils.ssh.CommandExecutionException; import net.geant.nmaas.utils.bash.CommandExecutionException;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
......
...@@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j; ...@@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import net.geant.nmaas.monitor.MonitorService; import net.geant.nmaas.monitor.MonitorService;
import net.geant.nmaas.monitor.MonitorStatus; import net.geant.nmaas.monitor.MonitorStatus;
import net.geant.nmaas.monitor.ServiceType; import net.geant.nmaas.monitor.ServiceType;
import net.geant.nmaas.utils.ssh.CommandExecutionException; import net.geant.nmaas.utils.bash.CommandExecutionException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
......
...@@ -16,13 +16,13 @@ public class HelmInstallCommand extends HelmCommand { ...@@ -16,13 +16,13 @@ public class HelmInstallCommand extends HelmCommand {
/** /**
* Creates {@link HelmInstallCommand} with provided custom input * Creates {@link HelmInstallCommand} with provided custom input
* *
* @param helmVersion version of Helm in use * @param helmVersion version of Helm in use
* @param namespace namespace to install the release into * @param namespace namespace to install the release into
* @param releaseName release name * @param releaseName release name
* @param values a map of key - value pairs to customize the release installation * @param values a map of key - value pairs to customize the release installation
* @param chartName chart name for download from repository * @param chartName chart name for download from repository
* @param chartVersion chart version from download from repository * @param chartVersion chart version from download from repository
* @param enableTls flag indicating if tls option should be added * @param enableTls flag indicating if tls option should be added
* @return complete command object * @return complete command object
*/ */
public static HelmInstallCommand commandWithRepo(String helmVersion, String namespace, String releaseName, Map<String, String> values, String chartName, String chartVersion, boolean enableTls) { public static HelmInstallCommand commandWithRepo(String helmVersion, String namespace, String releaseName, Map<String, String> values, String chartName, String chartVersion, boolean enableTls) {
...@@ -41,10 +41,10 @@ public class HelmInstallCommand extends HelmCommand { ...@@ -41,10 +41,10 @@ public class HelmInstallCommand extends HelmCommand {
/** /**
* Creates {@link HelmInstallCommand} with provided custom input and local chart archive * Creates {@link HelmInstallCommand} with provided custom input and local chart archive
* *
* @param helmVersion version of Helm in use * @param helmVersion version of Helm in use
* @param namespace namespace to install the release into * @param namespace namespace to install the release into
* @param releaseName release name * @param releaseName release name
* @param values a map of key - value pairs to customize the release installation * @param values a map of key - value pairs to customize the release installation
* @param chartArchive complete path to the release chart archive * @param chartArchive complete path to the release chart archive
* @return complete command object * @return complete command object
*/ */
...@@ -75,7 +75,7 @@ public class HelmInstallCommand extends HelmCommand { ...@@ -75,7 +75,7 @@ public class HelmInstallCommand extends HelmCommand {
} }
public static String commaSeparatedValuesString(Map<String, String> values) { public static String commaSeparatedValuesString(Map<String, String> values) {
values.entrySet().forEach(e -> log.info(e.getKey() + " " + e.getValue())); values.forEach((key, value) -> log.info("{} {}", key, value));
return values.entrySet().stream() return values.entrySet().stream()
.map(entry -> { .map(entry -> {
if (entry.getKey().contains(TEXT_TO_REPLACE_WITH_VALUE)) { if (entry.getKey().contains(TEXT_TO_REPLACE_WITH_VALUE)) {
......
package net.geant.nmaas.utils.ssh; package net.geant.nmaas.utils.bash;
import java.util.function.Predicate; import java.util.function.Predicate;
......
package net.geant.nmaas.utils.ssh; package net.geant.nmaas.utils.bash;
public class CommandExecutionException extends RuntimeException { public class CommandExecutionException extends RuntimeException {
......
package net.geant.nmaas.utils.bash;
public interface CommandExecutor {
void execute(Command command) throws CommandExecutionException;
String executeWithOutput(Command command) throws CommandExecutionException;
}
\ No newline at end of file
package net.geant.nmaas.utils.bash;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Slf4j
@Component
public class DefaultCommandExecutor implements CommandExecutor {
@Override
public void execute(Command command) throws CommandExecutionException {
try {
new ProcessBuilder(command.asString()).start();
} catch (IOException e) {
throw new CommandExecutionException(e.getMessage());
}
}
@Override
public String executeWithOutput(Command command) throws CommandExecutionException {
try {
Process process = new ProcessBuilder(command.asString()).start();
final String output = new String(process.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
log.debug("Output: {}", output);
return output;
} catch (IOException e) {
throw new CommandExecutionException(e.getMessage());
}
}
}
package net.geant.nmaas.utils.ssh;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public class BasicCredentials {
private final String username;
private final String password;
public BasicCredentials(String username) {
this.username = username;
this.password = null;
}
}
package net.geant.nmaas.utils.ssh;
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
import java.security.PublicKey;
import java.util.Collections;
import java.util.List;
public class DummyHostKeyVerifier implements HostKeyVerifier {
@Override
public boolean verify(String hostname, int port, PublicKey key) {
return true;
}
@Override
public List<String> findExistingAlgorithms(String hostname, int port) {
return Collections.emptyList();
}
}
package net.geant.nmaas.utils.ssh;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import java.util.function.Predicate;
@Slf4j
public class SingleCommandExecutor {
private final String hostname;
private final int port;
private final BasicCredentials credentials;
private SshConnector connector = null;
private static SingleCommandExecutor defaultExecutor;
public static SingleCommandExecutor getExecutor(String hostname, String username) {
if (defaultExecutor != null) {
return defaultExecutor;
}
return new SingleCommandExecutor(hostname, 22, new BasicCredentials(username, null));
}
public static SingleCommandExecutor getExecutor(String hostname, BasicCredentials credentials) {
if (defaultExecutor != null) {
return defaultExecutor;
}
return new SingleCommandExecutor(hostname, 22, credentials);
}
public static SingleCommandExecutor getExecutor(String hostname, int port, BasicCredentials credentials) {
if (defaultExecutor != null) {
return defaultExecutor;
}
return new SingleCommandExecutor(hostname, port, credentials);
}
public static void setDefaultExecutor(SingleCommandExecutor executor) {
defaultExecutor = executor;
}
private SingleCommandExecutor(String hostname, int port, BasicCredentials credentials) {
this.hostname = hostname;
this.port = port;
this.credentials = credentials;
}
public void executeSingleCommand(Command command) {
log.trace("command : {}", command.asString());
executeCommand(command);
}
public String executeSingleCommandAndReturnOutput(Command command) {
return executeCommand(command);
}
private String executeCommand(Command command) {
connect();
String output = execute(command);
validateOutput(output, command.isOutputCorrect());
disconnect();
return output;
}
private void connect() {
log.trace("Connecting to {}", hostname);
connector = new SshConnector(hostname, port, credentials);
}
private String execute(Command command) {
log.trace("Executing command: {}", command.asString());
return connector.executeSingleCommand(command.asString());
}
void validateOutput(String output, Predicate<String> isOutputCorrect) {
if (isOutputCorrect.negate().test(output)) {
throw new CommandExecutionException("Identified problem with command execution based on output -> details: " + output + ")");
}
}
private void disconnect() {
if (connector != null) {
connector.close();
connector = null;
}
}
}
package net.geant.nmaas.utils.ssh;
public class SshConnectionException extends RuntimeException {
public SshConnectionException(String message) {
super(message);
}
public SshConnectionException(String message, Throwable cause) {
super(message, cause);
}
}
package net.geant.nmaas.utils.ssh;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.connection.channel.direct.Session;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@NoArgsConstructor
@Slf4j
public class SshConnector {
private SSHClient ssh;
SshConnector(String hostname, int port, BasicCredentials credentials) {
connect(hostname, port);
if (isConnected()) {
authenticate(credentials);
}
}
private void connect(String hostname, int port) {
try {
ssh = new SSHClient();
ssh.addHostKeyVerifier(new DummyHostKeyVerifier());
ssh.connect(hostname, port);
} catch (IOException ex) {
ssh = null;
throw new SshConnectionException("Unable to connect -> " + ex.getMessage());
}
}
private void authenticate(BasicCredentials credentials) {
if (ssh == null || !isConnected()) {
throw new SshConnectionException("Not connected.");
}
try {
ssh.authPublickey(credentials.getUsername());
} catch(IOException ex) {
throw new SshConnectionException("Unable to authenticate due to some errors -> " + ex.getMessage());
}
}
String executeSingleCommand(String command) {
if(!isAuthenticated()) {
throw new SshConnectionException("Not authenticated connection to " + ssh.getRemoteAddress());
}
try (Session session = ssh.startSession()) {
final Session.Command c = session.exec(command);
String error = IOUtils.readFully(c.getErrorStream()).toString();
String output = IOUtils.readFully(c.getInputStream()).toString();
c.join(5, TimeUnit.SECONDS);
if (exitStatusIndicatesThatSomethingWentWrong(c.getExitStatus())) {
throw new CommandExecutionException("Command execution failed (exit status: " + c.getExitStatus() + "; details: " + error + ")");
}
return output;
} catch (IOException ex) {
throw new SshConnectionException("Unable to read command execution error message -> " + ex.getMessage());
}
}
void close() {
if (ssh != null) {
try {
ssh.disconnect();
} catch (IOException e) {
log.warn(e.getMessage());
}
ssh = null;
}
}
private boolean exitStatusIndicatesThatSomethingWentWrong(int exitStatus) {
return exitStatus != 0;
}
private boolean isConnected() {
return ssh.isConnected();
}
private boolean isAuthenticated() {
return (isConnected() && ssh.isAuthenticated());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment