mirror of https://github.com/grafana/grafana
K8s: Dashboards: Add deletion validation for provisioned dashboards (#98504)
parent
ce512862f7
commit
5ed2a4c624
@ -0,0 +1,160 @@ |
||||
package dashboard |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"testing" |
||||
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" |
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" |
||||
"github.com/grafana/grafana/pkg/services/dashboards" |
||||
"github.com/grafana/grafana/pkg/services/user" |
||||
"github.com/stretchr/testify/mock" |
||||
"github.com/stretchr/testify/require" |
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||
"k8s.io/apiserver/pkg/admission" |
||||
) |
||||
|
||||
func TestDashboardAPIBuilder_Validate(t *testing.T) { |
||||
oneInt64 := int64(1) |
||||
zeroInt64 := int64(0) |
||||
tests := []struct { |
||||
name string |
||||
inputObj *v0alpha1.Dashboard |
||||
deletionOptions metav1.DeleteOptions |
||||
dashboardResponse *dashboards.DashboardProvisioning |
||||
dashboardErrorResponse error |
||||
checkRan bool |
||||
expectedError bool |
||||
}{ |
||||
{ |
||||
name: "should return an error if data is found", |
||||
inputObj: &v0alpha1.Dashboard{ |
||||
Spec: common.Unstructured{}, |
||||
TypeMeta: metav1.TypeMeta{ |
||||
Kind: "Dashboard", |
||||
}, |
||||
ObjectMeta: metav1.ObjectMeta{ |
||||
Name: "test", |
||||
}, |
||||
}, |
||||
deletionOptions: metav1.DeleteOptions{ |
||||
GracePeriodSeconds: nil, |
||||
}, |
||||
dashboardResponse: &dashboards.DashboardProvisioning{ID: 1}, |
||||
dashboardErrorResponse: nil, |
||||
checkRan: true, |
||||
expectedError: true, |
||||
}, |
||||
{ |
||||
name: "should return an error if unable to check", |
||||
inputObj: &v0alpha1.Dashboard{ |
||||
Spec: common.Unstructured{}, |
||||
TypeMeta: metav1.TypeMeta{ |
||||
Kind: "Dashboard", |
||||
}, |
||||
ObjectMeta: metav1.ObjectMeta{ |
||||
Name: "test", |
||||
}, |
||||
}, |
||||
deletionOptions: metav1.DeleteOptions{ |
||||
GracePeriodSeconds: nil, |
||||
}, |
||||
dashboardResponse: nil, |
||||
dashboardErrorResponse: fmt.Errorf("generic error"), |
||||
checkRan: true, |
||||
expectedError: true, |
||||
}, |
||||
{ |
||||
name: "should be okay if error is provisioned dashboard not found", |
||||
inputObj: &v0alpha1.Dashboard{ |
||||
Spec: common.Unstructured{}, |
||||
TypeMeta: metav1.TypeMeta{ |
||||
Kind: "Dashboard", |
||||
}, |
||||
ObjectMeta: metav1.ObjectMeta{ |
||||
Name: "test", |
||||
}, |
||||
}, |
||||
deletionOptions: metav1.DeleteOptions{ |
||||
GracePeriodSeconds: nil, |
||||
}, |
||||
dashboardResponse: nil, |
||||
dashboardErrorResponse: dashboards.ErrProvisionedDashboardNotFound, |
||||
checkRan: true, |
||||
expectedError: false, |
||||
}, |
||||
{ |
||||
name: "Should still run the check for delete if grace period is not 0", |
||||
inputObj: &v0alpha1.Dashboard{ |
||||
Spec: common.Unstructured{}, |
||||
TypeMeta: metav1.TypeMeta{ |
||||
Kind: "Dashboard", |
||||
}, |
||||
ObjectMeta: metav1.ObjectMeta{ |
||||
Name: "test", |
||||
}, |
||||
}, |
||||
deletionOptions: metav1.DeleteOptions{ |
||||
GracePeriodSeconds: &oneInt64, |
||||
}, |
||||
dashboardResponse: nil, |
||||
dashboardErrorResponse: nil, |
||||
checkRan: true, |
||||
expectedError: false, |
||||
}, |
||||
{ |
||||
name: "should not run the check for delete if grace period is set to 0", |
||||
inputObj: &v0alpha1.Dashboard{ |
||||
Spec: common.Unstructured{}, |
||||
TypeMeta: metav1.TypeMeta{ |
||||
Kind: "Dashboard", |
||||
}, |
||||
ObjectMeta: metav1.ObjectMeta{ |
||||
Name: "test", |
||||
}, |
||||
}, |
||||
deletionOptions: metav1.DeleteOptions{ |
||||
GracePeriodSeconds: &zeroInt64, |
||||
}, |
||||
dashboardResponse: nil, |
||||
dashboardErrorResponse: nil, |
||||
checkRan: false, |
||||
expectedError: false, |
||||
}, |
||||
} |
||||
for _, tt := range tests { |
||||
t.Run(tt.name, func(t *testing.T) { |
||||
fakeService := &dashboards.FakeDashboardProvisioning{} |
||||
fakeService.On("GetProvisionedDashboardDataByDashboardUID", mock.Anything, mock.Anything, mock.Anything).Return(tt.dashboardResponse, tt.dashboardErrorResponse).Once() |
||||
b := &DashboardsAPIBuilder{ |
||||
ProvisioningDashboardService: fakeService, |
||||
} |
||||
err := b.Validate(context.Background(), admission.NewAttributesRecord( |
||||
tt.inputObj, |
||||
nil, |
||||
v0alpha1.DashboardResourceInfo.GroupVersionKind(), |
||||
"stacks-123", |
||||
tt.inputObj.Name, |
||||
v0alpha1.DashboardResourceInfo.GroupVersionResource(), |
||||
"", |
||||
admission.Operation("DELETE"), |
||||
&tt.deletionOptions, |
||||
true, |
||||
&user.SignedInUser{}, |
||||
), nil) |
||||
|
||||
if tt.expectedError { |
||||
require.Error(t, err) |
||||
} else { |
||||
require.NoError(t, err) |
||||
} |
||||
|
||||
if tt.checkRan { |
||||
fakeService.AssertCalled(t, "GetProvisionedDashboardDataByDashboardUID", mock.Anything, mock.Anything, mock.Anything) |
||||
} else { |
||||
fakeService.AssertNotCalled(t, "GetProvisionedDashboardDataByDashboardUID", mock.Anything, mock.Anything, mock.Anything) |
||||
} |
||||
}) |
||||
} |
||||
} |
Loading…
Reference in new issue