Unistore: Add validation for resource names (#110990)
* Unistore: Add validation for resource names Signed-off-by: Maicon Costa <maiconscosta@gmail.com> --------- Signed-off-by: Maicon Costa <maiconscosta@gmail.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -195,6 +196,202 @@ func TestSimpleServer(t *testing.T) {
|
||||
require.Len(t, all.Items, 0) // empty
|
||||
})
|
||||
|
||||
t.Run("playlist FAIL CRUD paths due to invalid key", func(t *testing.T) {
|
||||
raw := []byte(`{
|
||||
"apiVersion": "playlist.grafana.app/v0alpha1",
|
||||
"kind": "Playlist",
|
||||
"metadata": {
|
||||
"name": "fdgsv37#qslr0ga",
|
||||
"uid": "xyz",
|
||||
"namespace": "default",
|
||||
"annotations": {
|
||||
"grafana.app/repoName": "elsewhere",
|
||||
"grafana.app/repoPath": "path/to/item",
|
||||
"grafana.app/repoTimestamp": "2024-02-02T00:00:00Z"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"title": "hello",
|
||||
"interval": "5m",
|
||||
"items": [
|
||||
{
|
||||
"type": "dashboard_by_uid",
|
||||
"value": "vmie2cmWz"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
|
||||
// invalid group
|
||||
key := &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app###",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "fdgsv37qslr0ga",
|
||||
}
|
||||
|
||||
created, err := server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.Nil(t, created)
|
||||
|
||||
// invalid resource
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr###", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "fdgsv37qslr0ga",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.Nil(t, created)
|
||||
|
||||
// invalid namespace
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default###",
|
||||
Name: "fdgsv37qslr0ga",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.Nil(t, created)
|
||||
|
||||
// invalid name
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "fdgsv37qslr0g###",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.Nil(t, created)
|
||||
|
||||
// legacy name - valid
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "2c7e5361-7360-4d2a-ae45-5e79bba458d6",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, created)
|
||||
|
||||
// legacy name - also valid
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "IvIsO_YGz",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, created)
|
||||
|
||||
// legacy name - also valid
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "_IvIsOYGz",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, created)
|
||||
|
||||
invalidQualifiedNames := []string{
|
||||
"", // empty
|
||||
strings.Repeat("1", MaxQualifiedNameLength+1), // too long
|
||||
" ", // only spaces
|
||||
"f8cc010c.ee72.4681;89d2+d46e1bd47d33", // invalid chars
|
||||
}
|
||||
|
||||
// group
|
||||
for _, invalidGroup := range invalidQualifiedNames {
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: invalidGroup,
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "_IvIsOYGz",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
|
||||
require.Error(t, err)
|
||||
require.Nil(t, created)
|
||||
}
|
||||
|
||||
// resource
|
||||
for _, invalidResource := range invalidQualifiedNames {
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: invalidResource,
|
||||
Namespace: "default",
|
||||
Name: "_IvIsOYGz",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
|
||||
require.Error(t, err)
|
||||
require.Nil(t, created)
|
||||
}
|
||||
|
||||
// namespace
|
||||
for _, invalidNamespace := range invalidQualifiedNames {
|
||||
key = &resourcepb.ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: invalidNamespace,
|
||||
Name: "_IvIsOYGz",
|
||||
}
|
||||
|
||||
created, err = server.Create(ctx, &resourcepb.CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
|
||||
require.Error(t, err)
|
||||
require.Nil(t, created)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("playlist update optimistic concurrency check", func(t *testing.T) {
|
||||
raw := []byte(`{
|
||||
"apiVersion": "playlist.grafana.app/v0alpha1",
|
||||
|
||||
Reference in New Issue
Block a user