diff --git a/pkg/implementation/controllergetter/storcli2.go b/pkg/implementation/controllergetter/storcli2.go index 58c9ed5..84fcc48 100644 --- a/pkg/implementation/controllergetter/storcli2.go +++ b/pkg/implementation/controllergetter/storcli2.go @@ -114,23 +114,48 @@ func (s *StorCLI2) Controllers() ([]*raidcontroller.RAIDController, error) { controllers := make([]*raidcontroller.RAIDController, 0) for i := range cmd.Controllers { - overview, err := utils.UnmarshalToSlice[storcli2SystemOverview]( - cmd.Controllers[i].ResponseData, "System Overview", - ) + found, err := s.controllersFromOverview(cmd.Controllers[i]) if err != nil { - return nil, errors.Wrap(err, "failed to unmarshal system overview") + return nil, err } - for j := range overview { - metadata := &raidcontroller.Metadata{ID: overview[j].Ctrl} + controllers = append(controllers, found...) + } - controller, err := s.Controller(metadata) - if err != nil { - return nil, errors.Wrapf(err, "failed to get controller %d", metadata.ID) - } + return controllers, nil +} - controllers = append(controllers, controller) +// controllersFromOverview resolves every controller listed in one "show all" +// envelope's "System Overview" section. storcli2 omits that section when the +// host has no controllers ("Number of Controllers": 0); that is an empty +// inventory, not an error, mirroring the logical-volume and physical-drive +// getters. +func (s *StorCLI2) controllersFromOverview(controller storcli2.Controller) ( + []*raidcontroller.RAIDController, + error, +) { + overview, err := utils.UnmarshalToSlice[storcli2SystemOverview]( + controller.ResponseData, "System Overview", + ) + if err != nil { + if errors.Is(err, utils.ErrKeyNotFound) { + return nil, nil } + + return nil, errors.Wrap(err, "failed to unmarshal system overview") + } + + controllers := make([]*raidcontroller.RAIDController, 0, len(overview)) + + for j := range overview { + metadata := &raidcontroller.Metadata{ID: overview[j].Ctrl} + + found, err := s.Controller(metadata) + if err != nil { + return nil, errors.Wrapf(err, "failed to get controller %d", metadata.ID) + } + + controllers = append(controllers, found) } return controllers, nil diff --git a/pkg/implementation/controllergetter/storcli2_test.go b/pkg/implementation/controllergetter/storcli2_test.go index 8b4f56e..3d5bdcf 100644 --- a/pkg/implementation/controllergetter/storcli2_test.go +++ b/pkg/implementation/controllergetter/storcli2_test.go @@ -52,6 +52,11 @@ func TestStorCLI2Controllers(t *testing.T) { showAll: []byte(`{"Controllers":[]}`), expectError: true, }, + { + name: "no managed controllers", + showAll: storcli2Fixture(t, "all_no_controllers.json"), + expectedLen: 0, + }, } for _, tt := range tests { @@ -81,7 +86,10 @@ func TestStorCLI2Controllers(t *testing.T) { require.NoError(t, err) require.Len(t, controllers, tt.expectedLen) - assert.Equal(t, 0, controllers[0].ID) + + if tt.expectedLen > 0 { + assert.Equal(t, 0, controllers[0].ID) + } }) } } diff --git a/pkg/implementation/controllergetter/testdata/storcli2/all_no_controllers.json b/pkg/implementation/controllergetter/testdata/storcli2/all_no_controllers.json new file mode 100644 index 0000000..77793af --- /dev/null +++ b/pkg/implementation/controllergetter/testdata/storcli2/all_no_controllers.json @@ -0,0 +1,19 @@ +{ +"Controllers":[ +{ + "Command Status" : { + "CLI Version" : "008.0005.0000.0010 Feb 22, 2023", + "Operating system" : "Linux4.18.0-553.124.1.el8_10.x86_64", + "Status Code" : 0, + "Status" : "Success", + "Description" : "None" + }, + "Response Data" : { + "Number of Controllers" : 0, + "Host Name" : "application-node", + "Operating System " : "Linux4.18.0-553.124.1.el8_10.x86_64", + "SL8 Library Version" : "08.0507.0000" + } +} +] +}