func BuildTargetRAIDCfg(raid *metal3v1alpha1.RAIDConfig) (logicalDisks []nodes.LogicalDisk, err error) {
	defer func() {
		r := recover()
		if r != nil {
			err = fmt.Errorf("panic in build RAID settings: %v", r)
		}
	}()
	if raid == nil {
		return
	}
	if len(raid.HardwareRAIDVolumes) != 0 {
		logicalDisks, err = buildTargetHardwareRAIDCfg(raid.HardwareRAIDVolumes)
	} else if len(raid.SoftwareRAIDVolumes) != 0 {
		logicalDisks, err = buildTargetSoftwareRAIDCfg(raid.SoftwareRAIDVolumes)
	}
	return
}
BuildTargetRAIDCfg build RAID logical disks, this method doesn't set the root volume
package ironic
import (
	"fmt"
	"reflect"
	"github.com/pkg/errors"
	"github.com/gophercloud/gophercloud/openstack/baremetal/v1/nodes"
	metal3v1alpha1 "github.com/metal3-io/baremetal-operator/apis/metal3.io/v1alpha1"
	"github.com/metal3-io/baremetal-operator/pkg/ironic/devicehints"
)
const (
	noRAIDInterface       string = "no-raid"
	softwareRAIDInterface string = "agent"
)
func BuildRAIDCleanSteps(raidInterface string, target *metal3v1alpha1.RAIDConfig, actual *metal3v1alpha1.RAIDConfig) (cleanSteps []nodes.CleanStep, err error) {
	err = CheckRAIDConfigure(raidInterface, target)
	if err != nil {
		return nil, err
	}
	if raidInterface == noRAIDInterface {
		return
	}
	if raidInterface == softwareRAIDInterface {
		if target != nil {
			target.HardwareRAIDVolumes = nil
		}
		if actual != nil {
			actual.HardwareRAIDVolumes = nil
		}
		if reflect.DeepEqual(target, actual) {
			return
		}
		cleanSteps = append(
			cleanSteps,
			[]nodes.CleanStep{
				{
					Interface: "raid",
					Step:      "delete_configuration",
				},
				{
					Interface: "deploy",
					Step:      "erase_devices_metadata",
				},
			}...,
		)
		if target == nil || len(target.SoftwareRAIDVolumes) == 0 {
			return
		}
		cleanSteps = append(
			cleanSteps,
			nodes.CleanStep{
				Interface: "raid",
				Step:      "create_configuration",
			},
		)
		return
	}
	if target == nil || target.HardwareRAIDVolumes == nil {
		return
	}
	target.SoftwareRAIDVolumes = nil
	if actual != nil {
		actual.SoftwareRAIDVolumes = nil
	}
	if reflect.DeepEqual(target, actual) {
		return
	}
	cleanSteps = append(
		cleanSteps,
		nodes.CleanStep{
			Interface: "raid",
			Step:      "delete_configuration",
		},
	)
	if len(target.HardwareRAIDVolumes) == 0 {
		return
	}
	cleanSteps = append(
		cleanSteps,
		nodes.CleanStep{
			Interface: "raid",
			Step:      "create_configuration",
		},
	)
	return
}
func CheckRAIDConfigure(raidInterface string, raid *metal3v1alpha1.RAIDConfig) error {
	switch raidInterface {
	case noRAIDInterface:
		if raid != nil && (len(raid.HardwareRAIDVolumes) != 0 || len(raid.SoftwareRAIDVolumes) != 0) {
			return fmt.Errorf("raid settings are defined, but the node's driver %s does not support RAID", raidInterface)
		}
	case softwareRAIDInterface:
		if raid != nil && len(raid.HardwareRAIDVolumes) != 0 {
			return fmt.Errorf("node's driver %s does not support hardware RAID", raidInterface)
		}
	default:
		if raid != nil && len(raid.HardwareRAIDVolumes) == 0 && len(raid.SoftwareRAIDVolumes) != 0 {
			return fmt.Errorf("node's driver %s does not support software RAID", raidInterface)
		}
	}
	return nil
}