Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #114: Develop IPMI Extension #156

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion metricshub-agent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@
</execution>
</executions>
</plugin>

</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.sentrysoftware.metricshub.engine.configuration.IConfiguration;

/**
* This abstract class defines a generic protocol configuration that will be extended to configure all the protocols such as {@link SshProtocolConfig} or {@link IpmiProtocolConfig}).
* This abstract class defines a generic protocol configuration that will be extended to configure all the protocols.
*/
public abstract class AbstractProtocolConfig {

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public class ProtocolsConfig {
private IConfiguration snmp;

@JsonSetter(nulls = SKIP)
private IpmiProtocolConfig ipmi;
@JsonDeserialize(using = ExtensionConfigDeserializer.class)
private IConfiguration ipmi;

@JsonSetter(nulls = SKIP)
private SshProtocolConfig ssh;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
import org.sentrysoftware.metricshub.agent.config.ResourceConfig;
import org.sentrysoftware.metricshub.agent.config.ResourceGroupConfig;
import org.sentrysoftware.metricshub.agent.config.protocols.AbstractProtocolConfig;
import org.sentrysoftware.metricshub.agent.config.protocols.IpmiProtocolConfig;
import org.sentrysoftware.metricshub.agent.config.protocols.OsCommandProtocolConfig;
import org.sentrysoftware.metricshub.agent.config.protocols.ProtocolsConfig;
import org.sentrysoftware.metricshub.agent.config.protocols.SshProtocolConfig;
Expand Down Expand Up @@ -112,7 +111,6 @@ public class ConfigHelper {
private static final String WMI_PROTOCOL = "WMI";
private static final String WBEM_PROTOCOL = "WBEM";
private static final String SSH_PROTOCOL = "SSH";
private static final String IPMI_PROTOCOL = "IPMI";
private static final String WIN_RM_PROTOCOL = "WinRM";
private static final String TIMEOUT_ERROR =
"Resource %s - Timeout value is invalid for protocol %s." +
Expand Down Expand Up @@ -943,9 +941,9 @@ private static void validateProtocols(@NonNull final String resourceKey, final R
snmpConfig.validateConfiguration(resourceKey);
}

final IpmiProtocolConfig ipmiConfig = protocolsConfig.getIpmi();
final IConfiguration ipmiConfig = protocolsConfig.getIpmi();
if (ipmiConfig != null) {
validateIpmiInfo(resourceKey, ipmiConfig.getUsername(), ipmiConfig.getTimeout());
ipmiConfig.validateConfiguration(resourceKey);
}

final SshProtocolConfig sshConfig = protocolsConfig.getSsh();
Expand Down Expand Up @@ -1014,29 +1012,6 @@ static void validateWinRmInfo(
);
}

/**
* Validate the given IPMI information (username and timeout)
*
* @param resourceKey Resource unique identifier
* @param username Name used to establish the connection with the host via the IPMI protocol
* @param timeout How long until the IPMI request times out
* @throws InvalidConfigurationException
*/
static void validateIpmiInfo(final String resourceKey, final String username, final Long timeout)
throws InvalidConfigurationException {
StringHelper.validateConfigurationAttribute(
username,
INVALID_STRING_CHECKER,
() -> String.format(USERNAME_ERROR, resourceKey, IPMI_PROTOCOL)
);

StringHelper.validateConfigurationAttribute(
timeout,
INVALID_TIMEOUT_CHECKER,
() -> String.format(TIMEOUT_ERROR, resourceKey, IPMI_PROTOCOL, timeout)
);
}

/**
* Validate the given SSH information (username, timeout)
*
Expand Down Expand Up @@ -1162,7 +1137,6 @@ static HostConfiguration buildHostConfiguration(
protocols.getWbem(),
protocols.getWmi(),
protocols.getOsCommand(),
protocols.getIpmi(),
protocols.getWinrm()
)
.filter(Objects::nonNull)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,21 @@
* ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
*/

import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import lombok.Data;
import org.sentrysoftware.metricshub.engine.common.helpers.ArrayHelper;
import org.sentrysoftware.metricshub.cli.service.CliExtensionManager;
import org.sentrysoftware.metricshub.engine.common.exception.InvalidConfigurationException;
import org.sentrysoftware.metricshub.engine.configuration.IConfiguration;
import org.sentrysoftware.metricshub.engine.configuration.IpmiConfiguration;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParameterException;
import picocli.CommandLine.Spec;

/**
* This class is used by MetricsHubCliService to configure Ipmi protocol when using the MetricsHub CLI.
* It create the engine's {@link IpmiConfiguration} object that is used to monitor a specific resource through IPMI.
* It create the engine's {@link IConfiguration} object that is used to monitor a specific resource through IPMI.
*/
@Data
public class IpmiConfigCli implements IProtocolConfigCli {
Expand Down Expand Up @@ -89,28 +92,31 @@ public class IpmiConfigCli implements IProtocolConfigCli {
defaultValue = "" + DEFAULT_TIMEOUT,
description = "Timeout in seconds for HTTP operations (default: ${DEFAULT-VALUE} s)"
)
private long timeout;
private String timeout;

/**
* This method creates an {@link IpmiConfiguration} for a given username and a given password
* This method creates an {@link IConfiguration} for a given username and a given password
*
* @param defaultUsername Username specified at the top level of the CLI (with the --username option)
* @param defaultPassword Password specified at the top level of the CLI (with the --password option)
* @return an {@link IpmiConfiguration} instance corresponding to the options specified by the user in the CLI
* @return an {@link IConfiguration} instance corresponding to the options specified by the user in the CLI
*/
@Override
public IConfiguration toProtocol(final String defaultUsername, final char[] defaultPassword) {
try {
return IpmiConfiguration
.builder()
.username(username == null ? defaultUsername : username)
.password(username == null ? defaultPassword : password)
.bmcKey(ArrayHelper.hexToByteArray(bmcKey))
.skipAuth(skipAuth)
.timeout(timeout)
.build();
} catch (Exception e) {
throw new ParameterException(spec.commandLine(), e.getMessage());
}
public IConfiguration toProtocol(final String defaultUsername, final char[] defaultPassword)
throws InvalidConfigurationException {
final ObjectNode configuration = JsonNodeFactory.instance.objectNode();
configuration.set("username", new TextNode(username == null ? defaultUsername : username));
configuration.set(
"password",
new TextNode(username == null ? String.valueOf(defaultPassword) : String.valueOf(password))
);
configuration.set("timeout", new TextNode(timeout));
configuration.set("skipAuth", BooleanNode.valueOf(skipAuth));
configuration.set("bmcKey", new TextNode(bmcKey));

return CliExtensionManager
.getExtensionManagerSingleton()
.buildConfigurationFromJsonNode("ipmi", configuration, value -> value)
.orElseThrow();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.sentrysoftware.metricshub.agent.extension;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.sentrysoftware.metricshub.engine.common.exception.InvalidConfigurationException;
import org.sentrysoftware.metricshub.engine.common.helpers.StringHelper;
import org.sentrysoftware.metricshub.engine.configuration.IConfiguration;

/**
* The IpmiConfiguration class represents the configuration for IPMI (Intelligent Platform Management Interface) connections
* in the MetricsHub engine.
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IpmiTestConfiguration implements IConfiguration {

@Builder.Default
private final Long timeout = 120L;

private String username;
private char[] password;
private String bmcKey;
private boolean skipAuth;

@Override
public String toString() {
String description = "IPMI";
if (username != null) {
description = description + " as " + username;
}
return description;
}

/**
* Validate the given IPMI information (username and timeout)
*
* @param resourceKey Resource unique identifier
* @throws InvalidConfigurationException
*/
@Override
public void validateConfiguration(String resourceKey) throws InvalidConfigurationException {
StringHelper.validateConfigurationAttribute(
username,
attr -> attr == null || attr == "",
() ->
String.format(
"Resource %s - Username value is invalid for protocol %s." +
" Timeout value returned: %s. This resource will not be monitored. Please verify the configured timeout value.",
resourceKey,
"HTTP",
timeout
)
);

StringHelper.validateConfigurationAttribute(
timeout,
attr -> attr == null || attr < 0L,
() ->
String.format(
"Resource %s - Timeout value is invalid for protocol %s." +
" Timeout value returned: %s. This resource will not be monitored. Please verify the configured timeout value.",
resourceKey,
"HTTP",
timeout
)
);
}
}
Loading