github.com/openshift/installer@v1.4.17/pkg/types/powervs/validation/machinepool.go (about)

     1  package validation
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/google/uuid"
    10  	"k8s.io/apimachinery/pkg/util/intstr"
    11  	"k8s.io/apimachinery/pkg/util/sets"
    12  	"k8s.io/apimachinery/pkg/util/validation/field"
    13  
    14  	"github.com/openshift/installer/pkg/types/powervs"
    15  )
    16  
    17  var validSMTLevels = sets.New[string]("1", "2", "3", "4", "5", "6", "7", "8", "on", "off")
    18  
    19  // ValidateMachinePool checks that the specified machine pool is valid.
    20  func ValidateMachinePool(p *powervs.MachinePool, fldPath *field.Path) field.ErrorList {
    21  	allErrs := field.ErrorList{}
    22  
    23  	// Validate VolumeIDs
    24  	volumes := make(map[string]bool)
    25  	for i, volumeID := range p.VolumeIDs {
    26  		_, err := uuid.Parse(volumeID)
    27  		if err != nil {
    28  			allErrs = append(allErrs, field.Invalid(fldPath.Child("volumeIDs").Index(i), volumeID, "volume ID must be a valid UUID"))
    29  		}
    30  		if _, ok := volumes[volumeID]; ok {
    31  			allErrs = append(allErrs, field.Duplicate(fldPath.Child("volumeIDs").Index(i), volumeID))
    32  			continue
    33  		}
    34  		volumes[volumeID] = true
    35  	}
    36  
    37  	// Validate ProcType
    38  	if p.ProcType != "" {
    39  		procTypes := sets.NewString("Shared", "Dedicated", "Capped")
    40  		if !procTypes.Has(string(p.ProcType)) {
    41  			allErrs = append(allErrs, field.NotSupported(fldPath.Child("procType"), p.ProcType, procTypes.List()))
    42  		}
    43  	}
    44  
    45  	// Validate PowerVS Memory and Processors max and min limits
    46  	// More details about PowerVS limits.
    47  	// https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-pricing-virtual-server
    48  	// Validate Processors
    49  	var processors float64
    50  	var err error
    51  	switch p.Processors.Type {
    52  	case intstr.Int:
    53  		processors = float64(p.Processors.IntVal)
    54  	case intstr.String:
    55  		processors, err = strconv.ParseFloat(p.Processors.StrVal, 64)
    56  		if err != nil {
    57  			allErrs = append(allErrs, field.Invalid(fldPath.Child("processors"), p.Processors.StrVal, "processors must be a valid floating point number"))
    58  		}
    59  		if err == nil && !regexp.MustCompile(`^(^$|[0]*|25[0]*|5[0]*|75[0]*)$`).MatchString(strings.Split(p.Processors.StrVal, ".")[1]) {
    60  			allErrs = append(allErrs, field.Invalid(fldPath.Child("processors"), processors, "processors must be in increments of .25"))
    61  		}
    62  	}
    63  	if processors != 0 {
    64  		switch p.ProcType {
    65  		case "Shared", "Capped", "":
    66  			if processors < 0.5 {
    67  				allErrs = append(allErrs, field.Invalid(fldPath.Child("processors"), processors, "minimum number of processors must be .5 cores for capped or shared ProcType"))
    68  			}
    69  		case "Dedicated":
    70  			if processors < 1 {
    71  				allErrs = append(allErrs, field.Invalid(fldPath.Child("processors"), processors, "minimum number of processors must be from 1 core for Dedicated ProcType"))
    72  			}
    73  		}
    74  	}
    75  
    76  	// Validate SMTLevel
    77  	if p.SMTLevel != "" && !validSMTLevels.Has(p.SMTLevel) {
    78  		allErrs = append(allErrs, field.Invalid(fldPath.Child("smtLevel"), p.SMTLevel, fmt.Sprintf("Valid SMT Levels are %s", sets.List(validSMTLevels))))
    79  	}
    80  
    81  	// Validate SysType
    82  	if p.SysType != "" {
    83  		if !powervs.AllKnownSysTypes().Has(p.SysType) {
    84  			allErrs = append(allErrs, field.Invalid(fldPath.Child("sysType"), p.SysType, "unknown system type specified"))
    85  		}
    86  	}
    87  
    88  	// Validate for Maximum Memory and Processors limits
    89  	if p.MemoryGiB != 0 {
    90  		if p.MemoryGiB < 4 {
    91  			allErrs = append(allErrs, field.Invalid(fldPath.Child("memory"), p.MemoryGiB, "memory must be an integer number of GB that is at least 4"))
    92  		}
    93  	}
    94  
    95  	// Validate Mimimum Memory limit of machinepool.
    96  	s922TypeRegex := regexp.MustCompile(`^s922(-.*|)$`)
    97  	e980TypeRegex := regexp.MustCompile(`^e980$`)
    98  
    99  	switch {
   100  	case e980TypeRegex.MatchString(p.SysType):
   101  		if p.MemoryGiB > 15307 {
   102  			allErrs = append(allErrs, field.Invalid(fldPath.Child("memory"), p.MemoryGiB, "maximum memory limit for the e980 SysType is 15307GiB"))
   103  		}
   104  
   105  		if processors > 143 {
   106  			allErrs = append(allErrs, field.Invalid(fldPath.Child("processors"), processors, "maximum processors limit for e980 SysType is 143 cores"))
   107  		}
   108  	case s922TypeRegex.MatchString(p.SysType):
   109  		if p.MemoryGiB > 942 {
   110  			allErrs = append(allErrs, field.Invalid(fldPath.Child("memory"), p.MemoryGiB, "maximum memory limit for the s922 SysType is 942GiB"))
   111  		}
   112  
   113  		if processors > 15 {
   114  			allErrs = append(allErrs, field.Invalid(fldPath.Child("processors"), processors, "maximum processors limit for s922 SysType is 15 cores"))
   115  		}
   116  	}
   117  	return allErrs
   118  }