mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 14:12:41 +08:00
233 lines
7.2 KiB
Go
233 lines
7.2 KiB
Go
package builder_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana/pkg/services/apiserver/builder"
|
|
"github.com/stretchr/testify/require"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/apiserver/pkg/admission"
|
|
"k8s.io/apiserver/pkg/apis/example"
|
|
)
|
|
|
|
func TestBuilderAdmission_Validate(t *testing.T) {
|
|
gvk := schema.GroupVersionKind{
|
|
Group: "example.grafana.app",
|
|
Version: "v1",
|
|
Kind: "Foo",
|
|
}
|
|
gvr := gvk.GroupVersion().WithResource("foos")
|
|
defaultAttributes := admission.NewAttributesRecord(nil, nil, gvk, "default", "foo", gvr, "", admission.Create, nil, false, nil)
|
|
tests := []struct {
|
|
name string
|
|
validators map[schema.GroupVersion]builder.APIGroupValidation
|
|
attributes admission.Attributes
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "validator exists - forbidden",
|
|
validators: map[schema.GroupVersion]builder.APIGroupValidation{
|
|
gvk.GroupVersion(): &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return admission.NewForbidden(a, errors.New("test error"))
|
|
},
|
|
},
|
|
},
|
|
attributes: defaultAttributes,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "validator exists - allowed",
|
|
validators: map[schema.GroupVersion]builder.APIGroupValidation{
|
|
gvk.GroupVersion(): &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return nil
|
|
},
|
|
},
|
|
},
|
|
attributes: defaultAttributes,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "validator does not exist",
|
|
validators: map[schema.GroupVersion]builder.APIGroupValidation{},
|
|
attributes: defaultAttributes,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "multiple validators",
|
|
validators: map[schema.GroupVersion]builder.APIGroupValidation{
|
|
{Group: "example.grafana.app", Version: "v1beta"}: &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return nil
|
|
},
|
|
},
|
|
gvk.GroupVersion(): &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return admission.NewForbidden(a, errors.New("test error"))
|
|
},
|
|
},
|
|
{Group: "example.grafana.app", Version: "v2"}: &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return nil
|
|
},
|
|
},
|
|
},
|
|
attributes: defaultAttributes,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
b := builder.NewAdmission(nil, tt.validators)
|
|
err := b.Validate(context.Background(), tt.attributes, nil)
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewAdmissionFromBuilders(t *testing.T) {
|
|
gvk := schema.GroupVersionKind{
|
|
Group: "example.grafana.app",
|
|
Version: "v1",
|
|
Kind: "Foo",
|
|
}
|
|
gvr := gvk.GroupVersion().WithResource("foos")
|
|
defaultAttributes := admission.NewAttributesRecord(nil, nil, gvk, "default", "foo", gvr, "", admission.Create, nil, false, nil)
|
|
|
|
builders := []builder.APIGroupBuilder{
|
|
&mockBuilder{
|
|
groupVersion: schema.GroupVersion{Group: "example.grafana.app", Version: "v1beta"},
|
|
validator: &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return nil
|
|
},
|
|
},
|
|
},
|
|
&mockBuilder{
|
|
groupVersion: gvk.GroupVersion(),
|
|
validator: &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return admission.NewForbidden(a, errors.New("test error"))
|
|
},
|
|
},
|
|
},
|
|
&mockBuilder{
|
|
groupVersion: schema.GroupVersion{Group: "example.grafana.app", Version: "v2"},
|
|
validator: &mockValidator{
|
|
validateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return nil
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
a := builder.NewAdmissionFromBuilders(builders)
|
|
err := a.Validate(context.Background(), defaultAttributes, nil)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestBuilderAdmission_Admit(t *testing.T) {
|
|
gvk := schema.GroupVersionKind{
|
|
Group: "test.grafana.app",
|
|
Version: "v1",
|
|
Kind: "Foo",
|
|
}
|
|
gvr := gvk.GroupVersion().WithResource("foos")
|
|
exampleObj := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: example.PodSpec{}}
|
|
tests := []struct {
|
|
name string
|
|
mutators map[schema.GroupVersion]builder.APIGroupMutation
|
|
attributes admission.Attributes
|
|
wantErr bool
|
|
wantSpec example.PodSpec
|
|
}{
|
|
{
|
|
name: "mutator exists - error",
|
|
mutators: map[schema.GroupVersion]builder.APIGroupMutation{
|
|
gvk.GroupVersion(): &mockMutator{
|
|
mutateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return errors.New("test error")
|
|
},
|
|
},
|
|
},
|
|
attributes: admission.NewAttributesRecord(exampleObj.DeepCopy(), nil, gvk, "default", "foo", gvr, "", admission.Create, nil, false, nil),
|
|
wantErr: true,
|
|
wantSpec: exampleObj.Spec,
|
|
},
|
|
{
|
|
name: "mutator exists - add hostname",
|
|
mutators: map[schema.GroupVersion]builder.APIGroupMutation{
|
|
gvk.GroupVersion(): &mockMutator{
|
|
mutateFunc: func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
obj := a.GetObject().(*example.Pod)
|
|
obj.Spec.Hostname = "test"
|
|
return nil
|
|
},
|
|
},
|
|
},
|
|
attributes: admission.NewAttributesRecord(exampleObj.DeepCopy(), nil, gvk, "default", "foo", gvr, "", admission.Create, nil, false, nil),
|
|
wantErr: false,
|
|
wantSpec: example.PodSpec{Hostname: "test"},
|
|
},
|
|
{
|
|
name: "mutator does not exist",
|
|
mutators: map[schema.GroupVersion]builder.APIGroupMutation{},
|
|
attributes: admission.NewAttributesRecord(exampleObj.DeepCopy(), nil, gvk, "default", "foo", gvr, "", admission.Create, nil, false, nil),
|
|
wantErr: false,
|
|
wantSpec: exampleObj.Spec,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
b := builder.NewAdmission(tt.mutators, nil)
|
|
err := b.Admit(context.Background(), tt.attributes, nil)
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
require.Equal(t, tt.wantSpec, tt.attributes.GetObject().(*example.Pod).Spec)
|
|
})
|
|
}
|
|
}
|
|
|
|
type mockBuilder struct {
|
|
builder.APIGroupBuilder
|
|
groupVersion schema.GroupVersion
|
|
validator builder.APIGroupValidation
|
|
}
|
|
|
|
func (m *mockBuilder) GetGroupVersions() []schema.GroupVersion {
|
|
return []schema.GroupVersion{m.groupVersion}
|
|
}
|
|
|
|
func (m *mockBuilder) Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return m.validator.Validate(ctx, a, o)
|
|
}
|
|
|
|
type mockMutator struct {
|
|
mutateFunc func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error
|
|
}
|
|
|
|
func (m *mockMutator) Mutate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return m.mutateFunc(ctx, a, o)
|
|
}
|
|
|
|
type mockValidator struct {
|
|
validateFunc func(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error
|
|
}
|
|
|
|
func (m *mockValidator) Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
|
return m.validateFunc(ctx, a, o)
|
|
}
|