resource-api: Loosen name validation to match K8s requirements (#93404)

* resource-api: Loosen name validation to match K8s requirements

This patch modifies some of the requirements for name validation of
objects in Resource API to match Kubernetes.

The limit we have on characters in name is 64, but some resources allow
upto 253 characters. Similarly we also include `:` in the regex, as many
objects in default K8s setup use it in the name (the group
`system:masters` for example)

Signed-off-by: Prem Kumar <prem.saraswat@grafana.com>

* Update the name column length in migrator and update e2e test to verify

---------

Signed-off-by: Prem Kumar <prem.saraswat@grafana.com>
dash-schema-experiments-zod
Prem Saraswat 8 months ago committed by GitHub
parent 21d26de4d8
commit 5c03c14b25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      pkg/storage/unified/resource/validation.go
  2. 8
      pkg/storage/unified/resource/validation_test.go
  3. 4
      pkg/storage/unified/sql/db/migrations/resource_mig.go
  4. 20
      pkg/tests/apis/scopes/scopes_test.go
  5. 14
      pkg/tests/apis/scopes/testdata/example-scope3.yaml

@ -4,14 +4,14 @@ import (
"regexp"
)
var validNameCharPattern = `a-zA-Z0-9\-\_\.`
var validNameCharPattern = `a-zA-Z0-9:\-\_\.`
var validNamePattern = regexp.MustCompile(`^[` + validNameCharPattern + `]*$`).MatchString
func validateName(name string) *ErrorResult {
if len(name) == 0 {
return NewBadRequestError("name is too short")
}
if len(name) > 64 {
if len(name) > 253 {
return NewBadRequestError("name is too long")
}
if !validNamePattern(name) {

@ -1,22 +1,22 @@
package resource
import (
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func TestNameValidation(t *testing.T) {
require.NotNil(t, validateName("")) // too short
require.NotNil(t, validateName( // too long (max 64)
"0123456789012345678901234567890123456789012345678901234567890123456789",
))
require.NotNil(t, validateName("")) // too short
require.NotNil(t, validateName(strings.Repeat("0", 254))) // too long (max 253)
// OK
require.Nil(t, validateName("a"))
require.Nil(t, validateName("hello-world"))
require.Nil(t, validateName("hello.world"))
require.Nil(t, validateName("hello_world"))
require.Nil(t, validateName("hello:world"))
// Bad characters
require.NotNil(t, validateName("hello world"))

@ -22,7 +22,7 @@ func initResourceTables(mg *migrator.Migrator) string {
{Name: "group", Type: migrator.DB_NVarchar, Length: 190, Nullable: false},
{Name: "resource", Type: migrator.DB_NVarchar, Length: 190, Nullable: false},
{Name: "namespace", Type: migrator.DB_NVarchar, Length: 63, Nullable: false},
{Name: "name", Type: migrator.DB_NVarchar, Length: 190, Nullable: false},
{Name: "name", Type: migrator.DB_NVarchar, Length: 253, Nullable: false},
{Name: "value", Type: migrator.DB_LongText, Nullable: true},
{Name: "action", Type: migrator.DB_Int, Nullable: false}, // 1: create, 2: update, 3: delete
@ -44,7 +44,7 @@ func initResourceTables(mg *migrator.Migrator) string {
{Name: "group", Type: migrator.DB_NVarchar, Length: 190, Nullable: false},
{Name: "resource", Type: migrator.DB_NVarchar, Length: 190, Nullable: false},
{Name: "namespace", Type: migrator.DB_NVarchar, Length: 63, Nullable: false},
{Name: "name", Type: migrator.DB_NVarchar, Length: 190, Nullable: false},
{Name: "name", Type: migrator.DB_NVarchar, Length: 253, Nullable: false},
{Name: "value", Type: migrator.DB_LongText, Nullable: true},
{Name: "action", Type: migrator.DB_Int, Nullable: false}, // 1: create, 2: update, 3: delete

@ -3,6 +3,7 @@ package scopes
import (
"context"
"encoding/json"
"strings"
"testing"
"github.com/stretchr/testify/require"
@ -159,6 +160,25 @@ func TestIntegrationScopes(t *testing.T) {
)
require.NoError(t, err)
// Name length test
scope3 := helper.LoadYAMLOrJSONFile("testdata/example-scope3.yaml")
// Name too long (>253)
scope3.SetName(strings.Repeat("0", 254))
_, err = scopeClient.Resource.Create(ctx,
scope3,
createOptions,
)
require.Error(t, err)
// Maximum allowed length for name (253)
scope3.SetName(strings.Repeat("0", 253))
_, err = scopeClient.Resource.Create(ctx,
scope3,
createOptions,
)
require.NoError(t, err)
// Field Selector test
found, err := scopeClient.Resource.List(ctx, metav1.ListOptions{
FieldSelector: "spec.title=foo-scope",

@ -0,0 +1,14 @@
apiVersion: scope.grafana.app/v0alpha1
kind: Scope
metadata:
name: example-long
spec:
title: baz-scope
description: Longer description for a scope
filters:
- key: aaa
operator: equals
value: eee
- key: ccc
operator: not-equals
value: fff
Loading…
Cancel
Save