Merge "Add strong typing for baremetal power statuses"

This commit is contained in:
Zuul 2020-05-01 18:28:11 +00:00 committed by Gerrit Code Review
commit 8387ba7aa5
5 changed files with 128 additions and 13 deletions

View File

@ -22,6 +22,7 @@ import (
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/environment" "opendev.org/airship/airshipctl/pkg/environment"
"opendev.org/airship/airshipctl/pkg/log" "opendev.org/airship/airshipctl/pkg/log"
"opendev.org/airship/airshipctl/pkg/remote/power"
"opendev.org/airship/airshipctl/pkg/remote/redfish" "opendev.org/airship/airshipctl/pkg/remote/redfish"
redfishdell "opendev.org/airship/airshipctl/pkg/remote/redfish/vendors/dell" redfishdell "opendev.org/airship/airshipctl/pkg/remote/redfish/vendors/dell"
) )
@ -30,17 +31,12 @@ import (
// functions within client are used by power management commands and remote direct functionality. // functions within client are used by power management commands and remote direct functionality.
type Client interface { type Client interface {
EjectVirtualMedia(context.Context) error EjectVirtualMedia(context.Context) error
NodeID() string
RebootSystem(context.Context) error RebootSystem(context.Context) error
SetBootSourceByType(context.Context) error
SystemPowerOff(context.Context) error SystemPowerOff(context.Context) error
SystemPowerOn(context.Context) error SystemPowerOn(context.Context) error
SystemPowerStatus(context.Context) (power.Status, 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.
SystemPowerStatus(context.Context) (string, error)
NodeID() string
SetBootSourceByType(context.Context) error
// TODO(drewwalters96): This function is tightly coupled to Redfish. It should be combined with the // TODO(drewwalters96): This function is tightly coupled to Redfish. It should be combined with the
// SetBootSource operation and removed from the client interface. // SetBootSource operation and removed from the client interface.

View File

@ -0,0 +1,45 @@
/*
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 power safely translates power information between different management clients.
package power
const (
// StatusUnknown indicates that a baremetal host is in an unknown power state.
StatusUnknown Status = iota
// StatusOn indicates that a baremetal host is powered on.
StatusOn
// StatusOff indicates that a baremetal host is not powered on.
StatusOff
// StatusPoweringOn indicates that a baremetal host is powering on.
StatusPoweringOn
// StatusPoweringOff indicates that a baremetal host is powering off.
StatusPoweringOff
)
// Status indicates the power status of a baremetal host e.g. on, off, unknown.
type Status int
var statusMap = [5]string{
"UNKNOWN",
"ON",
"OFF",
"POWERING ON",
"POWERING OFF",
}
// String provides a human-readable string value for a power status.
func (s Status) String() string {
return statusMap[s]
}

View File

@ -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 power
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestStatus(t *testing.T) {
tests := []struct {
name string
status Status
}{
{
name: "StatusUnknown",
status: StatusUnknown,
},
{
name: "StatusOn",
status: StatusOn,
},
{
name: "StatusOff",
status: StatusOff,
},
{
name: "StatusPoweringOn",
status: StatusPoweringOn,
},
{
name: "StatusPoweringOff",
status: StatusPoweringOff,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, statusMap[test.status], test.status.String())
})
}
}

View File

@ -24,6 +24,7 @@ import (
redfishClient "opendev.org/airship/go-redfish/client" redfishClient "opendev.org/airship/go-redfish/client"
"opendev.org/airship/airshipctl/pkg/log" "opendev.org/airship/airshipctl/pkg/log"
"opendev.org/airship/airshipctl/pkg/remote/power"
) )
// contextKey is used by the redfish package as a unique key type in order to prevent collisions // contextKey is used by the redfish package as a unique key type in order to prevent collisions
@ -257,13 +258,24 @@ func (c *Client) SystemPowerOn(ctx context.Context) error {
} }
// SystemPowerStatus retrieves the power status of a host as a human-readable string. // SystemPowerStatus retrieves the power status of a host as a human-readable string.
func (c *Client) SystemPowerStatus(ctx context.Context) (string, error) { func (c *Client) SystemPowerStatus(ctx context.Context) (power.Status, error) {
computerSystem, httpResp, err := c.RedfishAPI.GetSystem(ctx, c.nodeID) computerSystem, httpResp, err := c.RedfishAPI.GetSystem(ctx, c.nodeID)
if err = ScreenRedfishError(httpResp, err); err != nil { if err = ScreenRedfishError(httpResp, err); err != nil {
return "", err return power.StatusUnknown, err
} }
return string(computerSystem.PowerState), nil switch computerSystem.PowerState {
case redfishClient.POWERSTATE_ON:
return power.StatusOn, nil
case redfishClient.POWERSTATE_OFF:
return power.StatusOff, nil
case redfishClient.POWERSTATE_POWERING_ON:
return power.StatusPoweringOn, nil
case redfishClient.POWERSTATE_POWERING_OFF:
return power.StatusPoweringOff, nil
default:
return power.StatusUnknown, nil
}
} }
// NewClient returns a client with the capability to make Redfish requests. // NewClient returns a client with the capability to make Redfish requests.

View File

@ -18,6 +18,7 @@ import (
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
redfishClient "opendev.org/airship/go-redfish/client" redfishClient "opendev.org/airship/go-redfish/client"
"opendev.org/airship/airshipctl/pkg/remote/power"
"opendev.org/airship/airshipctl/pkg/remote/redfish" "opendev.org/airship/airshipctl/pkg/remote/redfish"
) )
@ -127,9 +128,14 @@ func (m *MockClient) SystemPowerOn(ctx context.Context) error {
// client.On("SystemPowerStatus").Return(<return values>) // client.On("SystemPowerStatus").Return(<return values>)
// //
// err := client.SystemPowerStatus(<args>) // err := client.SystemPowerStatus(<args>)
func (m *MockClient) SystemPowerStatus(ctx context.Context) (string, error) { func (m *MockClient) SystemPowerStatus(ctx context.Context) (power.Status, error) {
args := m.Called(ctx) args := m.Called(ctx)
return args.String(0), args.Error(1) powerStatus, ok := args.Get(0).(power.Status)
if !ok {
return power.StatusUnknown, args.Error(2)
}
return powerStatus, args.Error(1)
} }
// NewClient returns a mocked Redfish client in order to test functions that use the Redfish client without making any // NewClient returns a mocked Redfish client in order to test functions that use the Redfish client without making any