All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sentrysoftware.metricshub.extension.win.WinCommandService Maven / Gradle / Ivy

package org.sentrysoftware.metricshub.extension.win;

/*-
 * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
 * MetricsHub Win Extension Common
 * ჻჻჻჻჻჻
 * Copyright 2023 - 2024 Sentry Software
 * ჻჻჻჻჻჻
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see .
 * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
 */

import static org.sentrysoftware.metricshub.engine.common.helpers.MetricsHubConstants.HOSTNAME_MACRO;
import static org.sentrysoftware.metricshub.engine.common.helpers.MetricsHubConstants.PASSWORD_MACRO;
import static org.sentrysoftware.metricshub.engine.common.helpers.MetricsHubConstants.USERNAME_MACRO;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.sentrysoftware.metricshub.engine.common.exception.ClientException;
import org.sentrysoftware.metricshub.engine.common.exception.NoCredentialProvidedException;
import org.sentrysoftware.metricshub.engine.connector.model.common.EmbeddedFile;
import org.sentrysoftware.metricshub.engine.strategy.utils.EmbeddedFileHelper;
import org.sentrysoftware.metricshub.engine.strategy.utils.OsCommandHelper;
import org.sentrysoftware.metricshub.engine.strategy.utils.OsCommandResult;

/**
 * Provides a service for executing Windows commands through Windows Management Instrumentation (WMI).
 */
@RequiredArgsConstructor
public class WinCommandService {

	@NonNull
	private IWinRequestExecutor winRequestExecutor;

	/**
	 * Get the username from the IWinConfiguration.
	 *
	 * @param configuration IWinConfiguration instance.
	 * @return An optional with the username if found. An empty optional otherwise.
	 */
	public Optional getUsername(final IWinConfiguration configuration) {
		if (configuration == null) {
			return Optional.empty();
		}
		return Optional.ofNullable(configuration.getUsername());
	}

	/**
	 * Get the password from the IWinConfiguration.
	 *
	 * @param configuration IWinConfiguration instance.
	 * @return An optional with the password if found. An empty optional otherwise.
	 */
	public Optional getPassword(final IWinConfiguration configuration) {
		if (configuration == null) {
			return Optional.empty();
		}
		return Optional.ofNullable(configuration.getPassword());
	}

	/**
	 * Run the OS Command on Remote windows (use WMI/WinRm command)
	 * 

It replaces Host name, User name, Password, Sudo, Embedded files macros in the command line.

*

If necessary, it creates embedded files and deletes them after the command execution.

* * @param commandLine The command Line. (mandatory) * @param hostname The hostname of the remote device where the WMI or WinRm service is running. (mandatory) * @param configuration Windows Protocol configuration (credentials, timeout). E.g. WMI or WinRm. * @param connectorEmbeddedFiles All the embedded files defined by the connector object. (mandatory) * * @return The command execution return and the command with password masked (if present). * @throws IOException When an I/O error occurred on local command execution or embedded file creation. * @throws ClientException When an error occurred on remote execution. * @throws NoCredentialProvidedException When there's no user provided for a remote command. */ public OsCommandResult runOsCommand( @NonNull final String commandLine, @NonNull final String hostname, final IWinConfiguration configuration, @NonNull Map connectorEmbeddedFiles ) throws IOException, ClientException, NoCredentialProvidedException { final Optional maybeUsername = getUsername(configuration); // Remote command and no username if ((maybeUsername.isEmpty() || maybeUsername.get().isBlank())) { throw new NoCredentialProvidedException(); } final Optional maybePassword = getPassword(configuration); final Map embeddedTempFiles = OsCommandHelper.createOsCommandEmbeddedFiles( commandLine, null, EmbeddedFileHelper.findEmbeddedFiles(commandLine, connectorEmbeddedFiles), OsCommandHelper.TEMP_FILE_CREATOR ); final String updatedUserCommand = maybeUsername .map(username -> commandLine.replaceAll(OsCommandHelper.toCaseInsensitiveRegex(USERNAME_MACRO), username)) .orElse(commandLine); final String updatedHostnameCommand = updatedUserCommand.replaceAll( OsCommandHelper.toCaseInsensitiveRegex(HOSTNAME_MACRO), hostname ); final String updatedSudoCommand = OsCommandHelper.replaceSudo(updatedHostnameCommand, null); final String updatedEmbeddedFilesCommand = embeddedTempFiles .entrySet() .stream() .reduce( updatedSudoCommand, (s, entry) -> s.replaceAll( OsCommandHelper.toCaseInsensitiveRegex(entry.getKey()), Matcher.quoteReplacement(entry.getValue().getAbsolutePath()) ), (s1, s2) -> null ); final String command = maybePassword .map(password -> updatedEmbeddedFilesCommand.replaceAll( OsCommandHelper.toCaseInsensitiveRegex(PASSWORD_MACRO), String.valueOf(password) ) ) .orElse(updatedEmbeddedFilesCommand); final String noPasswordCommand = maybePassword .map(password -> updatedEmbeddedFilesCommand.replaceAll(OsCommandHelper.toCaseInsensitiveRegex(PASSWORD_MACRO), "********") ) .orElse(updatedEmbeddedFilesCommand); try { final String commandResult = winRequestExecutor.executeWinRemoteCommand( hostname, configuration, command, embeddedTempFiles.values().stream().map(File::getAbsolutePath).collect(Collectors.toList()) // NOSONAR ); return new OsCommandResult(commandResult, noPasswordCommand); } finally { //noinspection ResultOfMethodCallIgnored embeddedTempFiles.values().forEach(File::delete); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy