mirror of
https://github.com/openshift/installer.git
synced 2026-02-05 15:47:14 +01:00
validation: Allow periods in gcp and azure cluster names.
Prior to this change, GCP and Azure did not allow periods in the cluster names because that would violate their API naming conventions. However, newer versions of the installer create cloud assets based on the InfraID, where all periods are now translated to dashes. This change modifies the verification to allow periods. As a result, users can now create clusters with names such as "my.prod". They must otherwise comply with RFC1035 "[a-z]([-a-z0-9]*[a-z0-9])?".
This commit is contained in:
@@ -4,8 +4,6 @@ import (
|
||||
survey "gopkg.in/AlecAivazis/survey.v1"
|
||||
|
||||
"github.com/openshift/installer/pkg/asset"
|
||||
azurevalidation "github.com/openshift/installer/pkg/types/azure/validation"
|
||||
gcpvalidation "github.com/openshift/installer/pkg/types/gcp/validation"
|
||||
"github.com/openshift/installer/pkg/types/validation"
|
||||
"github.com/openshift/installer/pkg/validate"
|
||||
)
|
||||
@@ -32,10 +30,10 @@ func (a *clusterName) Generate(parents asset.Parents) error {
|
||||
|
||||
validator := survey.Required
|
||||
|
||||
if platform.GCP != nil {
|
||||
validator = survey.ComposeValidators(validator, func(ans interface{}) error { return gcpvalidation.ValidateClusterName(ans.(string)) })
|
||||
} else if platform.Azure != nil {
|
||||
validator = survey.ComposeValidators(validator, func(ans interface{}) error { return azurevalidation.ValidateClusterName(ans.(string)) })
|
||||
if platform.GCP != nil || platform.Azure != nil {
|
||||
validator = survey.ComposeValidators(validator, func(ans interface{}) error {
|
||||
return validate.ClusterName1035(ans.(string))
|
||||
})
|
||||
}
|
||||
validator = survey.ComposeValidators(validator, func(ans interface{}) error {
|
||||
return validate.DomainName(validation.ClusterDomain(bd.BaseDomain, ans.(string)), false)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
|
||||
"github.com/openshift/installer/pkg/types"
|
||||
@@ -45,14 +42,3 @@ func ValidatePlatform(p *azure.Platform, publish types.PublishingStrategy, fldPa
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateClusterName confirms that the provided cluster name matches Azure naming requirements.
|
||||
func ValidateClusterName(clusterName string) error {
|
||||
azureResourceFmt := `[a-z][a-z0-9-]{1,61}[a-z0-9]`
|
||||
|
||||
re := regexp.MustCompile("^" + azureResourceFmt + "$")
|
||||
if !re.MatchString(clusterName) {
|
||||
return errors.Errorf("Azure requires cluster name to match regular expression %s", azureResourceFmt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"sort"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
|
||||
"github.com/openshift/installer/pkg/types/gcp"
|
||||
@@ -72,14 +70,3 @@ func ValidatePlatform(p *gcp.Platform, fldPath *field.Path) field.ErrorList {
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateClusterName confirms that the provided cluster name matches GCP naming requirements.
|
||||
func ValidateClusterName(clusterName string) error {
|
||||
gcpResourceFmt := `(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)`
|
||||
|
||||
re := regexp.MustCompile("^" + gcpResourceFmt + "$")
|
||||
if !re.MatchString(clusterName) {
|
||||
return errors.Errorf("GCP requires cluster name to match regular expression %s", gcpResourceFmt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -63,11 +63,10 @@ func ValidateInstallConfig(c *types.InstallConfig, openStackValidValuesFetcher o
|
||||
}
|
||||
}
|
||||
nameErr := validate.ClusterName(c.ObjectMeta.Name)
|
||||
if gcpNameErr := gcpvalidation.ValidateClusterName(c.ObjectMeta.Name); c.Platform.GCP != nil && gcpNameErr != nil {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata", "name"), c.ObjectMeta.Name, gcpNameErr.Error()))
|
||||
} else if azureNameErr := azurevalidation.ValidateClusterName(c.ObjectMeta.Name); c.Platform.Azure != nil && azureNameErr != nil {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata", "name"), c.ObjectMeta.Name, azureNameErr.Error()))
|
||||
} else if nameErr != nil {
|
||||
if c.Platform.GCP != nil || c.Platform.Azure != nil {
|
||||
nameErr = validate.ClusterName1035(c.ObjectMeta.Name)
|
||||
}
|
||||
if nameErr != nil {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("metadata", "name"), c.ObjectMeta.Name, nameErr.Error()))
|
||||
}
|
||||
baseDomainErr := validate.DomainName(c.BaseDomain, true)
|
||||
|
||||
@@ -747,7 +747,7 @@ func TestValidateInstallConfig(t *testing.T) {
|
||||
c.ObjectMeta.Name = "1-invalid-cluster"
|
||||
return c
|
||||
}(),
|
||||
expectedError: `^metadata\.name: Invalid value: "1-invalid-cluster": GCP requires cluster name to match regular expression \(\?:\[a-z\]\(\?:\[-a-z0-9\]\{0,61\}\[a-z0-9\]\)\?\)$`,
|
||||
expectedError: `^metadata\.name: Invalid value: "1-invalid-cluster": cluster name must begin with a lower-case letter$`,
|
||||
},
|
||||
{
|
||||
name: "release image source is not canonical",
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
uuid "github.com/google/uuid"
|
||||
@@ -97,6 +98,22 @@ func ImagePullSecret(secret string) error {
|
||||
return k8serrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
// ClusterName1035 checks the provided cluster name matches RFC1035 naming requirements.
|
||||
// Some platform resource names must comply with RFC1035 "[a-z]([-a-z0-9]*[a-z0-9])?". They
|
||||
// are based on the InfraID, which is a truncated version of the cluster name where all non-
|
||||
// alphanumeric characters "[^A-Za-z0-9-]" have been replaced with dashes "-". As a result,
|
||||
// if we first verify the name starts with a lower-case letter "^[a-z]" then we can rely on
|
||||
// the ClusterName function to confirm compliance with the rest. The resulting name will
|
||||
// therefore match RFC1035 with the exception of possible periods ".", which will be
|
||||
// translated into dashes "-" in the InfraID before being used to create cloud resources.
|
||||
func ClusterName1035(v string) error {
|
||||
re := regexp.MustCompile("^[a-z]")
|
||||
if !re.MatchString(v) {
|
||||
return errors.New("cluster name must begin with a lower-case letter")
|
||||
}
|
||||
return ClusterName(v)
|
||||
}
|
||||
|
||||
// ClusterName checks if the given string is a valid name for a cluster and returns an error if not.
|
||||
// The max length of the DNS label is `DNS1123LabelMaxLength + 9` because the public DNS zones have records
|
||||
// `api.clustername`, `*.apps.clustername`, and *.apps is rendered as the nine-character \052.apps in DNS records.
|
||||
|
||||
Reference in New Issue
Block a user