in pkg/apis/ndbcontroller/v1/validation.go [56:146]
func (nc *NdbCluster) HasValidSpec() (bool, field.ErrorList) {
spec := nc.Spec
var errList field.ErrorList
specPath := field.NewPath("spec")
mysqldPath := specPath.Child("mysqlNode")
dataNodePath := specPath.Child("dataNode")
managementNodePath := specPath.Child("managementNode")
dataNodeCount := spec.DataNode.NodeCount
mysqlServerCount := nc.GetMySQLServerMaxNodeCount()
managementNodeCount := nc.GetManagementNodeCount()
numOfFreeApiSlots := spec.FreeAPISlots + 1
// check if number of data nodes is a multiple of redundancy
if math.Mod(float64(dataNodeCount), float64(spec.RedundancyLevel)) != 0 {
msg := fmt.Sprintf(
"spec.dataNode.nodeCount should be a multiple of the spec.redundancyLevel(=%d)", spec.RedundancyLevel)
errList = append(errList, field.Invalid(dataNodePath.Child("nodeCount"), dataNodeCount, msg))
}
// check if total number of nodes are not more than the allowed maximum
total := managementNodeCount + dataNodeCount + mysqlServerCount + numOfFreeApiSlots
if total > constants.MaxNumberOfNodes {
invalidValue := fmt.Sprintf(
"%d (= %d management, %d data, %d mysql nodes and %d free API nodes)",
total, managementNodeCount, dataNodeCount, mysqlServerCount, numOfFreeApiSlots)
msg := fmt.Sprintf(
"Total number of MySQL Cluster nodes should not exceed the allowed maximum of %d", constants.MaxNumberOfNodes)
errList = append(errList, field.Invalid(field.NewPath("Total Nodes"), invalidValue, msg))
}
// check if there are any disallowed config params in dataNode's Configuration.
if err := validateConfigParams(nc.Spec.DataNode.Config, dataNodePath.Child("config")); err != nil {
errList = append(errList, err...)
}
// check if there are any disallowed config params in managementNode Config.
if nc.Spec.ManagementNode != nil {
if err := validateConfigParams(nc.Spec.ManagementNode.Config, managementNodePath.Child("config")); err != nil {
errList = append(errList, err...)
}
}
// check if the MySQL root password secret name has the expected format
var rootPasswordSecret string
if spec.MysqlNode != nil {
mysqldSpec := spec.MysqlNode
// check if the MySQL root password secret name has the expected format
rootPasswordSecret = mysqldSpec.RootPasswordSecretName
if rootPasswordSecret != "" {
errs := validation.IsDNS1123Subdomain(rootPasswordSecret)
// append errors, if any, to errList
for _, err := range errs {
errList = append(errList,
field.Invalid(mysqldPath.Child("rootPasswordSecretName"), rootPasswordSecret, err))
}
}
// check if maxNodeCount is less than nodeCount
if mysqldSpec.MaxNodeCount != 0 &&
mysqldSpec.MaxNodeCount < mysqldSpec.NodeCount {
msg := fmt.Sprintf(
"spec.mysqlNode.maxNodeCount cannot be less than spec.mysqlNode.nodeCount(=%d)", mysqldSpec.NodeCount)
errList = append(errList,
field.Invalid(mysqldPath.Child("maxNodeCount"), mysqldSpec.MaxNodeCount, msg))
}
}
// check if any passed my.cnf has proper format
myCnfString := nc.GetMySQLCnf()
if len(myCnfString) > 0 {
myCnf, err := configparser.ParseString(myCnfString)
if err != nil {
// error parsing the cnf
errList = append(errList,
field.Invalid(mysqldPath.Child("myCnf"), myCnfString, err.Error()))
} else {
// accept only one mysqld section in the cnf
if len(myCnf) != 1 ||
myCnf.GetNumberOfSections("mysqld") != 1 {
errList = append(errList,
field.Invalid(mysqldPath.Child("myCnf"),
myCnfString, "spec.mysqlNode.myCnf can have only one mysqld section"))
}
}
}
return errList == nil, errList
}