This is an automated email from the ASF dual-hosted git repository.
gongchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
The following commit(s) were added to refs/heads/master by this push:
new d3eff79a9 [feature] Support Redfish protocol to monitoring server
(#1867)
d3eff79a9 is described below
commit d3eff79a903f1686ac2b1f42a98dfadea04bba15
Author: Gao Jian <[email protected]>
AuthorDate: Sun Apr 28 08:47:53 2024 +0800
[feature] Support Redfish protocol to monitoring server (#1867)
Co-authored-by: tomsun28 <[email protected]>
---
.../collect/common/cache/RedfishConnect.java | 48 ++++
.../collector/collect/redfish/ConnectSession.java | 27 ++
.../collector/collect/redfish/RedfishClient.java | 112 ++++++++
.../collect/redfish/RedfishCollectImpl.java | 193 ++++++++++++++
.../collect/redfish/RedfishCollectionSchema.java | 37 +++
.../collect/redfish/RedfishConnectSession.java | 100 +++++++
.../collector/collect/redfish/Session.java | 23 ++
.../collector/dispatch/DispatchConstants.java | 4 +
...che.hertzbeat.collector.collect.AbstractCollect | 1 +
.../collect/redfish/RedfishCollectImplTest.java | 164 ++++++++++++
.../hertzbeat/common/entity/job/Metrics.java | 6 +-
.../entity/job/protocol/RedfishProtocol.java | 62 +++++
manager/src/main/resources/define/app-redfish.yml | 288 +++++++++++++++++++++
13 files changed, 1064 insertions(+), 1 deletion(-)
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/collect/common/cache/RedfishConnect.java
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/common/cache/RedfishConnect.java
new file mode 100644
index 000000000..199a8350e
--- /dev/null
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/common/cache/RedfishConnect.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.common.cache;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.hertzbeat.collector.collect.redfish.ConnectSession;
+
+/**
+ * redfish connect session
+ */
+@Slf4j
+public class RedfishConnect implements CacheCloseable{
+ private final ConnectSession reddishConnectSession;
+
+ public RedfishConnect(ConnectSession reddishConnectSession) {
+ this.reddishConnectSession = reddishConnectSession;
+ }
+
+ @Override
+ public void close() {
+ try {
+ if (reddishConnectSession != null) {
+ reddishConnectSession.close();
+ }
+ } catch (Exception e) {
+ log.error("[connection common cache] close redfish connect error:
{}", e.getMessage());
+ }
+ }
+
+ public ConnectSession getConnection() {
+ return reddishConnectSession;
+ }
+}
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/ConnectSession.java
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/ConnectSession.java
new file mode 100644
index 000000000..38b8bb14c
--- /dev/null
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/ConnectSession.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.redfish;
+
+/**
+ * redfish client interface
+ */
+public interface ConnectSession extends AutoCloseable {
+ boolean isOpen();
+
+ String getRedfishResource(String uri) throws Exception;
+}
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishClient.java
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishClient.java
new file mode 100644
index 000000000..b813b6653
--- /dev/null
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishClient.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.redfish;
+
+import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
+import org.apache.hertzbeat.common.constants.CollectorConstants;
+import org.apache.hertzbeat.common.entity.job.protocol.RedfishProtocol;
+import org.apache.hertzbeat.common.util.IpDomainUtil;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.methods.RequestBuilder;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.entity.StringEntity;
+
+/**
+ * redfish client impl
+ */
+public class RedfishClient {
+ private final String host;
+ private final Integer port;
+ private final String username;
+ private final String password;
+ private final Integer timeout;
+ public static final String REDFISH_SESSION_SERVICE =
"/redfish/v1/SessionService/Sessions";
+
+ protected RedfishClient(String host, int port, String username, String
password, Integer timeout) {
+ this.host = host;
+ this.port = port;
+ this.username = username;
+ this.password = password;
+ this.timeout = timeout;
+ }
+
+ public static RedfishClient create(RedfishProtocol redfishProtocol) {
+ return new RedfishClient(redfishProtocol.getHost(),
Integer.parseInt(redfishProtocol.getPort()),
+ redfishProtocol.getUsername(), redfishProtocol.getPassword(),
Integer.parseInt(redfishProtocol.getTimeout()));
+ }
+
+ public ConnectSession connect() throws Exception {
+ HttpHost host = new HttpHost(this.host, this.port);
+ HttpClientContext httpClientContext = new HttpClientContext();
+ httpClientContext.setTargetHost(host);
+ RequestBuilder requestBuilder = RequestBuilder.post();
+
+ String uri = REDFISH_SESSION_SERVICE;
+ if (IpDomainUtil.isHasSchema(this.host)) {
+ requestBuilder.setUri(this.host + ":" + this.port + uri);
+ } else {
+ String ipAddressType = IpDomainUtil.checkIpAddressType(this.host);
+ String baseUri = CollectorConstants.IPV6.equals(ipAddressType)
+ ? String.format("[%s]:%s", this.host, this.port + uri)
+ : String.format("%s:%s", this.host, this.port + uri);
+
+ requestBuilder.setUri(CollectorConstants.HTTP_HEADER + baseUri);
+ }
+
+ requestBuilder.addHeader(HttpHeaders.CONNECTION, "Keep-Alive");
+ requestBuilder.addHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+ requestBuilder.addHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows
NT 6.1; WOW64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76
Safari/537.36");
+ requestBuilder.addHeader(HttpHeaders.CONTENT_ENCODING, "UTF-8");
+
+ final String json = "{\"UserName\": \"" + this.username + "\",
\"Password\": \"" + this.password + "\"}";
+ StringEntity entity = new StringEntity(json, "UTF-8");
+ requestBuilder.setEntity(entity);
+
+ if (this.timeout > 0) {
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setConnectTimeout(this.timeout)
+ .setSocketTimeout(this.timeout)
+ .setRedirectsEnabled(true)
+ .build();
+ requestBuilder.setConfig(requestConfig);
+ }
+
+ HttpUriRequest request = requestBuilder.build();
+
+ Session session;
+ try (CloseableHttpResponse response =
CommonHttpClient.getHttpClient().execute(request, httpClientContext)) {
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_CREATED) {
+ throw new Exception("Http Status Code: " + statusCode);
+ }
+ String location = response.getFirstHeader("Location").getValue();
+ String auth = response.getFirstHeader("X-Auth-Token").getValue();
+ session = new Session(auth, location, this.host, this.port);
+ } catch (Exception e) {
+ throw new Exception("Redfish session create error: " +
e.getMessage());
+ } finally {
+ request.abort();
+ }
+ return new RedfishConnectSession(session);
+ }
+}
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectImpl.java
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectImpl.java
new file mode 100644
index 000000000..7ba22fede
--- /dev/null
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectImpl.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.redfish;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.hertzbeat.collector.collect.AbstractCollect;
+import org.apache.hertzbeat.collector.collect.common.cache.CacheIdentifier;
+import
org.apache.hertzbeat.collector.collect.common.cache.ConnectionCommonCache;
+import org.apache.hertzbeat.collector.collect.common.cache.RedfishConnect;
+import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
+import org.apache.hertzbeat.collector.util.JsonPathParser;
+import org.apache.hertzbeat.common.constants.CommonConstants;
+import org.apache.hertzbeat.common.entity.job.Metrics;
+import org.apache.hertzbeat.common.entity.job.protocol.RedfishProtocol;
+import org.apache.hertzbeat.common.entity.message.CollectRep;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * redfish collect impl
+ */
+@Slf4j
+public class RedfishCollectImpl extends AbstractCollect {
+
+ @Override
+ public void collect(CollectRep.MetricsData.Builder builder, long
monitorId, String app, Metrics metrics) {
+ try {
+ validateParams(metrics);
+ } catch (Exception e) {
+ builder.setCode(CollectRep.Code.FAIL);
+ builder.setMsg(e.getMessage());
+ return;
+ }
+ ConnectSession connectSession = null;
+ try {
+ connectSession = getRedfishConnectSession(metrics.getRedfish());
+ } catch (Exception e) {
+ log.error("Redfish session create error: {}", e.getMessage());
+ builder.setCode(CollectRep.Code.FAIL);
+ builder.setMsg(e.getMessage());
+ return;
+ }
+ List<String> resourcesUri = getResourcesUri(metrics, connectSession);
+ if (resourcesUri == null || resourcesUri.isEmpty()) {
+ builder.setCode(CollectRep.Code.FAIL);
+ builder.setMsg("Get redfish resources uri error");
+ return;
+ }
+ for (String uri : resourcesUri) {
+ String resp = null;
+ try {
+ resp = connectSession.getRedfishResource(uri);
+ } catch (Exception e) {
+ log.error("Get redfish {} detail resource error: {}", uri,
e.getMessage());
+ continue;
+ }
+ parseRedfishResource(builder, resp, metrics);
+ }
+ }
+
+ private ConnectSession getRedfishConnectSession(RedfishProtocol
redfishProtocol) throws Exception {
+ CacheIdentifier identifier = CacheIdentifier.builder()
+ .ip(redfishProtocol.getHost())
+ .port(redfishProtocol.getPort())
+ .password(redfishProtocol.getPassword())
+ .username(redfishProtocol.getUsername())
+ .build();
+ ConnectSession redfishConnectSession = null;
+ Optional<Object> cacheOption =
ConnectionCommonCache.getInstance().getCache(identifier, true);
+ if (cacheOption.isPresent()) {
+ RedfishConnect redfishConnect = (RedfishConnect) cacheOption.get();
+ redfishConnectSession = redfishConnect.getConnection();
+ if (redfishConnectSession == null ||
!redfishConnectSession.isOpen()) {
+ redfishConnectSession = null;
+ ConnectionCommonCache.getInstance().removeCache(identifier);
+ }
+ }
+ if (redfishConnectSession != null) {
+ return redfishConnectSession;
+ }
+ RedfishClient redfishClient = RedfishClient.create(redfishProtocol);
+ redfishConnectSession = redfishClient.connect();
+ ConnectionCommonCache.getInstance().addCache(identifier, new
RedfishConnect(redfishConnectSession));
+ return redfishConnectSession;
+ }
+
+ @Override
+ public String supportProtocol() {
+ return DispatchConstants.PROTOCOL_REDFISH;
+ }
+
+ private void validateParams(Metrics metrics) throws Exception {
+ if (metrics == null || metrics.getRedfish() == null) {
+ throw new Exception("Redfish collect must has redfish params");
+ }
+ RedfishProtocol redfishProtocol = metrics.getRedfish();
+ Assert.hasText(redfishProtocol.getHost(), "Redfish Protocol host is
required.");
+ Assert.hasText(redfishProtocol.getPort(), "Redfish Protocol port is
required.");
+ Assert.hasText(redfishProtocol.getUsername(), "Redfish Protocol
username is required.");
+ Assert.hasText(redfishProtocol.getPassword(), "Redfish Protocol
password is required.");
+ }
+
+
+ private List<String> getResourcesUri(Metrics metrics, ConnectSession
connectSession) {
+ String name = metrics.getName();
+ String collectionSchema = metrics.getRedfish().getSchema();
+ String schema = (collectionSchema != null) ? collectionSchema :
RedfishCollectionSchema.getSchema(name);
+ if (!StringUtils.hasText(schema)) {
+ return null;
+ }
+ String pattern = "\\{\\w+\\}";
+ Pattern r = Pattern.compile(pattern);
+ String[] fragment = r.split(schema);
+ List<String> res = new ArrayList<>();
+ for (String value : fragment) {
+ List<String> temp = new ArrayList<>();
+ if (res.isEmpty()) {
+ res.add(value);
+ } else {
+ res = res.stream().map(s -> s +
value).collect(Collectors.toList());
+ }
+
+ for (String s : res) {
+ List<String> t = getCollectionResource(s, connectSession);
+ temp.addAll(t);
+ }
+ res.clear();
+ res.addAll(temp);
+ }
+ return res;
+ }
+
+ private List<String> parseCollectionResource(String resp) {
+ if (!StringUtils.hasText(resp)) {
+ return Collections.emptyList();
+ }
+ String resourceIdPath = "$.Members[*].['@odata.id']";
+ List<Object> resourceIds =
JsonPathParser.parseContentWithJsonPath(resp, resourceIdPath);
+ List<String> res =
resourceIds.stream().filter(Objects::nonNull).map(String::valueOf).toList();
+ return res;
+ }
+
+ private List<String> getCollectionResource(String uri, ConnectSession
connectSession) {
+ String resp = null;
+ try {
+ resp = connectSession.getRedfishResource(uri);
+ } catch (Exception e) {
+ log.error("Get redfish {} collection resource error: {}", uri,
e.getMessage());
+ return Collections.emptyList();
+ }
+ return parseCollectionResource(resp);
+ }
+
+ private void parseRedfishResource(CollectRep.MetricsData.Builder builder,
String resp, Metrics metrics) {
+ if (!StringUtils.hasText(resp)) {
+ return;
+ }
+ List<String> aliasFields = metrics.getAliasFields();
+ CollectRep.ValueRow.Builder valueRowBuilder =
CollectRep.ValueRow.newBuilder();
+ for (String alias : aliasFields) {
+ List<Object> res = JsonPathParser.parseContentWithJsonPath(resp,
alias);
+ if (res != null && !res.isEmpty()) {
+ Object value = res.get(0);
+ valueRowBuilder.addColumns(value == null ?
CommonConstants.NULL_VALUE : String.valueOf(value));
+ } else {
+ valueRowBuilder.addColumns(CommonConstants.NULL_VALUE);
+ }
+ }
+ builder.addValues(valueRowBuilder.build());
+ }
+}
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectionSchema.java
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectionSchema.java
new file mode 100644
index 000000000..5d0740e87
--- /dev/null
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectionSchema.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.redfish;
+
+import java.util.Map;
+
+/**
+ * redfish collection schema
+ */
+public class RedfishCollectionSchema {
+
+ private static final Map<String, String> schemaMap = Map.of(
+ "Chassis", "/redfish/v1/Chassis",
+ "Fan", "/redfish/v1/Chassis/{ChassisId}/ThermalSubsystem/Fans",
+ "Battery",
"/redfish/v1/Chassis/{ChassisId}/PowerSubsystem/Batteries",
+ "PowerSupply",
"/redfish/v1/Chassis/{ChassisId}/PowerSubsystem/PowerSupplies");
+
+ public static String getSchema(String key) {
+ return schemaMap.get(key);
+ }
+
+}
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishConnectSession.java
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishConnectSession.java
new file mode 100644
index 000000000..4cec1c775
--- /dev/null
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/RedfishConnectSession.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.redfish;
+
+import java.nio.charset.StandardCharsets;
+import org.apache.hertzbeat.collector.collect.common.http.CommonHttpClient;
+import org.apache.hertzbeat.common.constants.CollectorConstants;
+import org.apache.hertzbeat.common.util.IpDomainUtil;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.util.EntityUtils;
+
+
+/**
+ * Redfish connect session
+ */
+public class RedfishConnectSession implements ConnectSession {
+
+ private final Session session;
+
+ private volatile boolean active = true;
+
+
+ public RedfishConnectSession(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return this.active;
+ }
+
+ @Override
+ public void close() throws Exception {
+ this.active = false;
+ String url = RedfishClient.REDFISH_SESSION_SERVICE +
session.location();
+ HttpDelete httpDelete = new HttpDelete(url);
+ httpDelete.setHeader("X-Auth-Token", session.token());
+ httpDelete.setHeader("Location", session.location());
+ try (CloseableHttpResponse response =
CommonHttpClient.getHttpClient().execute(httpDelete)) {
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ throw new Exception("Http State code: " + statusCode);
+ }
+ } catch (Exception e) {
+ throw new Exception("Redfish session close error:" +
e.getMessage());
+ } finally {
+ httpDelete.abort();
+ }
+ }
+
+ @Override
+ public String getRedfishResource(String uri) throws Exception {
+ if (uri.endsWith("/")) {
+ uri = uri.substring(0, uri.length() - 1);
+ }
+ String url = null;
+ if (IpDomainUtil.isHasSchema(this.session.host())) {
+ url = this.session.host() + ":" + this.session.port() + uri;
+ } else {
+ String ipAddressType =
IpDomainUtil.checkIpAddressType(this.session.host());
+ String baseUri = CollectorConstants.IPV6.equals(ipAddressType)
+ ? String.format("[%s]:%s", this.session.host(),
this.session.port() + uri)
+ : String.format("%s:%s", this.session.host(),
this.session.port() + uri);
+ url = CollectorConstants.HTTPS_HEADER + baseUri;
+ }
+ HttpGet httpGet = new HttpGet(url);
+ httpGet.setHeader("X-Auth-Token", session.token());
+ httpGet.setHeader("Location", session.location());
+ try (CloseableHttpResponse response =
CommonHttpClient.getHttpClient().execute(httpGet)) {
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ throw new Exception("Http State code: " + statusCode);
+ }
+ String resp = EntityUtils.toString(response.getEntity(),
StandardCharsets.UTF_8);
+ return resp;
+ } catch (Exception e) {
+ throw new Exception("Redfish session get resource error:" +
e.getMessage());
+ } finally {
+ httpGet.abort();
+ }
+ }
+}
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/Session.java
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/Session.java
new file mode 100644
index 000000000..25d5c2e34
--- /dev/null
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/collect/redfish/Session.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.redfish;
+
+/**
+ * Redfish session
+ */
+public record Session(String token, String location, String host, Integer
port) {}
diff --git
a/collector/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
b/collector/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
index 81357b569..b5beeeeb0 100644
---
a/collector/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
+++
b/collector/src/main/java/org/apache/hertzbeat/collector/dispatch/DispatchConstants.java
@@ -119,6 +119,10 @@ public interface DispatchConstants {
* protocol http_sd
*/
String PROTOCOL_HTTP_SD = "httpsd";
+ /**
+ * protocol redfish
+ */
+ String PROTOCOL_REDFISH = "redfish";
// Protocol type related - end
// 协议类型相关 - end //
diff --git
a/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect
b/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect
index b4a4b6129..b2d5149bf 100644
---
a/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect
+++
b/collector/src/main/resources/META-INF/services/org.apache.hertzbeat.collector.collect.AbstractCollect
@@ -21,3 +21,4 @@
org.apache.hertzbeat.collector.collect.memcached.MemcachedCollectImpl
org.apache.hertzbeat.collector.collect.nebulagraph.NebulaGraphCollectImpl
org.apache.hertzbeat.collector.collect.pop3.Pop3CollectImpl
org.apache.hertzbeat.collector.collect.httpsd.HttpsdImpl
+org.apache.hertzbeat.collector.collect.redfish.RedfishCollectImpl
diff --git
a/collector/src/test/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectImplTest.java
b/collector/src/test/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectImplTest.java
new file mode 100644
index 000000000..26ffe9f34
--- /dev/null
+++
b/collector/src/test/java/org/apache/hertzbeat/collector/collect/redfish/RedfishCollectImplTest.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.collector.collect.redfish;
+
+import org.apache.hertzbeat.common.entity.job.Metrics;
+import org.apache.hertzbeat.common.entity.job.protocol.RedfishProtocol;
+import org.apache.hertzbeat.common.entity.message.CollectRep;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@ExtendWith(MockitoExtension.class)
+public class RedfishCollectImplTest {
+ @Mock
+ private RedfishProtocol redfishProtocol;
+
+ @Mock
+ private ConnectSession redfishConnectSession;
+
+ @Mock
+ private RedfishClient redfishClient;
+
+ @InjectMocks
+ private RedfishCollectImpl redfishCollect;
+
+ @BeforeEach
+ void setUp() {
+ redfishProtocol = RedfishProtocol.builder()
+ .host("https://127.0.0.1")
+ .port("5000")
+ .username("Administrator")
+ .password("Password")
+ .timeout("5000")
+ .build();
+ }
+
+ @Test
+ void collect() {
+ CollectRep.MetricsData.Builder builder =
CollectRep.MetricsData.newBuilder();
+ List<String> aliasField = new ArrayList<>();
+ aliasField.add("$.Id");
+ Metrics metrics = new Metrics();
+ metrics.setRedfish(redfishProtocol);
+ metrics.setAliasFields(aliasField);
+ metrics.setName("Chassis");
+ RedfishClient.create(redfishProtocol);
+ redfishCollect.collect(builder, 1L, "test", metrics);
+ }
+
+ @Test
+ void mockCollect() throws Exception {
+ CollectRep.MetricsData.Builder builder =
CollectRep.MetricsData.newBuilder();
+ List<String> aliasField = new ArrayList<>();
+ aliasField.add("$.['@odata.id']");
+
redfishProtocol.setSchema("/redfish/v1/Chassis/{ChassisId}/PowerSubsystem/PowerSupplies");
+ Metrics metrics = new Metrics();
+ metrics.setRedfish(redfishProtocol);
+ metrics.setAliasFields(aliasField);
+ metrics.setName("PowerSupply");
+ String Chassis = "{\n" +
+ " \"@odata.type\":
\"#ChassisCollection.ChassisCollection\",\n" +
+ " \"Name\": \"Chassis Collection\",\n" +
+ " \"[email protected]\": 2,\n" +
+ " \"Members\": [\n" +
+ " {\n" +
+ " \"@odata.id\": \"/redfish/v1/Chassis/1U\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"@odata.id\": \"/redfish/v1/Chassis/2U\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+ String powerSupplies1U = "{\n" +
+ " \"@odata.type\":
\"#PowerSupplyCollection.PowerSupplyCollection\",\n" +
+ " \"Name\": \"Power Supply Collection\",\n" +
+ " \"[email protected]\": 2,\n" +
+ " \"Members\": [\n" +
+ " {\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay1\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay2\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+ String powerSupplies2U = "{\n" +
+ " \"@odata.type\":
\"#PowerSupplyCollection.PowerSupplyCollection\",\n" +
+ " \"Name\": \"Power Supply Collection\",\n" +
+ " \"[email protected]\": 2,\n" +
+ " \"Members\": [\n" +
+ " {\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay1\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay2\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+ String bay1U1 = "{\n" +
+ " \"@odata.type\": \"#PowerSupply.v1_5_3.PowerSupply\",\n" +
+ " \"Id\": \"Bay1\",\n" +
+ " \"Name\": \"Power Supply Bay 1\",\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay1\"\n" +
+ "}";
+ String bay2U1 = "{\n" +
+ " \"@odata.type\": \"#PowerSupply.v1_5_3.PowerSupply\",\n" +
+ " \"Id\": \"Bay2\",\n" +
+ " \"Name\": \"Power Supply Bay 2\",\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay2\"\n" +
+ "}";
+ String bay1U2 = "{\n" +
+ " \"@odata.type\": \"#PowerSupply.v1_5_3.PowerSupply\",\n" +
+ " \"Id\": \"Bay1\",\n" +
+ " \"Name\": \"Power Supply Bay 1\",\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay1\"\n" +
+ "}";
+ String bay2U2 = "{\n" +
+ " \"@odata.type\": \"#PowerSupply.v1_5_3.PowerSupply\",\n" +
+ " \"Id\": \"Bay2\",\n" +
+ " \"Name\": \"Power Supply Bay 2\",\n" +
+ " \"@odata.id\":
\"/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay2\"\n" +
+ "}";
+
Mockito.when(redfishConnectSession.getRedfishResource("/redfish/v1/Chassis/")).thenReturn(Chassis);
+
Mockito.when(redfishConnectSession.getRedfishResource("/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies")).thenReturn(powerSupplies1U);
+
Mockito.when(redfishConnectSession.getRedfishResource("/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies")).thenReturn(powerSupplies2U);
+
Mockito.when(redfishConnectSession.getRedfishResource("/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay1")).thenReturn(bay1U1);
+
Mockito.when(redfishConnectSession.getRedfishResource("/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay2")).thenReturn(bay2U1);
+
Mockito.when(redfishConnectSession.getRedfishResource("/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay1")).thenReturn(bay1U2);
+
Mockito.when(redfishConnectSession.getRedfishResource("/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay2")).thenReturn(bay2U2);
+ MockedStatic<RedfishClient> clientMockedStatic =
Mockito.mockStatic(RedfishClient.class);
+ clientMockedStatic.when(() ->
RedfishClient.create(redfishProtocol)).thenReturn(redfishClient);
+
Mockito.when(redfishClient.connect()).thenReturn(redfishConnectSession);
+ redfishCollect.collect(builder, 1L, "test", metrics);
+
assertEquals("/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay1",
builder.getValues(0).getColumns(0));
+
assertEquals("/redfish/v1/Chassis/1U/PowerSubsystem/PowerSupplies/Bay2",
builder.getValues(1).getColumns(0));
+
assertEquals("/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay1",
builder.getValues(2).getColumns(0));
+
assertEquals("/redfish/v1/Chassis/2U/PowerSubsystem/PowerSupplies/Bay2",
builder.getValues(3).getColumns(0));
+ }
+}
diff --git
a/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
b/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
index 1e517fd90..67349ea7b 100644
--- a/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
+++ b/common/src/main/java/org/apache/hertzbeat/common/entity/job/Metrics.java
@@ -43,6 +43,7 @@ import
org.apache.hertzbeat.common.entity.job.protocol.NtpProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.Pop3Protocol;
import org.apache.hertzbeat.common.entity.job.protocol.PrometheusProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.PushProtocol;
+import org.apache.hertzbeat.common.entity.job.protocol.RedfishProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.RedisProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.RocketmqProtocol;
import org.apache.hertzbeat.common.entity.job.protocol.SmtpProtocol;
@@ -205,7 +206,10 @@ public class Metrics {
* Monitoring configuration information using the public http_sd protocol
*/
private HttpsdProtocol httpsd;
-
+ /**
+ * Monitoring configuration information using the public redfish protocol
+ */
+ private RedfishProtocol redfish;
/**
* collector use - Temporarily store subTask metrics response data
*/
diff --git
a/common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/RedfishProtocol.java
b/common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/RedfishProtocol.java
new file mode 100644
index 000000000..b8042e12f
--- /dev/null
+++
b/common/src/main/java/org/apache/hertzbeat/common/entity/job/protocol/RedfishProtocol.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.common.entity.job.protocol;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Redfish Protocol
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class RedfishProtocol {
+ /**
+ * IP ADDRESS OR DOMAIN NAME OF THE PEER HOST
+ */
+ private String host;
+
+ /**
+ * Peer host port
+ */
+ private String port;
+
+ /**
+ * UserName
+ */
+ private String username;
+
+ /**
+ * Password
+ */
+ private String password;
+
+ /**
+ * TIME OUT PERIOD
+ */
+ private String timeout;
+
+ /**
+ * Redfish Resource Name and Corresponding Collection URI
+ */
+ private String schema;
+}
diff --git a/manager/src/main/resources/define/app-redfish.yml
b/manager/src/main/resources/define/app-redfish.yml
new file mode 100644
index 000000000..af3e4d3a7
--- /dev/null
+++ b/manager/src/main/resources/define/app-redfish.yml
@@ -0,0 +1,288 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# The monitoring type category:service-application service monitoring
db-database monitoring custom-custom monitoring os-operating system monitoring
+# 监控类型所属类别:service-应用服务 program-应用程序 db-数据库 custom-自定义 os-操作系统 bigdata-大数据
mid-中间件 webserver-web服务器 cache-缓存 cn-云原生 network-网络监控等等
+category: os
+# The monitoring type eg: linux windows tomcat mysql aws...
+# 监控类型 eg: linux windows tomcat mysql aws...
+app: redfish
+# The monitoring i18n name
+# 监控类型国际化名称
+name:
+ zh-CN: Redfish
+ en-US: Redfish
+# The description and help of this monitoring type
+# 监控类型的帮助描述信息
+help:
+ zh-CN: Hertzbeat 对支持 Redfish 服务的服务器进行测量监控。<br>您可以点击 “<i>新建 Redfish</i>”
并进行配置,或者选择“<i>更多操作</i>”,导入已有配置。
+ en-US: Hertzbeat monitoring servers supporting Redfish services. You could
click the "<i>New Redfish</i>" button and proceed with the configuration or
import an existing setup through the "<i>More Actions</i>" menu.
+ zh-TW: Hertzbeat 對支援 Redfish
服務的伺服器進行測量監控。<br>您可以點擊“<i>Redfish</i>”並進行配寘,或者選擇“<i>更多操作</i>”,導入已有配寘。
+helpLink:
+ zh-CN: https://hertzbeat.apache.org/zh-cn/docs/help/redfish
+ en-US: https://hertzbeat.apache.org/docs/help/redfish
+# 监控所需输入参数定义(根据定义渲染页面UI)
+# Input params define for monitoring(render web ui by the definition)
+params:
+ # field-param field key
+ # field-变量字段标识符
+ - field: host
+ # name-param field display i18n name
+ # name-参数字段显示名称
+ name:
+ zh-CN: 目标Host
+ en-US: Target Host
+ # type-param field type(most mapping the html input type)
+ # type-字段类型,样式(大部分映射input标签type属性)
+ type: host
+ # required-true or false
+ # required-是否是必输项 true-必填 false-可选
+ required: true
+ # field-param field key
+ # field-变量字段标识符
+ - field: port
+ # name-param field display i18n name
+ # name-参数字段显示名称
+ name:
+ zh-CN: 端口
+ en-US: Port
+ # type-param field type(most mapping the html input type)
+ # type-字段类型,样式(大部分映射input标签type属性)
+ type: number
+ # when type is number, range is required
+ # 当type为number时,用range表示范围
+ range: '[0,65535]'
+ # required-true or false
+ # required-是否是必输项 true-必填 false-可选
+ required: true
+ # default value
+ # 默认值
+ defaultValue: 443
+ # field-param field key
+ # field-变量字段标识符
+ - field: timeout
+ # name-param field display i18n name
+ # name-参数字段显示名称
+ name:
+ zh-CN: 查询超时时间
+ en-US: Query Timeout
+ # type-param field type(most mapping the html input type)
+ # type-字段类型,样式(大部分映射input标签type属性)
+ type: number
+ # required-true or false
+ # required-是否是必输项 true-必填 false-可选
+ required: false
+ # hide param-true or false
+ # 是否隐藏字段 true or false
+ hide: true
+ # default value
+ # 默认值
+ defaultValue: 6000
+ # field-param field key
+ # field-变量字段标识符
+ - field: username
+ # name-param field display i18n name
+ # name-参数字段显示名称
+ name:
+ zh-CN: 用户名
+ en-US: Username
+ # type-param field type(most mapping the html input type)
+ # type-字段类型,样式(大部分映射input标签type属性)
+ type: text
+ # when type is text, use limit to limit string length
+ # 当type为text时,用limit表示字符串限制大小
+ limit: 20
+ # required-true or false
+ # required-是否是必输项 true-必填 false-可选
+ required: false
+ # field-param field key
+ # field-变量字段标识符
+ - field: password
+ # name-param field display i18n name
+ # name-参数字段显示名称
+ name:
+ zh-CN: 密码
+ en-US: Password
+ # type-param field type(most mapping the html input tag)
+ # type-字段类型,样式(大部分映射input标签type属性)
+ type: password
+ # required-true or false
+ # required-是否是必输项 true-必填 false-可选
+ required: false
+# collect metrics config list
+# 采集指标配置列表
+metrics:
+ # metrics - cpu
+ # 监控指标 - cpu
+ - name: Chassis
+ # metrics scheduling priority(0->127)->(high->low), metrics with the same
priority will be scheduled in parallel
+ # priority 0's metrics is availability metrics, it will be scheduled
first, only availability metrics collect success will the scheduling continue
+ # 指标采集调度优先级(0->127)->(优先级高->低) 优先级低的指标会等优先级高的指标采集完成后才会被调度, 相同优先级的指标会并行调度采集
+ # 优先级为0的指标为可用性指标,即它会被首先调度,采集成功才会继续调度其它指标,采集失败则中断调度
+ priority: 0
+ # collect metrics content
+ # 具体监控指标列表
+ fields:
+ # field-metric name, type-metric type(0-number,1-string), unit-metric
unit('%','ms','MB'), label-whether it is a metrics label field
+ # field-指标名称, type-指标类型(0-number数字,1-string字符串),
unit-指标单位('%','ms','MB'), label-是否是指标标签字段
+ - field: id
+ type: 1
+ i18n:
+ zh-CN: 机箱唯一标识符
+ en-US: Chassis Unique Identifier
+ - field: name
+ type: 1
+ i18n:
+ zh-CN: 机箱名称
+ en-US: Chassis Name
+ - field: type
+ type: 1
+ i18n:
+ zh-CN: 机箱类型
+ en-US: Chasis Type
+ - field: state
+ type: 1
+ i18n:
+ zh-CN: 机箱状态
+ en-US: Chasis State
+ - field: health
+ type: 1
+ i18n:
+ zh-CN: 机箱健康状态
+ en-US: Chasis Health
+ # (optional)metrics field alias name, it is used as an alias field to map
and convert the collected data and metrics field
+ # (可选)监控指标别名, 做为中间字段与采集数据字段和指标字段映射转换
+ aliasFields:
+ - $.['@odata.id']
+ - $.Name
+ - $.ChassisType
+ - $.Status.State
+ - $.Status.Health
+ # the protocol used for monitoring, eg: sql, ssh, http, telnet, wmi, snmp,
sdk
+ protocol: redfish
+ # the config content when protocol is redfish
+ redfish:
+ # redfish host: ipv4 ipv6 domain
+ host: ^_^host^_^
+ # redfish port
+ port: ^_^port^_^
+ # redfish username
+ username: ^_^username^_^
+ # redfish password
+ password: ^_^password^_^
+ # timeout unit:ms
+ timeout: ^_^timeout^_^
+
+ - name: Battery
+ priority: 1
+ fields:
+ - field: id
+ type: 1
+ i18n:
+ zh-CN: 电池唯一标识符
+ en-US: Battery Unique Identifier
+ - field: name
+ type: 1
+ i18n:
+ zh-CN: 电池名称
+ en-US: Battery Name
+ - field: state
+ type: 1
+ i18n:
+ zh-CN: 电池状态
+ en-US: Battery State
+ - field: health
+ type: 1
+ i18n:
+ zh-CN: 电池健康状态
+ en-US: Battery Health
+ - field: charge_status
+ type: 1
+ i18n:
+ zh-CN: 电池充电状态
+ en-US: Battery Charge Status
+ aliasFields:
+ - $.['@odata.id']
+ - $.Name
+ - $.Status.State
+ - $.Status.Health
+ - $.ChargeState
+ protocol: redfish
+ redfish:
+ # redfish host: ipv4 ipv6 domain
+ host: ^_^host^_^
+ # redfish port
+ port: ^_^port^_^
+ # redfish username
+ username: ^_^username^_^
+ # redfish password
+ password: ^_^password^_^
+ # timeout unit:ms
+ timeout: ^_^timeout^_^
+
+ - name: Fan
+ priority: 2
+ fields:
+ - field: id
+ type: 1
+ i18n:
+ zh-CN: 风扇唯一标识符
+ en-US: Fan Unique Identifier
+ - field: name
+ type: 1
+ i18n:
+ zh-CN: 风扇名称
+ en-US: Fan Name
+ - field: state
+ type: 1
+ i18n:
+ zh-CN: 风扇状态
+ en-US: Fan State
+ - field: health
+ type: 1
+ i18n:
+ zh-CN: 风扇健康状态
+ en-US: Fan Health
+ - field: temperature
+ type: 0
+ i18n:
+ zh-CN: 传感器温度
+ en-US: Sensor Temperature
+ - field: speed
+ type: 0
+ i18n:
+ zh-CN: 风扇转速
+ en-US: Fan Speed
+ aliasFields:
+ - $.['@odata.id']
+ - $.Name
+ - $.Status.State
+ - $.Status.Health
+ - $.SpeedPercent.Reading
+ - $.SpeedPercent.SpeedRPM
+ protocol: redfish
+ redfish:
+ # redfish host: ipv4 ipv6 domain
+ host: ^_^host^_^
+ # redfish port
+ port: ^_^port^_^
+ # redfish username
+ username: ^_^username^_^
+ # redfish password
+ password: ^_^password^_^
+ # timeout unit:ms
+ timeout: ^_^timeout^_^
+ # redfish fan collection schema
+ schema: /redfish/v1/Chassis/{ChassisId}/ThermalSubsystem/Fans
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]