Skip to content

Commit ba6e2ac

Browse files
plugins: Redfish Client & Redfish OOBM Driver (#4175)
This PR adds support for the OOBM Redfish protocol, implementing a Java client to send HTTP requests to Redfish supported systems. Implementation overview: - Redfish Java client: a Java Client for Redfish that makes Redfish actions available to the HA workflow via an OOB driver. - OOB Redfish driver: a new Out-of-band driver was created for Redfish, allowing to integrate the Redfish Client with the CloudStack Out-of-band management implementation. Fixes: #3624
1 parent 36ef850 commit ba6e2ac

File tree

14 files changed

+886
-6
lines changed

14 files changed

+886
-6
lines changed

api/src/main/java/org/apache/cloudstack/outofbandmanagement/OutOfBandManagement.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,23 @@ enum Option {
6767
PASSWORD
6868
}
6969

70+
/**
71+
* <ul>
72+
* <li> <b>on:</b> Power up chassis.
73+
* <li> <b>off:</b> Power down chassis into soft off (S4/S5 state). WARNING: This command does not initiate a clean shutdown of the operating system prior to powering down the system.
74+
* <li> <b>cycle:</b> Provides a power off interval of at least 1 second. No action should occur if chassis power is in S4/S5 state, but it is recommended to check power state first and only issue a power cycle command if the system power is on or in lower sleep state than S4/S5.
75+
* <li> <b>reset:</b> This command will perform a hard reset.
76+
* <li> <b>soft:</b> Initiate a soft-shutdown of OS via ACPI. This can be done in a number of ways, commonly by simulating an overtemperture or by simulating a power button press. It is necessary for there to be Operating System support for ACPI and some sort of daemon watching for events for this soft power to work.
77+
* <li> <b>status:</b> Show current chassis power status.
78+
* </ul>
79+
*/
7080
enum PowerOperation {
7181
ON,
7282
OFF,
7383
CYCLE,
7484
RESET,
7585
SOFT,
76-
STATUS,
86+
STATUS
7787
}
7888

7989
enum PowerState {

client/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@
303303
<artifactId>cloud-plugin-outofbandmanagement-driver-nested-cloudstack</artifactId>
304304
<version>${project.version}</version>
305305
</dependency>
306+
<dependency>
307+
<groupId>org.apache.cloudstack</groupId>
308+
<artifactId>cloud-plugin-outofbandmanagement-driver-redfish</artifactId>
309+
<version>${project.version}</version>
310+
</dependency>
306311
<dependency>
307312
<groupId>org.apache.cloudstack</groupId>
308313
<artifactId>cloud-mom-rabbitmq</artifactId>

engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDao.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919

2020
import com.cloud.utils.db.GenericDao;
2121
import com.cloud.utils.fsm.StateDao;
22+
2223
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
2324
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagementVO;
2425

2526
import java.util.List;
2627

27-
public interface OutOfBandManagementDao extends GenericDao<OutOfBandManagementVO, Long>, StateDao<OutOfBandManagement.PowerState, OutOfBandManagement.PowerState.Event, OutOfBandManagement> {
28+
public interface OutOfBandManagementDao extends GenericDao<OutOfBandManagementVO, Long>,
29+
StateDao<OutOfBandManagement.PowerState, OutOfBandManagement.PowerState.Event, OutOfBandManagement> {
2830
OutOfBandManagement findByHost(long hostId);
31+
OutOfBandManagementVO findByHostAddress(String address);
2932
List<OutOfBandManagementVO> findAllByManagementServer(long serverId);
3033
void expireServerOwnership(long serverId);
3134
}

engine/schema/src/main/java/org/apache/cloudstack/outofbandmanagement/dao/OutOfBandManagementDaoImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ public OutOfBandManagement findByHost(long hostId) {
8686
return findOneBy(sc);
8787
}
8888

89+
@Override
90+
public OutOfBandManagementVO findByHostAddress(String address) {
91+
SearchCriteria<OutOfBandManagementVO> sc = HostSearch.create("address", address);
92+
return findOneBy(sc);
93+
}
94+
8995
@Override
9096
public List<OutOfBandManagementVO> findAllByManagementServer(long serverId) {
9197
SearchCriteria<OutOfBandManagementVO> sc = OutOfBandManagementOwnerSearch.create();
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
21+
<modelVersion>4.0.0</modelVersion>
22+
<artifactId>cloud-plugin-outofbandmanagement-driver-redfish</artifactId>
23+
<name>Apache CloudStack Plugin - Power Management Driver Redfish</name>
24+
<parent>
25+
<groupId>org.apache.cloudstack</groupId>
26+
<artifactId>cloudstack-plugins</artifactId>
27+
<version>4.15.0.0-SNAPSHOT</version>
28+
<relativePath>../../pom.xml</relativePath>
29+
</parent>
30+
<dependencies>
31+
<dependency>
32+
<groupId>org.apache.cloudstack</groupId>
33+
<artifactId>cloud-utils</artifactId>
34+
<version>${project.version}</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.apache.cloudstack</groupId>
38+
<artifactId>cloud-api</artifactId>
39+
<version>${project.version}</version>
40+
</dependency>
41+
</dependencies>
42+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
package org.apache.cloudstack.outofbandmanagement.driver.redfish;
20+
21+
import javax.inject.Inject;
22+
23+
import org.apache.cloudstack.framework.config.ConfigKey;
24+
import org.apache.cloudstack.framework.config.Configurable;
25+
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
26+
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagementDriver;
27+
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagementVO;
28+
import org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDao;
29+
import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverChangePasswordCommand;
30+
import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverCommand;
31+
import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverPowerCommand;
32+
import org.apache.cloudstack.outofbandmanagement.driver.OutOfBandManagementDriverResponse;
33+
import org.apache.cloudstack.utils.redfish.RedfishClient;
34+
import org.apache.cloudstack.utils.redfish.RedfishClient.RedfishResetCmd;
35+
import org.apache.commons.httpclient.HttpStatus;
36+
37+
import com.cloud.utils.component.AdapterBase;
38+
import com.cloud.utils.exception.CloudRuntimeException;
39+
import com.google.common.collect.ImmutableMap;
40+
41+
public class RedfishOutOfBandManagementDriver extends AdapterBase implements OutOfBandManagementDriver, Configurable {
42+
43+
@Inject
44+
private OutOfBandManagementDao outOfBandManagementDao;
45+
private RedfishWrapper redfishWrapper = new RedfishWrapper();
46+
47+
public static final ConfigKey<Boolean> IGNORE_SSL_CERTIFICATE = new ConfigKey<Boolean>("Advanced", Boolean.class, "redfish.ignore.ssl", "false",
48+
"Default value is false, ensuring that the client requests validate the certificate when using SSL. If set to true the redfish client will ignore SSL certificate validation when sending requests to a Redfish server.",
49+
true, ConfigKey.Scope.Global);
50+
51+
public static final ConfigKey<Boolean> USE_HTTPS = new ConfigKey<Boolean>("Advanced", Boolean.class, "redfish.use.https", "true",
52+
"Use HTTPS/SSL for all connections.", true, ConfigKey.Scope.Global);
53+
54+
private static final String HTTP_STATUS_OK = String.valueOf(HttpStatus.SC_OK);
55+
56+
@Override
57+
public OutOfBandManagementDriverResponse execute(OutOfBandManagementDriverCommand cmd) {
58+
OutOfBandManagementDriverResponse response = new OutOfBandManagementDriverResponse(null, "Unsupported Command", false);
59+
if (cmd instanceof OutOfBandManagementDriverPowerCommand) {
60+
response = execute((OutOfBandManagementDriverPowerCommand)cmd);
61+
} else if (cmd instanceof OutOfBandManagementDriverChangePasswordCommand) {
62+
response = execute((OutOfBandManagementDriverChangePasswordCommand)cmd);
63+
} else {
64+
throw new CloudRuntimeException(String.format("Operation [%s] not supported by the Redfish out-of-band management driver", cmd.getClass().getSimpleName()));
65+
}
66+
return response;
67+
}
68+
69+
/**
70+
* Sends a HTTPS request to execute the given power command ({@link OutOfBandManagementDriverPowerCommand})
71+
*/
72+
private OutOfBandManagementDriverResponse execute(final OutOfBandManagementDriverPowerCommand cmd) {
73+
ImmutableMap<OutOfBandManagement.Option, String> outOfBandOptions = cmd.getOptions();
74+
String username = outOfBandOptions.get(OutOfBandManagement.Option.USERNAME);
75+
String password = outOfBandOptions.get(OutOfBandManagement.Option.PASSWORD);
76+
String hostAddress = outOfBandOptions.get(OutOfBandManagement.Option.ADDRESS);
77+
RedfishClient redfishClient = new RedfishClient(username, password, USE_HTTPS.value(), IGNORE_SSL_CERTIFICATE.value());
78+
79+
RedfishClient.RedfishPowerState powerState = null;
80+
if (cmd.getPowerOperation() == OutOfBandManagement.PowerOperation.STATUS) {
81+
powerState = redfishClient.getSystemPowerState(hostAddress);
82+
} else {
83+
RedfishResetCmd redfishCmd = redfishWrapper.parsePowerCommand(cmd.getPowerOperation());
84+
redfishClient.executeComputerSystemReset(hostAddress, redfishCmd);
85+
}
86+
87+
OutOfBandManagementDriverResponse response = new OutOfBandManagementDriverResponse(HTTP_STATUS_OK, null, true);
88+
if (powerState != null) {
89+
OutOfBandManagement.PowerState oobPowerState = redfishWrapper.parseRedfishPowerStateToOutOfBand(powerState);
90+
response.setPowerState(oobPowerState);
91+
}
92+
return response;
93+
}
94+
95+
/**
96+
* Executes the password change command (OutOfBandManagementDriverChangePasswordCommand)
97+
*/
98+
private OutOfBandManagementDriverResponse execute(final OutOfBandManagementDriverChangePasswordCommand cmd) {
99+
cmd.getNewPassword();
100+
String hostAddress = cmd.getOptions().get(OutOfBandManagement.Option.ADDRESS);
101+
OutOfBandManagementVO outOfBandManagement = outOfBandManagementDao.findByHostAddress(hostAddress);
102+
outOfBandManagement.setPassword(cmd.getNewPassword());
103+
outOfBandManagementDao.update(outOfBandManagement.getId(), outOfBandManagement);
104+
105+
OutOfBandManagementDriverResponse response = new OutOfBandManagementDriverResponse(HTTP_STATUS_OK, null, true);
106+
107+
return response;
108+
}
109+
110+
@Override
111+
public String getConfigComponentName() {
112+
return RedfishOutOfBandManagementDriver.class.getSimpleName();
113+
}
114+
115+
@Override
116+
public ConfigKey<?>[] getConfigKeys() {
117+
return new ConfigKey<?>[] {IGNORE_SSL_CERTIFICATE, USE_HTTPS};
118+
}
119+
120+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
package org.apache.cloudstack.outofbandmanagement.driver.redfish;
20+
21+
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
22+
import org.apache.cloudstack.utils.redfish.RedfishClient;
23+
24+
public class RedfishWrapper {
25+
26+
public RedfishClient.RedfishResetCmd parsePowerCommand(OutOfBandManagement.PowerOperation operation) {
27+
if (operation == null) {
28+
throw new IllegalStateException("Invalid power operation requested");
29+
}
30+
switch (operation) {
31+
case ON:
32+
return RedfishClient.RedfishResetCmd.On;
33+
case OFF:
34+
return RedfishClient.RedfishResetCmd.GracefulShutdown;
35+
case CYCLE:
36+
return RedfishClient.RedfishResetCmd.PowerCycle;
37+
case RESET:
38+
return RedfishClient.RedfishResetCmd.ForceRestart;
39+
case SOFT:
40+
return RedfishClient.RedfishResetCmd.GracefulShutdown;
41+
case STATUS:
42+
throw new IllegalStateException(String.format("%s is not a valid Redfish Reset command [%s]", operation));
43+
default:
44+
throw new IllegalStateException(String.format("Redfish does not support operation [%s]", operation));
45+
}
46+
}
47+
48+
public OutOfBandManagement.PowerState parseRedfishPowerStateToOutOfBand(RedfishClient.RedfishPowerState redfishPowerState) {
49+
if (redfishPowerState == null) {
50+
throw new IllegalStateException("Invalid power state [null]");
51+
}
52+
53+
switch (redfishPowerState) {
54+
case On:
55+
return OutOfBandManagement.PowerState.On;
56+
case Off:
57+
return OutOfBandManagement.PowerState.Off;
58+
case PoweringOn:
59+
return OutOfBandManagement.PowerState.On;
60+
case PoweringOff:
61+
return OutOfBandManagement.PowerState.Off;
62+
default:
63+
return OutOfBandManagement.PowerState.Unknown;
64+
}
65+
}
66+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
name=redfish
18+
parent=outofbandmanagement
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
<beans xmlns="http://www.springframework.org/schema/beans"
20+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21+
xmlns:context="http://www.springframework.org/schema/context"
22+
xmlns:aop="http://www.springframework.org/schema/aop"
23+
xsi:schemaLocation="http://www.springframework.org/schema/beans
24+
http://www.springframework.org/schema/beans/spring-beans.xsd
25+
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
26+
http://www.springframework.org/schema/context
27+
http://www.springframework.org/schema/context/spring-context.xsd"
28+
>
29+
30+
<bean id="redfishOutOfBandManagementDriver" class="org.apache.cloudstack.outofbandmanagement.driver.redfish.RedfishOutOfBandManagementDriver">
31+
<property name="name" value="REDFISH" />
32+
</bean>
33+
</beans>

plugins/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
specific language governing permissions and limitations
1717
under the License.
1818
-->
19-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2120
<modelVersion>4.0.0</modelVersion>
2221
<artifactId>cloudstack-plugins</artifactId>
2322
<name>Apache CloudStack Plugin POM</name>
@@ -109,6 +108,7 @@
109108

110109
<module>outofbandmanagement-drivers/ipmitool</module>
111110
<module>outofbandmanagement-drivers/nested-cloudstack</module>
111+
<module>outofbandmanagement-drivers/redfish</module>
112112

113113
<module>storage/image/default</module>
114114
<module>storage/image/s3</module>
@@ -129,7 +129,7 @@
129129
<module>user-authenticators/plain-text</module>
130130
<module>user-authenticators/saml2</module>
131131
<module>user-authenticators/sha256salted</module>
132-
</modules>
132+
</modules>
133133
<dependencies>
134134
<dependency>
135135
<groupId>org.apache.cloudstack</groupId>
@@ -219,4 +219,4 @@
219219
</modules>
220220
</profile>
221221
</profiles>
222-
</project>
222+
</project>

0 commit comments

Comments
 (0)