diff --git a/utils/nvme.go b/utils/nvme.go index 10787e92..c771c895 100644 --- a/utils/nvme.go +++ b/utils/nvme.go @@ -14,6 +14,7 @@ import ( "time" "github.com/bmc-toolbox/common" + "github.com/metal-toolbox/ironlib/actions/wipe" "github.com/metal-toolbox/ironlib/model" "github.com/sirupsen/logrus" ) @@ -118,7 +119,7 @@ func (n *Nvme) Drives(ctx context.Context) ([]*model.Drive, error) { Capabilities: capabilitiesFound, Metadata: metadata, }, - }, nil) + }, n) } return drives, nil @@ -296,7 +297,15 @@ func (n *Nvme) WipeDisk(ctx context.Context, logger *logrus.Logger, device strin return n.wipe(ctx, logger, device, caps) } -func (n *Nvme) wipe(ctx context.Context, logger *logrus.Logger, device string, caps []*common.Capability) error { +// Wipers implements model.WipersGetter so *Nvme can be passed to model.NewDrive +// It returns functions that are able to wipe the drive according the capabilities reported by the drive. +// The functions are ordered by preference, in this case first function is the most secure and last is least. +// Sanitize is preferred over format, crytpographic erase modes over non-cryptographic erase. +func (n *Nvme) Wipers(d *model.Drive) []wipe.Wiper { + return n.getWipers(d.LogicalName, d.Capabilities) +} + +func (n *Nvme) getWipers(device string, caps []*common.Capability) []wipe.Wiper { var ber bool var cer bool var cese bool @@ -311,41 +320,68 @@ func (n *Nvme) wipe(ctx context.Context, logger *logrus.Logger, device string, c } } + var utilities []wipe.Wiper + if cer { - l := logger.WithField("method", "sanitize").WithField("action", CryptoErase) - l.Info("trying wipe") - err := n.Sanitize(ctx, device, CryptoErase) - if err == nil { - return nil - } - l.WithError(err).Info("failed") + fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error { + l := logger.WithField("method", "sanitize").WithField("action", CryptoErase) + l.Info("trying wipe") + err := n.Sanitize(ctx, device, CryptoErase) + if err == nil { + return nil + } + l.WithError(err).Info("failed") + return err + }) + utilities = append(utilities, fn) } if ber { - l := logger.WithField("method", "sanitize").WithField("action", BlockErase) - l.Info("trying wipe") - err := n.Sanitize(ctx, device, BlockErase) - if err == nil { - return nil - } - l.WithError(err).Info("failed") + fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error { + l := logger.WithField("method", "sanitize").WithField("action", BlockErase) + l.Info("trying wipe") + err := n.Sanitize(ctx, device, BlockErase) + if err == nil { + return nil + } + l.WithError(err).Info("failed") + return err + }) + utilities = append(utilities, fn) } if cese { - l := logger.WithField("method", "format").WithField("setting", CryptographicErase) + fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error { + l := logger.WithField("method", "format").WithField("setting", CryptographicErase) + l.Info("trying wipe") + err := n.Format(ctx, device, CryptographicErase) + if err == nil { + return nil + } + l.WithError(err).Info("failed") + return err + }) + utilities = append(utilities, fn) + } + + fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error { + l := logger.WithField("method", "format").WithField("setting", UserDataErase) l.Info("trying wipe") - err := n.Format(ctx, device, CryptographicErase) + err := n.Format(ctx, device, UserDataErase) if err == nil { return nil } l.WithError(err).Info("failed") - } + return err + }) + utilities = append(utilities, fn) + return utilities +} - l := logger.WithField("method", "format").WithField("setting", UserDataErase) - l.Info("trying wipe") - err := n.Format(ctx, device, UserDataErase) - if err == nil { - return nil +func (n *Nvme) wipe(ctx context.Context, logger *logrus.Logger, device string, caps []*common.Capability) error { + for _, cmd := range n.getWipers(device, caps) { + if cmd.Wipe(ctx, logger) == nil { + return nil + } } - l.WithError(err).Info("failed") return ErrIneffectiveWipe } diff --git a/utils/nvme_test.go b/utils/nvme_test.go index 21822263..08993784 100644 --- a/utils/nvme_test.go +++ b/utils/nvme_test.go @@ -68,7 +68,18 @@ func Test_NvmeComponents(t *testing.T) { t.Error(err) } - assert.Equal(t, expected, drives) + assert.Equal(t, len(expected), len(drives)) + for i := range expected { + assert.Equal(t, expected[i].LogicalName, drives[i].LogicalName) + assert.Equal(t, expected[i].Serial, drives[i].Serial) + assert.Equal(t, expected[i].Vendor, drives[i].Vendor) + assert.Equal(t, expected[i].Model, drives[i].Model) + assert.Equal(t, expected[i].Description, drives[i].Description) + assert.Equal(t, expected[i].ProductName, drives[i].ProductName) + assert.Equal(t, expected[i].Firmware, drives[i].Firmware) + assert.Equal(t, expected[i].Capabilities, drives[i].Capabilities) + assert.Equal(t, expected[i].Metadata, drives[i].Metadata) + } } func Test_NvmeDriveCapabilities(t *testing.T) {