From 7ddb8581354b5be6c0e36a226124e72758581e3c Mon Sep 17 00:00:00 2001 From: Drew Walters Date: Wed, 1 Apr 2020 19:56:19 +0000 Subject: [PATCH] Add baremetal host poweron command This change introduces a command to power on baremetal hosts. Closes: #5 Change-Id: Ie76cd7c044cc44629648ef0b02bb7e492ccccdcf Signed-off-by: Drew Walters --- cmd/baremetal/baremetal.go | 3 + cmd/baremetal/baremetal_test.go | 5 ++ cmd/baremetal/poweron.go | 56 +++++++++++++++++++ .../baremetal-poweron-with-help.golden | 8 +++ .../baremetal-with-help.golden | 1 + pkg/remote/management.go | 2 +- pkg/remote/redfish/client.go | 10 ++++ testutil/redfishutils/mock_client.go | 13 +++++ 8 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 cmd/baremetal/poweron.go create mode 100644 cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-poweron-with-help.golden diff --git a/cmd/baremetal/baremetal.go b/cmd/baremetal/baremetal.go index a6f2117fc..8551850e0 100644 --- a/cmd/baremetal/baremetal.go +++ b/cmd/baremetal/baremetal.go @@ -38,6 +38,9 @@ func NewBaremetalCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Co powerOffCmd := NewPowerOffCommand(rootSettings) cmd.AddCommand(powerOffCmd) + powerOnCmd := NewPowerOnCommand(rootSettings) + cmd.AddCommand(powerOnCmd) + powerStatusCmd := NewPowerStatusCommand(rootSettings) cmd.AddCommand(powerStatusCmd) diff --git a/cmd/baremetal/baremetal_test.go b/cmd/baremetal/baremetal_test.go index 6b03dd1da..6c017c114 100644 --- a/cmd/baremetal/baremetal_test.go +++ b/cmd/baremetal/baremetal_test.go @@ -38,6 +38,11 @@ func TestBaremetal(t *testing.T) { CmdLine: "-h", Cmd: baremetal.NewPowerOffCommand(nil), }, + { + Name: "baremetal-poweron-with-help", + CmdLine: "-h", + Cmd: baremetal.NewPowerOnCommand(nil), + }, { Name: "baremetal-powerstatus-with-help", CmdLine: "-h", diff --git a/cmd/baremetal/poweron.go b/cmd/baremetal/poweron.go new file mode 100644 index 000000000..7a90b3aff --- /dev/null +++ b/cmd/baremetal/poweron.go @@ -0,0 +1,56 @@ +/* +Licensed 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 + + https://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 baremetal + +import ( + "fmt" + + "github.com/spf13/cobra" + + "opendev.org/airship/airshipctl/pkg/config" + "opendev.org/airship/airshipctl/pkg/environment" + "opendev.org/airship/airshipctl/pkg/remote" +) + +// NewPowerOnCommand provides a command with the capability to power on baremetal hosts. +func NewPowerOnCommand(rootSettings *environment.AirshipCTLSettings) *cobra.Command { + var phase string + cmd := &cobra.Command{ + Use: "poweron BAREMETAL_HOST_DOC_NAME", + Short: "Power on a host", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + m, err := remote.NewManager(rootSettings, phase, remote.ByName(args[0])) + if err != nil { + return err + } + + for _, host := range m.Hosts { + if err := host.SystemPowerOn(host.Context); err != nil { + return err + } + + fmt.Fprintf(cmd.OutOrStdout(), "Powered on remote host %s\n", args[0]) + } + + return nil + }, + } + + flags := cmd.Flags() + flags.StringVar(&phase, flagPhase, config.BootstrapPhase, flagPhaseDescription) + + return cmd +} diff --git a/cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-poweron-with-help.golden b/cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-poweron-with-help.golden new file mode 100644 index 000000000..3d7ab695d --- /dev/null +++ b/cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-poweron-with-help.golden @@ -0,0 +1,8 @@ +Power on a host + +Usage: + poweron BAREMETAL_HOST_DOC_NAME [flags] + +Flags: + -h, --help help for poweron + --phase string airshipctl phase that contains the desired baremetal host document(s) (default "bootstrap") diff --git a/cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-with-help.golden b/cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-with-help.golden index 7d2281fd2..57673503d 100644 --- a/cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-with-help.golden +++ b/cmd/baremetal/testdata/TestBaremetalGoldenOutput/baremetal-with-help.golden @@ -7,6 +7,7 @@ Available Commands: help Help about any command isogen Generate baremetal host ISO image poweroff Shutdown a baremetal host + poweron Power on a host powerstatus Retrieve the power status of a baremetal host reboot Reboot a host remotedirect Bootstrap the ephemeral host diff --git a/pkg/remote/management.go b/pkg/remote/management.go index 0cd88702d..787bdf783 100644 --- a/pkg/remote/management.go +++ b/pkg/remote/management.go @@ -28,8 +28,8 @@ import ( // functions within client are used by power management commands and remote direct functionality. type Client interface { RebootSystem(context.Context) error - SystemPowerOff(context.Context) error + SystemPowerOn(context.Context) error // TODO(drewwalters96): Should this be a string forever? We may want to define our own custom type, as the // string format will be client dependent when we add new clients. diff --git a/pkg/remote/redfish/client.go b/pkg/remote/redfish/client.go index 8efb69c76..b79b8be87 100644 --- a/pkg/remote/redfish/client.go +++ b/pkg/remote/redfish/client.go @@ -200,6 +200,16 @@ func (c *Client) SystemPowerOff(ctx context.Context) error { return ScreenRedfishError(httpResp, err) } +// SystemPowerOn powers on a host. +func (c *Client) SystemPowerOn(ctx context.Context) error { + resetReq := redfishClient.ResetRequestBody{} + resetReq.ResetType = redfishClient.RESETTYPE_ON + + _, httpResp, err := c.RedfishAPI.ResetSystem(ctx, c.nodeID, resetReq) + + return ScreenRedfishError(httpResp, err) +} + // SystemPowerStatus retrieves the power status of a host as a human-readable string. func (c *Client) SystemPowerStatus(ctx context.Context) (string, error) { computerSystem, httpResp, err := c.RedfishAPI.GetSystem(ctx, c.nodeID) diff --git a/testutil/redfishutils/mock_client.go b/testutil/redfishutils/mock_client.go index c62f66949..544b9edaa 100644 --- a/testutil/redfishutils/mock_client.go +++ b/testutil/redfishutils/mock_client.go @@ -92,6 +92,19 @@ func (m *MockClient) SystemPowerOff(ctx context.Context) error { return args.Error(0) } +// SystemPowerOn provides a stubbed method that can be mocked to test functions that use the +// Redfish client without making any Redfish API calls or requiring the appropriate Redfish client settings. +// +// Example usage: +// client := redfishutils.NewClient() +// client.On("SystemPowerOn").Return() +// +// err := client.SystemPowerOn() +func (m *MockClient) SystemPowerOn(ctx context.Context) error { + args := m.Called(ctx) + return args.Error(0) +} + // SystemPowerStatus provides a stubbed method that can be mocked to test functions that use the // Redfish client without making any Redfish API calls or requiring the appropriate Redfish client settings. //