@ -321,6 +321,362 @@ func TestIntegrationAlertRulePermissions(t *testing.T) {
} )
}
func TestIntegrationAlertRuleNestedPermissions ( t * testing . T ) {
testinfra . SQLiteIntegrationTest ( t )
// Setup Grafana and its Database
dir , p := testinfra . CreateGrafDir ( t , testinfra . GrafanaOpts {
EnableFeatureToggles : [ ] string { featuremgmt . FlagNestedFolders } ,
DisableLegacyAlerting : true ,
EnableUnifiedAlerting : true ,
DisableAnonymous : true ,
AppModeProduction : true ,
} )
grafanaListedAddr , store := testinfra . StartGrafana ( t , dir , p )
permissionsStore := resourcepermissions . NewStore ( store , featuremgmt . WithFeatures ( ) )
// Create a user to make authenticated requests
userID := createUser ( t , store , user . CreateUserCommand {
DefaultOrgRole : string ( org . RoleEditor ) ,
Password : "password" ,
Login : "grafana" ,
} )
apiClient := newAlertingApiClient ( grafanaListedAddr , "grafana" , "password" )
// Create the namespace we'll save our alerts to.
apiClient . CreateFolder ( t , "folder1" , "folder1" )
// Create the namespace we'll save our alerts to.
apiClient . CreateFolder ( t , "folder2" , "folder2" )
// Create a subfolder
apiClient . CreateFolder ( t , "subfolder" , "subfolder" , "folder1" )
postGroupRaw , err := testData . ReadFile ( path . Join ( "test-data" , "rulegroup-1-post.json" ) )
require . NoError ( t , err )
var group1 apimodels . PostableRuleGroupConfig
require . NoError ( t , json . Unmarshal ( postGroupRaw , & group1 ) )
// Create rule under folder1
_ , status , response := apiClient . PostRulesGroupWithStatus ( t , "folder1" , & group1 )
require . Equalf ( t , http . StatusAccepted , status , response )
postGroupRaw , err = testData . ReadFile ( path . Join ( "test-data" , "rulegroup-2-post.json" ) )
require . NoError ( t , err )
var group2 apimodels . PostableRuleGroupConfig
require . NoError ( t , json . Unmarshal ( postGroupRaw , & group2 ) )
// Create rule under folder2
_ , status , response = apiClient . PostRulesGroupWithStatus ( t , "folder2" , & group2 )
require . Equalf ( t , http . StatusAccepted , status , response )
postGroupRaw , err = testData . ReadFile ( path . Join ( "test-data" , "rulegroup-3-post.json" ) )
require . NoError ( t , err )
var group3 apimodels . PostableRuleGroupConfig
require . NoError ( t , json . Unmarshal ( postGroupRaw , & group3 ) )
// Create rule under subfolder
_ , status , response = apiClient . PostRulesGroupWithStatus ( t , "subfolder" , & group3 )
require . Equalf ( t , http . StatusAccepted , status , response )
// With the rules created, let's make sure that rule definitions are stored.
allRules , status , _ := apiClient . GetAllRulesWithStatus ( t )
require . Equal ( t , http . StatusOK , status )
status , allExportRaw := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
} )
require . Equal ( t , http . StatusOK , status )
var allExport apimodels . AlertingFileExport
require . NoError ( t , json . Unmarshal ( [ ] byte ( allExportRaw ) , & allExport ) )
t . Run ( "when user has all permissions" , func ( t * testing . T ) {
t . Run ( "Get all returns all rules" , func ( t * testing . T ) {
var group1 , group2 , group3 apimodels . GettableRuleGroupConfig
getGroup1Raw , err := testData . ReadFile ( path . Join ( "test-data" , "rulegroup-1-get.json" ) )
require . NoError ( t , err )
require . NoError ( t , json . Unmarshal ( getGroup1Raw , & group1 ) )
getGroup2Raw , err := testData . ReadFile ( path . Join ( "test-data" , "rulegroup-2-get.json" ) )
require . NoError ( t , err )
require . NoError ( t , json . Unmarshal ( getGroup2Raw , & group2 ) )
getGroup3Raw , err := testData . ReadFile ( path . Join ( "test-data" , "rulegroup-3-get.json" ) )
require . NoError ( t , err )
require . NoError ( t , json . Unmarshal ( getGroup3Raw , & group3 ) )
nestedKey := ngmodels . GetNamespaceKey ( "folder1" , "subfolder" )
expected := apimodels . NamespaceConfigResponse {
"folder1" : [ ] apimodels . GettableRuleGroupConfig {
group1 ,
} ,
"folder2" : [ ] apimodels . GettableRuleGroupConfig {
group2 ,
} ,
nestedKey : [ ] apimodels . GettableRuleGroupConfig {
group3 ,
} ,
}
pathsToIgnore := [ ] string {
"GrafanaManagedAlert.Updated" ,
"GrafanaManagedAlert.UID" ,
"GrafanaManagedAlert.ID" ,
"GrafanaManagedAlert.Data.Model" ,
"GrafanaManagedAlert.NamespaceUID" ,
"GrafanaManagedAlert.NamespaceID" ,
}
// compare expected and actual and ignore the dynamic fields
diff := cmp . Diff ( expected , allRules , cmp . FilterPath ( func ( path cmp . Path ) bool {
for _ , s := range pathsToIgnore {
if strings . Contains ( path . String ( ) , s ) {
return true
}
}
return false
} , cmp . Ignore ( ) ) )
require . Empty ( t , diff )
for _ , rule := range allRules [ "folder1" ] [ 0 ] . Rules {
assert . Equal ( t , "folder1" , rule . GrafanaManagedAlert . NamespaceUID )
}
for _ , rule := range allRules [ "folder2" ] [ 0 ] . Rules {
assert . Equal ( t , "folder2" , rule . GrafanaManagedAlert . NamespaceUID )
}
for _ , rule := range allRules [ nestedKey ] [ 0 ] . Rules {
assert . Equal ( t , "subfolder" , rule . GrafanaManagedAlert . NamespaceUID )
}
} )
t . Run ( "Get by folder returns groups in folder" , func ( t * testing . T ) {
rules , status , _ := apiClient . GetAllRulesGroupInFolderWithStatus ( t , "folder1" )
require . Equal ( t , http . StatusAccepted , status )
require . Contains ( t , rules , "folder1" )
require . Len ( t , rules [ "folder1" ] , 1 )
require . Equal ( t , allRules [ "folder1" ] , rules [ "folder1" ] )
} )
t . Run ( "Get group returns a single group" , func ( t * testing . T ) {
rules := apiClient . GetRulesGroup ( t , "folder2" , allRules [ "folder2" ] [ 0 ] . Name )
cmp . Diff ( allRules [ "folder2" ] [ 0 ] , rules . GettableRuleGroupConfig )
} )
t . Run ( "Get by folder returns groups in folder with nested folder format" , func ( t * testing . T ) {
rules , status , _ := apiClient . GetAllRulesGroupInFolderWithStatus ( t , "subfolder" )
require . Equal ( t , http . StatusAccepted , status )
nestedKey := ngmodels . GetNamespaceKey ( "folder1" , "subfolder" )
require . Contains ( t , rules , nestedKey )
require . Len ( t , rules [ nestedKey ] , 1 )
require . Equal ( t , allRules [ nestedKey ] , rules [ nestedKey ] )
} )
t . Run ( "Export returns all rules" , func ( t * testing . T ) {
var group1File , group2File , group3File apimodels . AlertingFileExport
getGroup1Raw , err := testData . ReadFile ( path . Join ( "test-data" , "rulegroup-1-export.json" ) )
require . NoError ( t , err )
require . NoError ( t , json . Unmarshal ( getGroup1Raw , & group1File ) )
getGroup2Raw , err := testData . ReadFile ( path . Join ( "test-data" , "rulegroup-2-export.json" ) )
require . NoError ( t , err )
require . NoError ( t , json . Unmarshal ( getGroup2Raw , & group2File ) )
getGroup3Raw , err := testData . ReadFile ( path . Join ( "test-data" , "rulegroup-3-export.json" ) )
require . NoError ( t , err )
require . NoError ( t , json . Unmarshal ( getGroup3Raw , & group3File ) )
group1File . Groups = append ( group1File . Groups , group2File . Groups ... )
group1File . Groups = append ( group1File . Groups , group3File . Groups ... )
expected := group1File
pathsToIgnore := [ ] string {
"Groups.Rules.UID" ,
"Groups.Folder" ,
}
// compare expected and actual and ignore the dynamic fields
diff := cmp . Diff ( expected , allExport , cmp . FilterPath ( func ( path cmp . Path ) bool {
for _ , s := range pathsToIgnore {
if strings . Contains ( path . String ( ) , s ) {
return true
}
}
return false
} , cmp . Ignore ( ) ) )
require . Empty ( t , diff )
require . Equal ( t , "folder1" , allExport . Groups [ 0 ] . Folder )
require . Equal ( t , "folder2" , allExport . Groups [ 1 ] . Folder )
require . Equal ( t , "subfolder" , allExport . Groups [ 2 ] . Folder )
} )
t . Run ( "Export from one folder" , func ( t * testing . T ) {
expected := allExport . Groups [ 0 ]
status , exportRaw := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
FolderUID : [ ] string { "folder1" } ,
} )
require . Equal ( t , http . StatusOK , status )
var export apimodels . AlertingFileExport
require . NoError ( t , json . Unmarshal ( [ ] byte ( exportRaw ) , & export ) )
require . Len ( t , export . Groups , 1 )
require . Equal ( t , expected , export . Groups [ 0 ] )
} )
t . Run ( "Export from a subfolder" , func ( t * testing . T ) {
expected := allExport . Groups [ 2 ]
status , exportRaw := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
FolderUID : [ ] string { "subfolder" } ,
} )
require . Equal ( t , http . StatusOK , status )
var export apimodels . AlertingFileExport
require . NoError ( t , json . Unmarshal ( [ ] byte ( exportRaw ) , & export ) )
require . Len ( t , export . Groups , 1 )
require . Equal ( t , expected , export . Groups [ 0 ] )
} )
t . Run ( "Export from one group" , func ( t * testing . T ) {
expected := allExport . Groups [ 0 ]
status , exportRaw := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
FolderUID : [ ] string { "folder1" } ,
GroupName : expected . Name ,
} )
require . Equal ( t , http . StatusOK , status )
var export apimodels . AlertingFileExport
require . NoError ( t , json . Unmarshal ( [ ] byte ( exportRaw ) , & export ) )
require . Len ( t , export . Groups , 1 )
require . Equal ( t , expected , export . Groups [ 0 ] )
} )
t . Run ( "Export from one group under subfolder" , func ( t * testing . T ) {
expected := allExport . Groups [ 2 ]
status , exportRaw := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
FolderUID : [ ] string { "subfolder" } ,
GroupName : expected . Name ,
} )
require . Equal ( t , http . StatusOK , status )
var export apimodels . AlertingFileExport
require . NoError ( t , json . Unmarshal ( [ ] byte ( exportRaw ) , & export ) )
require . Len ( t , export . Groups , 1 )
require . Equal ( t , expected , export . Groups [ 0 ] )
} )
t . Run ( "Export single rule" , func ( t * testing . T ) {
expected := allExport . Groups [ 0 ]
expected . Rules = [ ] apimodels . AlertRuleExport {
expected . Rules [ 0 ] ,
}
status , exportRaw := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
RuleUID : expected . Rules [ 0 ] . UID ,
} )
require . Equal ( t , http . StatusOK , status )
var export apimodels . AlertingFileExport
t . Log ( exportRaw )
require . NoError ( t , json . Unmarshal ( [ ] byte ( exportRaw ) , & export ) )
require . Len ( t , export . Groups , 1 )
require . Equal ( t , expected , export . Groups [ 0 ] )
} )
} )
t . Run ( "when permissions for folder2 removed" , func ( t * testing . T ) {
// remove permissions for folder2
removeFolderPermission ( t , permissionsStore , 1 , userID , org . RoleEditor , "folder2" )
// remove permissions for subfolder (inherits from folder1)
removeFolderPermission ( t , permissionsStore , 1 , userID , org . RoleEditor , "subfolder" )
apiClient . ReloadCachedPermissions ( t )
t . Run ( "Get all returns all rules" , func ( t * testing . T ) {
newAll , status , _ := apiClient . GetAllRulesWithStatus ( t )
require . Equal ( t , http . StatusOK , status )
require . Contains ( t , newAll , "folder1" )
require . NotContains ( t , newAll , "folder2" )
require . Contains ( t , newAll , ngmodels . GetNamespaceKey ( "folder1" , "subfolder" ) )
} )
t . Run ( "Get by folder returns groups in folder" , func ( t * testing . T ) {
_ , status , _ := apiClient . GetAllRulesGroupInFolderWithStatus ( t , "folder2" )
require . Equal ( t , http . StatusForbidden , status )
} )
t . Run ( "Get group returns a single group" , func ( t * testing . T ) {
u := fmt . Sprintf ( "%s/api/ruler/grafana/api/v1/rules/folder2/arulegroup" , apiClient . url )
// nolint:gosec
resp , err := http . Get ( u )
require . NoError ( t , err )
defer func ( ) {
_ = resp . Body . Close ( )
} ( )
assert . Equal ( t , http . StatusForbidden , resp . StatusCode )
} )
t . Run ( "Export returns all rules" , func ( t * testing . T ) {
status , exportRaw := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
} )
require . Equal ( t , http . StatusOK , status )
var export apimodels . AlertingFileExport
require . NoError ( t , json . Unmarshal ( [ ] byte ( exportRaw ) , & export ) )
require . Equal ( t , http . StatusOK , status )
require . Len ( t , export . Groups , 2 )
require . Equal ( t , "folder1" , export . Groups [ 0 ] . Folder )
require . Equal ( t , "subfolder" , export . Groups [ 1 ] . Folder )
} )
t . Run ( "Export from one folder" , func ( t * testing . T ) {
status , _ := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
FolderUID : [ ] string { "folder2" } ,
} )
assert . Equal ( t , http . StatusForbidden , status )
} )
t . Run ( "Export from one group" , func ( t * testing . T ) {
status , _ := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
FolderUID : [ ] string { "folder2" } ,
GroupName : "arulegroup" ,
} )
assert . Equal ( t , http . StatusForbidden , status )
} )
t . Run ( "Export single rule" , func ( t * testing . T ) {
uid := allRules [ "folder2" ] [ 0 ] . Rules [ 0 ] . GrafanaManagedAlert . UID
status , _ := apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
RuleUID : uid ,
} )
require . Equal ( t , http . StatusForbidden , status )
} )
t . Run ( "when all permissions are revoked" , func ( t * testing . T ) {
removeFolderPermission ( t , permissionsStore , 1 , userID , org . RoleEditor , "folder1" )
apiClient . ReloadCachedPermissions ( t )
rules , status , _ := apiClient . GetAllRulesWithStatus ( t )
require . Equal ( t , http . StatusOK , status )
require . Empty ( t , rules )
status , _ = apiClient . ExportRulesWithStatus ( t , & apimodels . AlertRulesExportParameters {
ExportQueryParams : apimodels . ExportQueryParams { Format : "json" } ,
} )
require . Equal ( t , http . StatusNotFound , status )
} )
} )
}
func createRule ( t * testing . T , client apiClient , folder string ) ( apimodels . PostableRuleGroupConfig , string ) {
t . Helper ( )
@ -895,19 +1251,21 @@ func TestIntegrationRuleGroupSequence(t *testing.T) {
} )
client := newAlertingApiClient ( grafanaListedAddr , "grafana" , "password" )
folder1Title := "folder1"
client . CreateFolder ( t , util . GenerateShortUID ( ) , folder1Title )
parentFolderUID := util . GenerateShortUID ( )
client . CreateFolder ( t , parentFolderUID , "parent" )
folderUID := util . GenerateShortUID ( )
client . CreateFolder ( t , folderUID , "folder1" , parentFolderUID )
group1 := generateAlertRuleGroup ( 5 , alertRuleGen ( ) )
group2 := generateAlertRuleGroup ( 5 , alertRuleGen ( ) )
_ , status , _ := client . PostRulesGroupWithStatus ( t , folder1Title , & group1 )
_ , status , _ := client . PostRulesGroupWithStatus ( t , folderUID , & group1 )
require . Equal ( t , http . StatusAccepted , status )
_ , status , _ = client . PostRulesGroupWithStatus ( t , folder1Title , & group2 )
_ , status , _ = client . PostRulesGroupWithStatus ( t , folderUID , & group2 )
require . Equal ( t , http . StatusAccepted , status )
t . Run ( "should persist order of the rules in a group" , func ( t * testing . T ) {
group1Get := client . GetRulesGroup ( t , folder1Title , group1 . Name )
group1Get := client . GetRulesGroup ( t , folderUID , group1 . Name )
assert . Equal ( t , group1 . Name , group1Get . Name )
assert . Equal ( t , group1 . Interval , group1Get . Interval )
assert . Len ( t , group1Get . Rules , len ( group1 . Rules ) )
@ -926,10 +1284,10 @@ func TestIntegrationRuleGroupSequence(t *testing.T) {
for _ , rule := range postableGroup1 . Rules {
expectedUids = append ( expectedUids , rule . GrafanaManagedAlert . UID )
}
_ , status , _ := client . PostRulesGroupWithStatus ( t , folder1Title , & postableGroup1 )
_ , status , _ := client . PostRulesGroupWithStatus ( t , folderUID , & postableGroup1 )
require . Equal ( t , http . StatusAccepted , status )
group1Get = client . GetRulesGroup ( t , folder1Title , group1 . Name )
group1Get = client . GetRulesGroup ( t , folderUID , group1 . Name )
require . Len ( t , group1Get . Rules , len ( postableGroup1 . Rules ) )
@ -941,8 +1299,8 @@ func TestIntegrationRuleGroupSequence(t *testing.T) {
} )
t . Run ( "should be able to move a rule from another group in a specific position" , func ( t * testing . T ) {
group1Get := client . GetRulesGroup ( t , folder1Title , group1 . Name )
group2Get := client . GetRulesGroup ( t , folder1Title , group2 . Name )
group1Get := client . GetRulesGroup ( t , folderUID , group1 . Name )
group2Get := client . GetRulesGroup ( t , folderUID , group2 . Name )
movedRule := convertGettableRuleToPostable ( group2Get . Rules [ 3 ] )
// now shuffle the rules
@ -952,10 +1310,10 @@ func TestIntegrationRuleGroupSequence(t *testing.T) {
for _ , rule := range postableGroup1 . Rules {
expectedUids = append ( expectedUids , rule . GrafanaManagedAlert . UID )
}
_ , status , _ := client . PostRulesGroupWithStatus ( t , folder1Title , & postableGroup1 )
_ , status , _ := client . PostRulesGroupWithStatus ( t , folderUID , & postableGroup1 )
require . Equal ( t , http . StatusAccepted , status )
group1Get = client . GetRulesGroup ( t , folder1Title , group1 . Name )
group1Get = client . GetRulesGroup ( t , folderUID , group1 . Name )
require . Len ( t , group1Get . Rules , len ( postableGroup1 . Rules ) )
@ -965,7 +1323,7 @@ func TestIntegrationRuleGroupSequence(t *testing.T) {
}
assert . Equal ( t , expectedUids , actualUids )
group2Get = client . GetRulesGroup ( t , folder1Title , group2 . Name )
group2Get = client . GetRulesGroup ( t , folderUID , group2 . Name )
assert . Len ( t , group2Get . Rules , len ( group2 . Rules ) - 1 )
for _ , rule := range group2Get . Rules {
require . NotEqual ( t , movedRule . GrafanaManagedAlert . UID , rule . GrafanaManagedAlert . UID )
@ -1019,26 +1377,26 @@ func TestIntegrationRuleUpdate(t *testing.T) {
adminClient := newAlertingApiClient ( grafanaListedAddr , "admin" , "admin" )
client := newAlertingApiClient ( grafanaListedAddr , "grafana" , "password" )
folder1Title := "folder1"
client . CreateFolder ( t , util . GenerateShortUID ( ) , folder1Title )
folderUID := util . GenerateShortUID ( )
client . CreateFolder ( t , folderUID , "folder1" )
t . Run ( "should be able to reset 'for' to 0" , func ( t * testing . T ) {
group := generateAlertRuleGroup ( 1 , alertRuleGen ( ) )
expected := model . Duration ( 10 * time . Second )
group . Rules [ 0 ] . ApiRuleNode . For = & expected
_ , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
_ , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
getGroup := client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup := client . GetRulesGroup ( t , folderUID , group . Name )
require . Equal ( t , expected , * getGroup . Rules [ 0 ] . ApiRuleNode . For )
group = convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
expected = 0
group . Rules [ 0 ] . ApiRuleNode . For = & expected
_ , status , body = client . PostRulesGroupWithStatus ( t , folder1Title , & group )
_ , status , body = client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
getGroup = client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup = client . GetRulesGroup ( t , folderUID , group . Name )
require . Equal ( t , expected , * getGroup . Rules [ 0 ] . ApiRuleNode . For )
} )
t . Run ( "when data source missing" , func ( t * testing . T ) {
@ -1047,10 +1405,10 @@ func TestIntegrationRuleUpdate(t *testing.T) {
ds1 := adminClient . CreateTestDatasource ( t )
group := generateAlertRuleGroup ( 3 , alertRuleGen ( withDatasourceQuery ( ds1 . Body . Datasource . UID ) ) )
_ , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
_ , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
getGroup := client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup := client . GetRulesGroup ( t , folderUID , group . Name )
group = convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
require . Len ( t , group . Rules , 3 )
@ -1064,59 +1422,59 @@ func TestIntegrationRuleUpdate(t *testing.T) {
}
t . Run ( "noop should not fail" , func ( t * testing . T ) {
getGroup := client . GetRulesGroup ( t , folder1Title , groupName )
getGroup := client . GetRulesGroup ( t , folderUID , groupName )
group := convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
_ , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
_ , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post noop rule group. Response: %s" , body )
} )
t . Run ( "should not let update rule if it does not fix datasource" , func ( t * testing . T ) {
getGroup := client . GetRulesGroup ( t , folder1Title , groupName )
getGroup := client . GetRulesGroup ( t , folderUID , groupName )
group := convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
group . Rules [ 0 ] . GrafanaManagedAlert . Title = uuid . NewString ( )
resp , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
resp , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
if status == http . StatusAccepted {
assert . Len ( t , resp . Deleted , 1 )
getGroup = client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup = client . GetRulesGroup ( t , folderUID , group . Name )
assert . NotEqualf ( t , group . Rules [ 0 ] . GrafanaManagedAlert . Title , getGroup . Rules [ 0 ] . GrafanaManagedAlert . Title , "group was updated" )
}
require . Equalf ( t , http . StatusBadRequest , status , "expected BadRequest. Response: %s" , body )
assert . Contains ( t , body , "data source not found" )
} )
t . Run ( "should let delete broken rule" , func ( t * testing . T ) {
getGroup := client . GetRulesGroup ( t , folder1Title , groupName )
getGroup := client . GetRulesGroup ( t , folderUID , groupName )
group := convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
// remove the last rule.
group . Rules = group . Rules [ 0 : len ( group . Rules ) - 1 ]
resp , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
resp , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to delete last rule from group. Response: %s" , body )
assert . Len ( t , resp . Deleted , 1 )
getGroup = client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup = client . GetRulesGroup ( t , folderUID , group . Name )
group = convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
require . Len ( t , group . Rules , 2 )
} )
t . Run ( "should let fix single rule" , func ( t * testing . T ) {
getGroup := client . GetRulesGroup ( t , folder1Title , groupName )
getGroup := client . GetRulesGroup ( t , folderUID , groupName )
group := convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
ds2 := adminClient . CreateTestDatasource ( t )
withDatasourceQuery ( ds2 . Body . Datasource . UID ) ( & group . Rules [ 0 ] )
resp , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
resp , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post noop rule group. Response: %s" , body )
assert . Len ( t , resp . Deleted , 0 )
assert . Len ( t , resp . Updated , 2 )
assert . Len ( t , resp . Created , 0 )
getGroup = client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup = client . GetRulesGroup ( t , folderUID , group . Name )
group = convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
require . Equal ( t , ds2 . Body . Datasource . UID , group . Rules [ 0 ] . GrafanaManagedAlert . Data [ 0 ] . DatasourceUID )
} )
t . Run ( "should let delete group" , func ( t * testing . T ) {
status , body := client . DeleteRulesGroup ( t , folder1Title , groupName )
status , body := client . DeleteRulesGroup ( t , folderUID , groupName )
require . Equalf ( t , http . StatusAccepted , status , "failed to post noop rule group. Response: %s" , body )
} )
} )
@ -1210,18 +1568,18 @@ func TestIntegrationRulePause(t *testing.T) {
} )
client := newAlertingApiClient ( grafanaListedAddr , "grafana" , "password" )
folder1Title := "folder1"
client . CreateFolder ( t , util . GenerateShortUID ( ) , folder1Title )
folderUID := util . GenerateShortUID ( )
client . CreateFolder ( t , folderUID , "folder1" )
t . Run ( "should create a paused rule if isPaused is true" , func ( t * testing . T ) {
group := generateAlertRuleGroup ( 1 , alertRuleGen ( ) )
expectedIsPaused := true
group . Rules [ 0 ] . GrafanaManagedAlert . IsPaused = & expectedIsPaused
resp , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
resp , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
require . Len ( t , resp . Created , 1 )
getGroup := client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup := client . GetRulesGroup ( t , folderUID , group . Name )
require . Equalf ( t , http . StatusAccepted , status , "failed to get rule group. Response: %s" , body )
require . Equal ( t , expectedIsPaused , getGroup . Rules [ 0 ] . GrafanaManagedAlert . IsPaused )
} )
@ -1231,10 +1589,10 @@ func TestIntegrationRulePause(t *testing.T) {
expectedIsPaused := false
group . Rules [ 0 ] . GrafanaManagedAlert . IsPaused = & expectedIsPaused
resp , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
resp , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
require . Len ( t , resp . Created , 1 )
getGroup := client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup := client . GetRulesGroup ( t , folderUID , group . Name )
require . Equalf ( t , http . StatusAccepted , status , "failed to get rule group. Response: %s" , body )
require . Equal ( t , expectedIsPaused , getGroup . Rules [ 0 ] . GrafanaManagedAlert . IsPaused )
} )
@ -1243,10 +1601,10 @@ func TestIntegrationRulePause(t *testing.T) {
group := generateAlertRuleGroup ( 1 , alertRuleGen ( ) )
group . Rules [ 0 ] . GrafanaManagedAlert . IsPaused = nil
resp , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
resp , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
require . Len ( t , resp . Created , 1 )
getGroup := client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup := client . GetRulesGroup ( t , folderUID , group . Name )
require . Equalf ( t , http . StatusAccepted , status , "failed to get rule group. Response: %s" , body )
require . False ( t , getGroup . Rules [ 0 ] . GrafanaManagedAlert . IsPaused )
} )
@ -1301,17 +1659,17 @@ func TestIntegrationRulePause(t *testing.T) {
group := generateAlertRuleGroup ( 1 , alertRuleGen ( ) )
group . Rules [ 0 ] . GrafanaManagedAlert . IsPaused = & tc . isPausedInDb
_ , status , body := client . PostRulesGroupWithStatus ( t , folder1Title , & group )
_ , status , body := client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
getGroup := client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup := client . GetRulesGroup ( t , folderUID , group . Name )
require . Equalf ( t , http . StatusAccepted , status , "failed to get rule group. Response: %s" , body )
group = convertGettableRuleGroupToPostable ( getGroup . GettableRuleGroupConfig )
group . Rules [ 0 ] . GrafanaManagedAlert . IsPaused = tc . isPausedInBody
_ , status , body = client . PostRulesGroupWithStatus ( t , folder1Title , & group )
_ , status , body = client . PostRulesGroupWithStatus ( t , folderUID , & group )
require . Equalf ( t , http . StatusAccepted , status , "failed to post rule group. Response: %s" , body )
getGroup = client . GetRulesGroup ( t , folder1Title , group . Name )
getGroup = client . GetRulesGroup ( t , folderUID , group . Name )
require . Equal ( t , tc . expectedIsPausedInDb , getGroup . Rules [ 0 ] . GrafanaManagedAlert . IsPaused )
} )
}