From 086280a89b5ed79e28a948e626c8d5815e221731 Mon Sep 17 00:00:00 2001 From: Dimitar Mirchev Date: Tue, 22 Aug 2023 11:04:04 +0300 Subject: [PATCH] unify regexp usage across codebase (#8379) * unify regexp usage across codebase * address PR feedback --- .../healthcheck/general/managed_resource.go | 11 +++++------ extensions/pkg/controller/worker/machines.go | 11 ++--------- extensions/pkg/terraformer/errors.go | 10 ++++++---- extensions/pkg/webhook/utils.go | 5 ++++- pkg/apis/core/validation/cloudprofile.go | 8 +++++--- pkg/apis/core/validation/shoot.go | 5 +++-- pkg/operation/botanist/secrets.go | 6 ++++-- pkg/operation/care/checker.go | 10 ++++++---- .../controller/networkpolicy/reconciler.go | 6 +----- pkg/utils/kubernetes/bootstraptoken/bootstraptoken.go | 6 ++++-- pkg/utils/managedresources/managedresources.go | 11 +++++------ pkg/utils/miscellaneous.go | 6 ++++-- test/framework/reporter/esreporter.go | 2 +- 13 files changed, 50 insertions(+), 47 deletions(-) diff --git a/extensions/pkg/controller/healthcheck/general/managed_resource.go b/extensions/pkg/controller/healthcheck/general/managed_resource.go index 25d5b369efb..6e6178da327 100644 --- a/extensions/pkg/controller/healthcheck/general/managed_resource.go +++ b/extensions/pkg/controller/healthcheck/general/managed_resource.go @@ -62,6 +62,9 @@ func (healthChecker *ManagedResourceHealthChecker) DeepCopy() healthcheck.Health return &shallowCopy } +// configurationProblemRegex is used to check if a not healthy managed resource has a configuration problem. +var configurationProblemRegex = regexp.MustCompile(`(?i)(error during apply of object .* is invalid:)`) + // Check executes the health check func (healthChecker *ManagedResourceHealthChecker) Check(ctx context.Context, request types.NamespacedName) (*healthcheck.SingleCheckResult, error) { mcmDeployment := &resourcesv1alpha1.ManagedResource{} @@ -81,12 +84,8 @@ func (healthChecker *ManagedResourceHealthChecker) Check(ctx context.Context, re if isHealthy, err := managedResourceIsHealthy(mcmDeployment); !isHealthy { healthChecker.logger.Error(err, "Health check failed") - var ( - errorCodes []gardencorev1beta1.ErrorCode - configurationProblemRegexp = regexp.MustCompile(`(?i)(error during apply of object .* is invalid:)`) - ) - - if configurationProblemRegexp.MatchString(err.Error()) { + var errorCodes []gardencorev1beta1.ErrorCode + if configurationProblemRegex.MatchString(err.Error()) { errorCodes = append(errorCodes, gardencorev1beta1.ErrorConfigurationProblem) } diff --git a/extensions/pkg/controller/worker/machines.go b/extensions/pkg/controller/worker/machines.go index 5b244a72e5a..c9232cbc959 100644 --- a/extensions/pkg/controller/worker/machines.go +++ b/extensions/pkg/controller/worker/machines.go @@ -23,7 +23,6 @@ import ( machinev1alpha1 "github.com/gardener/machine-controller-manager/pkg/apis/machine/v1alpha1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" extensionscontroller "github.com/gardener/gardener/extensions/pkg/controller" "github.com/gardener/gardener/extensions/pkg/util" @@ -33,13 +32,7 @@ import ( "github.com/gardener/gardener/pkg/utils" ) -var diskSizeRegexp *regexp.Regexp - -func init() { - regexp, err := regexp.Compile(`^(\d+)`) - utilruntime.Must(err) - diskSizeRegexp = regexp -} +var diskSizeRegex = regexp.MustCompile(`^(\d+)`) // MachineDeployment holds information about the name, class, replicas of a MachineDeployment // managed by the machine-controller-manager. @@ -237,7 +230,7 @@ func DistributePositiveIntOrPercent(zoneIndex int32, intOrPercent intstr.IntOrSt // DiskSize extracts the numerical component of DiskSize strings, i.e. strings like "10Gi" and // returns it as string, i.e. "10" will be returned. func DiskSize(size string) (int, error) { - i, err := strconv.Atoi(diskSizeRegexp.FindString(size)) + i, err := strconv.Atoi(diskSizeRegex.FindString(size)) if err != nil { return -1, err } diff --git a/extensions/pkg/terraformer/errors.go b/extensions/pkg/terraformer/errors.go index 9614e8c7f7b..e0db91dde7a 100644 --- a/extensions/pkg/terraformer/errors.go +++ b/extensions/pkg/terraformer/errors.go @@ -20,14 +20,16 @@ import ( "strings" ) +var ( + regexTerraformError = regexp.MustCompile(`(?:Error): *([\s\S]*)`) + regexUUID = regexp.MustCompile(`(?i)[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}`) + regexMultiNewline = regexp.MustCompile(`\n{2,}`) +) + // findTerraformErrors gets the of a Terraform run and parses it to find the occurred // errors (which will be returned). If no errors occurred, an empty string will be returned. func findTerraformErrors(output string) string { var ( - regexTerraformError = regexp.MustCompile(`(?:Error): *([\s\S]*)`) - regexUUID = regexp.MustCompile(`(?i)[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}`) - regexMultiNewline = regexp.MustCompile(`\n{2,}`) - errorMessage = output valid []string ) diff --git a/extensions/pkg/webhook/utils.go b/extensions/pkg/webhook/utils.go index afeb8c5b8ea..f4e9685c397 100644 --- a/extensions/pkg/webhook/utils.go +++ b/extensions/pkg/webhook/utils.go @@ -42,10 +42,13 @@ func AppendUniqueUnit(units *[]extensionsv1alpha1.Unit, unit extensionsv1alpha1. *units = append(*units, unit) } +// splitCommandLineRegex is used to split command line arguments by white space or "\". +var splitCommandLineRegex = regexp.MustCompile(`[\\\s]+`) + // DeserializeCommandLine de-serializes the given string to a slice of command line elements by splitting it // on white space and the "\" character. func DeserializeCommandLine(s string) []string { - return regexp.MustCompile(`[\\\s]+`).Split(s, -1) + return splitCommandLineRegex.Split(s, -1) } // SerializeCommandLine serializes the given command line elements slice to a string by joining the first diff --git a/pkg/apis/core/validation/cloudprofile.go b/pkg/apis/core/validation/cloudprofile.go index 99cc559781e..67b4ed13bfb 100644 --- a/pkg/apis/core/validation/cloudprofile.go +++ b/pkg/apis/core/validation/cloudprofile.go @@ -86,6 +86,9 @@ func ValidateCloudProfileSpec(spec *core.CloudProfileSpec, fldPath *field.Path) return allErrs } +// k8sVersionCPRegex is used to validate kubernetes versions in a cloud profile. +var k8sVersionCPRegex = regexp.MustCompile(`^([0-9]+\.){2}[0-9]+$`) + func validateKubernetesSettings(kubernetes core.KubernetesSettings, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if len(kubernetes.Versions) == 0 { @@ -100,11 +103,10 @@ func validateKubernetesSettings(kubernetes core.KubernetesSettings, fldPath *fie } versionsFound := sets.New[string]() - r, _ := regexp.Compile(`^([0-9]+\.){2}[0-9]+$`) for i, version := range kubernetes.Versions { idxPath := fldPath.Child("versions").Index(i) - if !r.MatchString(version.Version) { - allErrs = append(allErrs, field.Invalid(idxPath, version, fmt.Sprintf("all Kubernetes versions must match the regex %s", r))) + if !k8sVersionCPRegex.MatchString(version.Version) { + allErrs = append(allErrs, field.Invalid(idxPath, version, fmt.Sprintf("all Kubernetes versions must match the regex %s", k8sVersionCPRegex))) } else if versionsFound.Has(version.Version) { allErrs = append(allErrs, field.Duplicate(idxPath.Child("version"), version.Version)) } else { diff --git a/pkg/apis/core/validation/shoot.go b/pkg/apis/core/validation/shoot.go index 4a57346ddf4..5347152ab6d 100644 --- a/pkg/apis/core/validation/shoot.go +++ b/pkg/apis/core/validation/shoot.go @@ -1412,6 +1412,9 @@ const ( maxVolumeNameLength = 15 ) +// volumeSizeRegex is used for volume size validation. +var volumeSizeRegex = regexp.MustCompile(`^(\d)+Gi$`) + // ValidateWorker validates the worker object. func ValidateWorker(worker core.Worker, kubernetes core.Kubernetes, fldPath *field.Path, inTemplate bool) field.ErrorList { kubernetesVersion := kubernetes.Version @@ -1476,8 +1479,6 @@ func ValidateWorker(worker core.Worker, kubernetes core.Kubernetes, fldPath *fie } } - volumeSizeRegex, _ := regexp.Compile(`^(\d)+Gi$`) - if worker.Volume != nil { if !volumeSizeRegex.MatchString(worker.Volume.VolumeSize) { allErrs = append(allErrs, field.Invalid(fldPath.Child("volume", "size"), worker.Volume.VolumeSize, fmt.Sprintf("volume size must match the regex %s", volumeSizeRegex))) diff --git a/pkg/operation/botanist/secrets.go b/pkg/operation/botanist/secrets.go index ff2ef909de6..18d33f6f3a0 100644 --- a/pkg/operation/botanist/secrets.go +++ b/pkg/operation/botanist/secrets.go @@ -278,6 +278,9 @@ func (b *Botanist) generateSSHKeypair(ctx context.Context) error { return nil } +// quotaExceededRegex is used to check if an error occurred due to infrastructure quota limits. +var quotaExceededRegex = regexp.MustCompile(`(?i)((?:^|[^t]|(?:[^s]|^)t|(?:[^e]|^)st|(?:[^u]|^)est|(?:[^q]|^)uest|(?:[^e]|^)quest|(?:[^r]|^)equest)LimitExceeded|Quotas|Quota.*exceeded|exceeded quota|Quota has been met|QUOTA_EXCEEDED)`) + func (b *Botanist) syncShootCredentialToGarden( ctx context.Context, nameSuffix string, @@ -303,8 +306,7 @@ func (b *Botanist) syncShootCredentialToGarden( return nil }) - quotaExceededRegexp := regexp.MustCompile(`(?i)((?:^|[^t]|(?:[^s]|^)t|(?:[^e]|^)st|(?:[^u]|^)est|(?:[^q]|^)uest|(?:[^e]|^)quest|(?:[^r]|^)equest)LimitExceeded|Quotas|Quota.*exceeded|exceeded quota|Quota has been met|QUOTA_EXCEEDED)`) - if err != nil && quotaExceededRegexp.MatchString(err.Error()) { + if err != nil && quotaExceededRegex.MatchString(err.Error()) { return v1beta1helper.NewErrorWithCodes(err, gardencorev1beta1.ErrorInfraQuotaExceeded) } return err diff --git a/pkg/operation/care/checker.go b/pkg/operation/care/checker.go index 8a7bbb95f68..c27edd24fb4 100644 --- a/pkg/operation/care/checker.go +++ b/pkg/operation/care/checker.go @@ -197,16 +197,18 @@ func (b *HealthChecker) checkStatefulSets(condition gardencorev1beta1.Condition, return nil } +// kubeletConfigProblemRegex is used to check if an error occurred due to a kubelet configuration problem. +var kubeletConfigProblemRegex = regexp.MustCompile(`(?i)(KubeletHasInsufficientMemory|KubeletHasDiskPressure|KubeletHasInsufficientPID)`) + func (b *HealthChecker) checkNodes(condition gardencorev1beta1.Condition, nodes []corev1.Node, workerGroupName string, workerGroupKubernetesVersion *semver.Version) *gardencorev1beta1.Condition { for _, object := range nodes { if err := health.CheckNode(&object); err != nil { var ( - errorCodes []gardencorev1beta1.ErrorCode - message = fmt.Sprintf("Node %q in worker group %q is unhealthy: %v", object.Name, workerGroupName, err) - configurationProblemRegexp = regexp.MustCompile(`(?i)(KubeletHasInsufficientMemory|KubeletHasDiskPressure|KubeletHasInsufficientPID)`) + errorCodes []gardencorev1beta1.ErrorCode + message = fmt.Sprintf("Node %q in worker group %q is unhealthy: %v", object.Name, workerGroupName, err) ) - if configurationProblemRegexp.MatchString(err.Error()) { + if kubeletConfigProblemRegex.MatchString(err.Error()) { errorCodes = append(errorCodes, gardencorev1beta1.ErrorConfigurationProblem) } diff --git a/pkg/resourcemanager/controller/networkpolicy/reconciler.go b/pkg/resourcemanager/controller/networkpolicy/reconciler.go index 072ed9c47a0..17ec698afbf 100644 --- a/pkg/resourcemanager/controller/networkpolicy/reconciler.go +++ b/pkg/resourcemanager/controller/networkpolicy/reconciler.go @@ -39,11 +39,7 @@ import ( kubernetesutils "github.com/gardener/gardener/pkg/utils/kubernetes" ) -var fromPolicyRegexp *regexp.Regexp - -func init() { - fromPolicyRegexp = regexp.MustCompile(resourcesv1alpha1.NetworkPolicyFromPolicyAnnotationPrefix + "(.*)" + resourcesv1alpha1.NetworkPolicyFromPolicyAnnotationSuffix) -} +var fromPolicyRegexp = regexp.MustCompile(resourcesv1alpha1.NetworkPolicyFromPolicyAnnotationPrefix + "(.*)" + resourcesv1alpha1.NetworkPolicyFromPolicyAnnotationSuffix) // Reconciler reconciles Service objects and creates NetworkPolicy objects. type Reconciler struct { diff --git a/pkg/utils/kubernetes/bootstraptoken/bootstraptoken.go b/pkg/utils/kubernetes/bootstraptoken/bootstraptoken.go index 72ede433da4..70e8f0e3b40 100644 --- a/pkg/utils/kubernetes/bootstraptoken/bootstraptoken.go +++ b/pkg/utils/kubernetes/bootstraptoken/bootstraptoken.go @@ -30,6 +30,9 @@ import ( "github.com/gardener/gardener/pkg/utils/kubernetes" ) +// validBootstrapTokenRegex is used to check if an existing token can be interpreted as a bootstrap token. +var validBootstrapTokenRegex = regexp.MustCompile(`[a-z0-9]{16}`) + // ComputeBootstrapToken computes and creates a new bootstrap token, and returns it. func ComputeBootstrapToken(ctx context.Context, c client.Client, tokenID, description string, validity time.Duration) (secret *corev1.Secret, err error) { var ( @@ -47,8 +50,7 @@ func ComputeBootstrapToken(ctx context.Context, c client.Client, tokenID, descri return nil, err } - validBootstrapTokenSecret, _ := regexp.Compile(`[a-z0-9]{16}`) - if existingSecretToken, ok := secret.Data[bootstraptokenapi.BootstrapTokenSecretKey]; ok && validBootstrapTokenSecret.Match(existingSecretToken) { + if existingSecretToken, ok := secret.Data[bootstraptokenapi.BootstrapTokenSecretKey]; ok && validBootstrapTokenRegex.Match(existingSecretToken) { bootstrapTokenSecretKey = string(existingSecretToken) } else { bootstrapTokenSecretKey, err = utils.GenerateRandomStringFromCharset(16, "0123456789abcdefghijklmnopqrstuvwxyz") diff --git a/pkg/utils/managedresources/managedresources.go b/pkg/utils/managedresources/managedresources.go index 5c838a0dac2..6bdf3f128af 100644 --- a/pkg/utils/managedresources/managedresources.go +++ b/pkg/utils/managedresources/managedresources.go @@ -352,13 +352,12 @@ func RenderChartAndCreate(ctx context.Context, namespace string, name string, se return Create(ctx, client, namespace, name, nil, secretNameWithPrefix, "", map[string][]byte{chartName: data}, pointer.Bool(false), injectedLabels, &forceOverwriteAnnotations) } -func checkConfigurationError(err error) []gardencorev1beta1.ErrorCode { - var ( - errorCodes []gardencorev1beta1.ErrorCode - configurationProblemRegexp = regexp.MustCompile(`(?i)(error during apply of object .* is invalid:)`) - ) +// configurationProblemRegex is used to check if an error is caused by a bad managed resource configuration. +var configurationProblemRegex = regexp.MustCompile(`(?i)(error during apply of object .* is invalid:)`) - if configurationProblemRegexp.MatchString(err.Error()) { +func checkConfigurationError(err error) []gardencorev1beta1.ErrorCode { + var errorCodes []gardencorev1beta1.ErrorCode + if configurationProblemRegex.MatchString(err.Error()) { errorCodes = append(errorCodes, gardencorev1beta1.ErrorConfigurationProblem) } diff --git a/pkg/utils/miscellaneous.go b/pkg/utils/miscellaneous.go index 963303b541c..541a99e6003 100644 --- a/pkg/utils/miscellaneous.go +++ b/pkg/utils/miscellaneous.go @@ -118,10 +118,12 @@ func FindFreePort() (int, error) { return l.Addr().(*net.TCPAddr).Port, nil } +// emailVefiryRegex is used to verify the validity of an email. +var emailVefiryRegex = regexp.MustCompile(`^[^@]+@(?:[a-zA-Z-0-9]+\.)+[a-zA-Z]{2,}$`) + // TestEmail validates the provided against a regular expression and returns whether it matches. func TestEmail(email string) bool { - match, _ := regexp.MatchString(`^[^@]+@(?:[a-zA-Z-0-9]+\.)+[a-zA-Z]{2,}$`, email) - return match + return emailVefiryRegex.MatchString(email) } // IDForKeyWithOptionalValue returns an identifier for the given key + optional value. diff --git a/test/framework/reporter/esreporter.go b/test/framework/reporter/esreporter.go index 2f611bf58bf..84e6f765298 100644 --- a/test/framework/reporter/esreporter.go +++ b/test/framework/reporter/esreporter.go @@ -82,7 +82,7 @@ type GardenerESReporter struct { index []byte } -var matchLabel, _ = regexp.Compile(`\\[(.*?)\\]`) +var matchLabel = regexp.MustCompile(`\\[(.*?)\\]`) // newGardenerESReporter creates a new Gardener elasticsearch reporter. // Any report will be encoded to json and stored to the passed filename in the given es index.