Skip to content

Commit

Permalink
Merge pull request #156 from sentrysoftware/114-develop-ipmi-extensio…
Browse files Browse the repository at this point in the history
…n-from-epic

Issue #114: Develop IPMI Extension
  • Loading branch information
NassimBtk committed Apr 23, 2024
2 parents 964e411 + 22ffaa7 commit 4ac179f
Show file tree
Hide file tree
Showing 32 changed files with 1,560 additions and 755 deletions.
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

0 comments on commit 4ac179f

Please sign in to comment.