Skip to content

Commit

Permalink
Merge pull request #55 from aws-controllers-k8s/feat/validate-k8s-ver…
Browse files Browse the repository at this point in the history
…sion

feat(validation): add Kubernetes "version" format validation
  • Loading branch information
michaelhtm authored Oct 22, 2024
2 parents 463ae9a + 1849971 commit f278272
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
24 changes: 24 additions & 0 deletions internal/resourcegroup/graph/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"fmt"
"regexp"

"k8s.io/apimachinery/pkg/runtime/schema"

"github.com/aws-controllers-k8s/symphony/api/v1alpha1"
)

Expand All @@ -30,6 +32,8 @@ var (
lowerCamelCaseRegex = regexp.MustCompile(`^[a-z][a-zA-Z0-9]*$`)
// UpperCamelCaseRegex
upperCamelCaseRegex = regexp.MustCompile(`^[A-Z][a-zA-Z0-9]*$`)
// kubernetesVersionRegex
kubernetesVersionRegex = regexp.MustCompile(`^v\d+(?:(?:alpha|beta)\d+)?$`)

// reservedKeyWords is a list of reserved words in Symphony.
reservedKeyWords = []string{
Expand Down Expand Up @@ -136,6 +140,17 @@ func validateKubernetesObjectStructure(obj map[string]interface{}) error {
return fmt.Errorf("apiVersion field is not a string")
}

groupVersion, err := schema.ParseGroupVersion(apiVersion.(string))
if err != nil {
return fmt.Errorf("apiVersion field is not a valid Kubernetes group version: %w", err)
}
if groupVersion.Version != "" {
// Only validate the version if it is not empty. Empty version is allowed.
if err := validateKubernetesVersion(groupVersion.Version); err != nil {
return fmt.Errorf("apiVersion field does not have a valid version: %w", err)
}
}

kind, exists := obj["kind"]
if !exists {
return fmt.Errorf("kind field not found")
Expand All @@ -156,3 +171,12 @@ func validateKubernetesObjectStructure(obj map[string]interface{}) error {

return nil
}

// validateKubernetesVersion checks if the given version is a valid Kubernetes
// version. e.g v1, v1alpha1, v1beta1..
func validateKubernetesVersion(version string) error {
if !kubernetesVersionRegex.MatchString(version) {
return fmt.Errorf("version %s is not a valid Kubernetes version", version)
}
return nil
}
37 changes: 37 additions & 0 deletions internal/resourcegroup/graph/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,40 @@ func TestValidateKubernetesObjectStructure(t *testing.T) {
})
}
}

func TestValidateKubernetesVersion(t *testing.T) {
tests := []struct {
version string
shouldPass bool
}{
{"v1", true},
{"v10", true},
{"v1beta1", true},
{"v1beta2", true},
{"v1alpha1", true},
{"v1alpha2", true},
{"v1alpha10", true},
{"v15alpha1", true},
{"v2", true},
{"v", false},
{"vvvv", false},
{"v1.1", false},
{"v1.1.1", false},
{"v1alpha", false},
{"valpha1", false},
{"alpha", false},
{"1alpha", false},
{"v1alpha1beta1", false},
}
for _, tt := range tests {
t.Run(tt.version, func(t *testing.T) {
err := validateKubernetesVersion(tt.version)
if tt.shouldPass && err != nil {
t.Errorf("Expected version %q to be valid, but got error: %v", tt.version, err)
}
if !tt.shouldPass && err == nil {
t.Errorf("Expected version %q to be invalid, but it passed validation", tt.version)
}
})
}
}

0 comments on commit f278272

Please sign in to comment.