Alerting: Move alerting codegen to --grouping=group (#105068)

This commit is contained in:
Gilles De Mey
2025-05-08 12:59:33 +00:00
committed by GitHub
parent 9156149960
commit c78ae5cb76
67 changed files with 2262 additions and 2451 deletions
@@ -8,7 +8,7 @@ import (
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/types"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/receiver/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
@@ -42,7 +42,7 @@ func convertToK8sResources(
if err != nil {
return nil, err
}
if selector != nil && !selector.Empty() && !selector.Matches(model.SelectableFields(k8sResource)) {
if selector != nil && !selector.Empty() && !selector.Matches(model.ReceiverSelectableFields(k8sResource)) {
continue
}
result.Items = append(result.Items, *k8sResource)
@@ -57,12 +57,12 @@ func convertToK8sResource(
metadata *ngmodels.ReceiverMetadata,
namespacer request.NamespaceMapper,
) (*model.Receiver, error) {
spec := model.Spec{
spec := model.ReceiverSpec{
Title: receiver.Name,
Integrations: make([]model.Integration, 0, len(receiver.Integrations)),
Integrations: make([]model.ReceiverIntegration, 0, len(receiver.Integrations)),
}
for _, integration := range receiver.Integrations {
spec.Integrations = append(spec.Integrations, model.Integration{
spec.Integrations = append(spec.Integrations, model.ReceiverIntegration{
Uid: &integration.UID,
Type: integration.Config.Type,
DisableResolveMessage: &integration.DisableResolveMessage,
@@ -11,7 +11,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/receiver/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/identity"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
@@ -7,11 +7,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/receiver/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
)
var kind = model.Kind()
var kind = model.ReceiverKind()
var ResourceInfo = utils.NewResourceInfo(kind.Group(), kind.Version(),
kind.GroupVersionResource().Resource, strings.ToLower(kind.Kind()), kind.Kind(),
func() runtime.Object { return kind.ZeroValue() },
@@ -9,6 +9,7 @@ import (
"k8s.io/apiserver/pkg/authorization/authorizer"
notificationsResource "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
notificationsApp "github.com/grafana/grafana/apps/alerting/notifications/pkg/app"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/registry/apps/alerting/notifications/receiver"
@@ -38,7 +39,7 @@ func RegisterApp(
appCfg := &runner.AppBuilderConfig{
Authorizer: getAuthorizer(ng.Api.AccessControl),
LegacyStorageGetter: getLegacyStorage(request.GetNamespaceMapper(cfg), ng),
OpenAPIDefGetter: notificationsResource.GetOpenAPIDefinitions,
OpenAPIDefGetter: v0alpha1.GetOpenAPIDefinitions,
ManagedKinds: notificationsResource.GetKinds(),
}
@@ -12,7 +12,7 @@ import (
promModel "github.com/prometheus/common/model"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/routingtree/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
@@ -20,8 +20,8 @@ import (
)
func ConvertToK8sResource(orgID int64, r definitions.Route, version string, namespacer request.NamespaceMapper) (*model.RoutingTree, error) {
spec := model.Spec{
Defaults: model.RouteDefaults{
spec := model.RoutingTreeSpec{
Defaults: model.RoutingTreeRouteDefaults{
GroupBy: r.GroupByStr,
GroupWait: optionalPrometheusDurationToString(r.GroupWait),
GroupInterval: optionalPrometheusDurationToString(r.GroupInterval),
@@ -49,8 +49,8 @@ func ConvertToK8sResource(orgID int64, r definitions.Route, version string, name
return result, nil
}
func convertRouteToK8sSubRoute(r *definitions.Route) model.Route {
result := model.Route{
func convertRouteToK8sSubRoute(r *definitions.Route) model.RoutingTreeRoute {
result := model.RoutingTreeRoute{
GroupBy: r.GroupByStr,
MuteTimeIntervals: r.MuteTimeIntervals,
ActiveTimeIntervals: r.ActiveTimeIntervals,
@@ -58,7 +58,7 @@ func convertRouteToK8sSubRoute(r *definitions.Route) model.Route {
GroupWait: optionalPrometheusDurationToString(r.GroupWait),
GroupInterval: optionalPrometheusDurationToString(r.GroupInterval),
RepeatInterval: optionalPrometheusDurationToString(r.RepeatInterval),
Routes: make([]model.Route, 0, len(r.Routes)),
Routes: make([]model.RoutingTreeRoute, 0, len(r.Routes)),
}
if r.Receiver != "" {
result.Receiver = util.Pointer(r.Receiver)
@@ -68,9 +68,9 @@ func convertRouteToK8sSubRoute(r *definitions.Route) model.Route {
keys := slices.Collect(maps.Keys(r.Match))
slices.Sort(keys)
for _, key := range keys {
result.Matchers = append(result.Matchers, model.Matcher{
result.Matchers = append(result.Matchers, model.RoutingTreeMatcher{
Label: key,
Type: model.MatcherTypeEqual,
Type: model.RoutingTreeMatcherTypeEqual,
Value: r.Match[key],
})
}
@@ -80,9 +80,9 @@ func convertRouteToK8sSubRoute(r *definitions.Route) model.Route {
keys := slices.Collect(maps.Keys(r.MatchRE))
slices.Sort(keys)
for _, key := range keys {
m := model.Matcher{
m := model.RoutingTreeMatcher{
Label: key,
Type: model.MatcherTypeEqualRegex,
Type: model.RoutingTreeMatcherTypeEqualRegex,
}
value, _ := r.MatchRE[key].MarshalYAML()
if s, ok := value.(string); ok {
@@ -93,16 +93,16 @@ func convertRouteToK8sSubRoute(r *definitions.Route) model.Route {
}
for _, m := range r.Matchers {
result.Matchers = append(result.Matchers, model.Matcher{
result.Matchers = append(result.Matchers, model.RoutingTreeMatcher{
Label: m.Name,
Type: model.MatcherType(m.Type.String()),
Type: model.RoutingTreeMatcherType(m.Type.String()),
Value: m.Value,
})
}
for _, m := range r.ObjectMatchers {
result.Matchers = append(result.Matchers, model.Matcher{
result.Matchers = append(result.Matchers, model.RoutingTreeMatcher{
Label: m.Name,
Type: model.MatcherType(m.Type.String()),
Type: model.RoutingTreeMatcherType(m.Type.String()),
Value: m.Value,
})
}
@@ -151,7 +151,7 @@ func convertToDomainModel(obj *model.RoutingTree) (definitions.Route, string, er
return result, obj.ResourceVersion, nil
}
func convertK8sSubRouteToRoute(r model.Route, path string) (definitions.Route, []error) {
func convertK8sSubRouteToRoute(r model.RoutingTreeRoute, path string) (definitions.Route, []error) {
result := definitions.Route{
GroupByStr: r.GroupBy,
MuteTimeIntervals: r.MuteTimeIntervals,
@@ -177,13 +177,13 @@ func convertK8sSubRouteToRoute(r model.Route, path string) (definitions.Route, [
for _, matcher := range r.Matchers {
var mt labels.MatchType
switch matcher.Type {
case model.MatcherTypeEqual:
case model.RoutingTreeMatcherTypeEqual:
mt = labels.MatchEqual
case model.MatcherTypeNotEqual:
case model.RoutingTreeMatcherTypeNotEqual:
mt = labels.MatchNotEqual
case model.MatcherTypeEqualRegex:
case model.RoutingTreeMatcherTypeEqualRegex:
mt = labels.MatchRegexp
case model.MatcherTypeNotEqualRegex:
case model.RoutingTreeMatcherTypeNotEqualRegex:
mt = labels.MatchNotRegexp
default:
errs = append(errs, fmt.Errorf("route '%s' has unsupported matcher type: %s", path, matcher.Type))
@@ -10,7 +10,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/routingtree/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
@@ -5,11 +5,11 @@ import (
"k8s.io/apimachinery/pkg/runtime"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/routingtree/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
)
var kind = model.Kind()
var kind = model.RoutingTreeKind()
var ResourceInfo = utils.NewResourceInfo(kind.Group(), kind.Version(),
kind.GroupVersionResource().Resource, strings.ToLower(kind.Kind()), kind.Kind(),
func() runtime.Object { return kind.ZeroValue() },
@@ -5,7 +5,7 @@ import (
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/types"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/templategroup/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
@@ -17,7 +17,7 @@ func convertToK8sResources(orgID int64, list []definitions.NotificationTemplate,
result := &model.TemplateGroupList{}
for _, t := range list {
item := convertToK8sResource(orgID, t, namespacer)
if selector != nil && !selector.Empty() && !selector.Matches(model.SelectableFields(item)) {
if selector != nil && !selector.Empty() && !selector.Matches(model.TemplateGroupSelectableFields(item)) {
continue
}
result.Items = append(result.Items, *item)
@@ -33,7 +33,7 @@ func convertToK8sResource(orgID int64, template definitions.NotificationTemplate
Namespace: namespacer(orgID),
ResourceVersion: template.ResourceVersion,
},
Spec: model.Spec{
Spec: model.TemplateGroupSpec{
Title: template.Name,
Content: template.Template,
},
@@ -12,7 +12,7 @@ import (
"github.com/grafana/alerting/templates"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/templategroup/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
@@ -7,11 +7,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/templategroup/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
)
var kind = model.Kind()
var kind = model.TemplateGroupKind()
var ResourceInfo = utils.NewResourceInfo(kind.Group(), kind.Version(),
kind.GroupVersionResource().Resource, strings.ToLower(kind.Kind()), kind.Kind(),
func() runtime.Object { return kind.ZeroValue() },
@@ -7,7 +7,7 @@ import (
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/types"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
@@ -20,7 +20,7 @@ func ConvertToK8sResources(orgID int64, intervals []definitions.MuteTimeInterval
if err != nil {
return nil, err
}
var specs []model.Spec
var specs []model.TimeIntervalSpec
err = json.Unmarshal(data, &specs)
if err != nil {
return nil, err
@@ -31,7 +31,7 @@ func ConvertToK8sResources(orgID int64, intervals []definitions.MuteTimeInterval
interval := intervals[idx]
spec := specs[idx]
item := buildTimeInterval(orgID, interval, spec, namespacer)
if selector != nil && !selector.Empty() && !selector.Matches(model.SelectableFields(&item)) {
if selector != nil && !selector.Empty() && !selector.Matches(model.TimeIntervalSelectableFields(&item)) {
continue
}
result.Items = append(result.Items, item)
@@ -44,7 +44,7 @@ func ConvertToK8sResource(orgID int64, interval definitions.MuteTimeInterval, na
if err != nil {
return nil, err
}
spec := model.Spec{}
spec := model.TimeIntervalSpec{}
err = json.Unmarshal(data, &spec)
if err != nil {
return nil, err
@@ -54,7 +54,7 @@ func ConvertToK8sResource(orgID int64, interval definitions.MuteTimeInterval, na
return &result, nil
}
func buildTimeInterval(orgID int64, interval definitions.MuteTimeInterval, spec model.Spec, namespacer request.NamespaceMapper) model.TimeInterval {
func buildTimeInterval(orgID int64, interval definitions.MuteTimeInterval, spec model.TimeIntervalSpec, namespacer request.NamespaceMapper) model.TimeInterval {
i := model.TimeInterval{
ObjectMeta: metav1.ObjectMeta{
UID: types.UID(interval.UID), // TODO This is needed to make PATCH work
@@ -10,7 +10,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
@@ -7,11 +7,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1"
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
)
var kind = model.Kind()
var kind = model.TimeIntervalKind()
var ResourceInfo = utils.NewResourceInfo(kind.Group(), kind.Version(),
kind.GroupVersionResource().Resource, strings.ToLower(kind.Kind()), kind.Kind(),
func() runtime.Object { return kind.ZeroValue() },
@@ -8,72 +8,69 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
v0alpha1_receiver "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/receiver/v0alpha1"
v0alpha1_routingtree "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/routingtree/v0alpha1"
v0alpha1_templategroup "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/templategroup/v0alpha1"
v0alpha1_timeinterval "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
)
func NewReceiverClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1_receiver.Receiver, v0alpha1_receiver.ReceiverList] {
func NewReceiverClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1.Receiver, v0alpha1.ReceiverList] {
t.Helper()
client, err := dynamic.NewForConfig(user.NewRestConfig())
require.NoError(t, err)
return &apis.TypedClient[v0alpha1_receiver.Receiver, v0alpha1_receiver.ReceiverList]{
return &apis.TypedClient[v0alpha1.Receiver, v0alpha1.ReceiverList]{
Client: client.Resource(
schema.GroupVersionResource{
Group: v0alpha1_receiver.Kind().Group(),
Version: v0alpha1_receiver.Kind().Version(),
Resource: v0alpha1_receiver.Kind().Plural(),
Group: v0alpha1.ReceiverKind().Group(),
Version: v0alpha1.ReceiverKind().Version(),
Resource: v0alpha1.ReceiverKind().Plural(),
}).Namespace("default"),
}
}
func NewRoutingTreeClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1_routingtree.RoutingTree, v0alpha1_routingtree.RoutingTreeList] {
func NewRoutingTreeClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1.RoutingTree, v0alpha1.RoutingTreeList] {
t.Helper()
client, err := dynamic.NewForConfig(user.NewRestConfig())
require.NoError(t, err)
return &apis.TypedClient[v0alpha1_routingtree.RoutingTree, v0alpha1_routingtree.RoutingTreeList]{
return &apis.TypedClient[v0alpha1.RoutingTree, v0alpha1.RoutingTreeList]{
Client: client.Resource(
schema.GroupVersionResource{
Group: v0alpha1_routingtree.Kind().Group(),
Version: v0alpha1_routingtree.Kind().Version(),
Resource: v0alpha1_routingtree.Kind().Plural(),
Group: v0alpha1.RoutingTreeKind().Group(),
Version: v0alpha1.RoutingTreeKind().Version(),
Resource: v0alpha1.RoutingTreeKind().Plural(),
}).Namespace("default"),
}
}
func NewTemplateGroupClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1_templategroup.TemplateGroup, v0alpha1_templategroup.TemplateGroupList] {
func NewTemplateGroupClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1.TemplateGroup, v0alpha1.TemplateGroupList] {
t.Helper()
client, err := dynamic.NewForConfig(user.NewRestConfig())
require.NoError(t, err)
return &apis.TypedClient[v0alpha1_templategroup.TemplateGroup, v0alpha1_templategroup.TemplateGroupList]{
return &apis.TypedClient[v0alpha1.TemplateGroup, v0alpha1.TemplateGroupList]{
Client: client.Resource(
schema.GroupVersionResource{
Group: v0alpha1_templategroup.Kind().Group(),
Version: v0alpha1_templategroup.Kind().Version(),
Resource: v0alpha1_templategroup.Kind().Plural(),
Group: v0alpha1.TemplateGroupKind().Group(),
Version: v0alpha1.TemplateGroupKind().Version(),
Resource: v0alpha1.TemplateGroupKind().Plural(),
}).Namespace("default"),
}
}
func NewTimeIntervalClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1_timeinterval.TimeInterval, v0alpha1_timeinterval.TimeIntervalList] {
func NewTimeIntervalClient(t *testing.T, user apis.User) *apis.TypedClient[v0alpha1.TimeInterval, v0alpha1.TimeIntervalList] {
t.Helper()
client, err := dynamic.NewForConfig(user.NewRestConfig())
require.NoError(t, err)
return &apis.TypedClient[v0alpha1_timeinterval.TimeInterval, v0alpha1_timeinterval.TimeIntervalList]{
return &apis.TypedClient[v0alpha1.TimeInterval, v0alpha1.TimeIntervalList]{
Client: client.Resource(
schema.GroupVersionResource{
Group: v0alpha1_timeinterval.Kind().Group(),
Version: v0alpha1_timeinterval.Kind().Version(),
Resource: v0alpha1_timeinterval.Kind().Plural(),
Group: v0alpha1.TimeIntervalKind().Group(),
Version: v0alpha1.TimeIntervalKind().Version(),
Resource: v0alpha1.TimeIntervalKind().Plural(),
}).Namespace("default"),
}
}
@@ -21,7 +21,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/receiver/v0alpha1"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/registry/apps/alerting/notifications/routingtree"
@@ -73,9 +73,9 @@ func TestIntegrationResourceIdentifier(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "Test-Receiver",
Integrations: []v0alpha1.Integration{},
Integrations: []v0alpha1.ReceiverIntegration{},
},
}
@@ -305,9 +305,9 @@ func TestIntegrationResourcePermissions(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "receiver-1",
Integrations: []v0alpha1.Integration{},
Integrations: []v0alpha1.ReceiverIntegration{},
},
}
d, err := json.Marshal(created)
@@ -571,9 +571,9 @@ func TestIntegrationAccessControl(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: fmt.Sprintf("receiver-1-%s", tc.user.Identity.GetLogin()),
Integrations: []v0alpha1.Integration{},
Integrations: []v0alpha1.ReceiverIntegration{},
},
}
d, err := json.Marshal(expected)
@@ -878,9 +878,9 @@ func TestIntegrationProvisioning(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "test-receiver-1",
Integrations: []v0alpha1.Integration{
Integrations: []v0alpha1.ReceiverIntegration{
createIntegration(t, "email"),
},
},
@@ -927,9 +927,9 @@ func TestIntegrationOptimisticConcurrency(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "receiver-1",
Integrations: []v0alpha1.Integration{},
Integrations: []v0alpha1.ReceiverIntegration{},
},
}
@@ -1010,9 +1010,9 @@ func TestIntegrationPatch(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "receiver",
Integrations: []v0alpha1.Integration{
Integrations: []v0alpha1.ReceiverIntegration{
createIntegration(t, "email"),
createIntegration(t, "webhook"),
createIntegration(t, "sns"),
@@ -1028,7 +1028,7 @@ func TestIntegrationPatch(t *testing.T) {
current, err := adminClient.Get(ctx, current.Name, v1.GetOptions{})
require.NoError(t, err)
index := slices.IndexFunc(current.Spec.Integrations, func(t v0alpha1.Integration) bool {
index := slices.IndexFunc(current.Spec.Integrations, func(t v0alpha1.ReceiverIntegration) bool {
return t.Type == "webhook"
})
@@ -1269,9 +1269,9 @@ func TestIntegrationCRUD(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: defaultReceiver.Spec.Title,
Integrations: []v0alpha1.Integration{},
Integrations: []v0alpha1.ReceiverIntegration{},
},
}
_, err := adminClient.Create(ctx, newReceiver, v1.CreateOptions{})
@@ -1285,7 +1285,7 @@ func TestIntegrationCRUD(t *testing.T) {
var receiver *v0alpha1.Receiver
t.Run("should correctly persist all known integrations", func(t *testing.T) {
integrations := make([]v0alpha1.Integration, 0, len(notify.AllKnownConfigsForTesting))
integrations := make([]v0alpha1.ReceiverIntegration, 0, len(notify.AllKnownConfigsForTesting))
keysIter := maps.Keys(notify.AllKnownConfigsForTesting)
keys := slices.Collect(keysIter)
sort.Strings(keys)
@@ -1297,7 +1297,7 @@ func TestIntegrationCRUD(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "all-receivers",
Integrations: integrations,
},
@@ -1369,9 +1369,9 @@ func TestIntegrationCRUD(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: fmt.Sprintf("invalid-%s", key),
Integrations: []v0alpha1.Integration{integration},
Integrations: []v0alpha1.ReceiverIntegration{integration},
},
}, v1.CreateOptions{})
require.Errorf(t, err, "Expected error but got successful result: %v", receiver)
@@ -1394,9 +1394,9 @@ func TestIntegrationReceiverListSelector(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "test-receiver-1",
Integrations: []v0alpha1.Integration{
Integrations: []v0alpha1.ReceiverIntegration{
createIntegration(t, "email"),
},
},
@@ -1408,9 +1408,9 @@ func TestIntegrationReceiverListSelector(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: "test-receiver-2",
Integrations: []v0alpha1.Integration{
Integrations: []v0alpha1.ReceiverIntegration{
createIntegration(t, "email"),
},
},
@@ -1486,16 +1486,16 @@ func persistInitialConfig(t *testing.T, amConfig definitions.PostableUserConfig)
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.ReceiverSpec{
Title: receiver.Name,
Integrations: []v0alpha1.Integration{},
Integrations: []v0alpha1.ReceiverIntegration{},
},
}
for _, integration := range receiver.GrafanaManagedReceivers {
settings := common.Unstructured{}
require.NoError(t, settings.UnmarshalJSON(integration.Settings))
toCreate.Spec.Integrations = append(toCreate.Spec.Integrations, v0alpha1.Integration{
toCreate.Spec.Integrations = append(toCreate.Spec.Integrations, v0alpha1.ReceiverIntegration{
Settings: settings.Object,
Type: integration.Type,
DisableResolveMessage: util.Pointer(false),
@@ -1519,15 +1519,15 @@ func persistInitialConfig(t *testing.T, amConfig definitions.PostableUserConfig)
require.NoError(t, err)
}
func createIntegration(t *testing.T, integrationType string) v0alpha1.Integration {
func createIntegration(t *testing.T, integrationType string) v0alpha1.ReceiverIntegration {
cfg, ok := notify.AllKnownConfigsForTesting[integrationType]
require.Truef(t, ok, "no known config for integration type %s", integrationType)
return createIntegrationWithSettings(t, integrationType, cfg.Config)
}
func createIntegrationWithSettings(t *testing.T, integrationType string, settingsJson string) v0alpha1.Integration {
func createIntegrationWithSettings(t *testing.T, integrationType string, settingsJson string) v0alpha1.ReceiverIntegration {
settings := common.Unstructured{}
require.NoError(t, settings.UnmarshalJSON([]byte(settingsJson)))
return v0alpha1.Integration{
return v0alpha1.ReceiverIntegration{
Settings: settings.Object,
Type: integrationType,
DisableResolveMessage: util.Pointer(false),
@@ -16,11 +16,10 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/routingtree/v0alpha1"
v0alpha1_timeinterval "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/registry/apps/alerting/notifications/routingtree"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1/fakes"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1/fakes"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/accesscontrol"
@@ -60,7 +59,7 @@ func TestIntegrationNotAllowedMethods(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{},
Spec: v0alpha1.RoutingTreeSpec{},
}
_, err := client.Create(ctx, route, v1.CreateOptions{})
assert.Error(t, err)
@@ -204,12 +203,12 @@ func TestIntegrationAccessControl(t *testing.T) {
current, err := adminClient.Get(ctx, v0alpha1.UserDefinedRoutingTreeName, v1.GetOptions{})
require.NoError(t, err)
expected := current.Copy().(*v0alpha1.RoutingTree)
expected.Spec.Routes = []v0alpha1.Route{
expected.Spec.Routes = []v0alpha1.RoutingTreeRoute{
{
Matchers: []v0alpha1.Matcher{
Matchers: []v0alpha1.RoutingTreeMatcher{
{
Label: "test",
Type: v0alpha1.MatcherTypeEqual,
Type: v0alpha1.RoutingTreeMatcherTypeEqual,
Value: "test",
},
},
@@ -313,12 +312,12 @@ func TestIntegrationProvisioning(t *testing.T) {
})
t.Run("should not let update if provisioned", func(t *testing.T) {
updated := current.Copy().(*v0alpha1.RoutingTree)
updated.Spec.Routes = []v0alpha1.Route{
updated.Spec.Routes = []v0alpha1.RoutingTreeRoute{
{
Matchers: []v0alpha1.Matcher{
Matchers: []v0alpha1.RoutingTreeMatcher{
{
Label: "test",
Type: v0alpha1.MatcherTypeNotEqual,
Type: v0alpha1.RoutingTreeMatcherTypeNotEqual,
Value: "123",
},
},
@@ -370,7 +369,7 @@ func TestIntegrationOptimisticConcurrency(t *testing.T) {
require.NoError(t, err)
updated := current.Copy().(*v0alpha1.RoutingTree)
updated.ResourceVersion = ""
updated.Spec.Routes = append(updated.Spec.Routes, v0alpha1.Route{Continue: true})
updated.Spec.Routes = append(updated.Spec.Routes, v0alpha1.RoutingTreeRoute{Continue: true})
actualUpdated, err := adminClient.Update(ctx, updated, v1.UpdateOptions{})
require.NoError(t, err)
@@ -403,11 +402,11 @@ func TestIntegrationDataConsistency(t *testing.T) {
require.NoError(t, err)
}
_, err := common.NewTimeIntervalClient(t, helper.Org1.Admin).Create(ctx, &v0alpha1_timeinterval.TimeInterval{
_, err := common.NewTimeIntervalClient(t, helper.Org1.Admin).Create(ctx, &v0alpha1.TimeInterval{
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1_timeinterval.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: timeInterval,
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(1),
},
@@ -447,25 +446,25 @@ func TestIntegrationDataConsistency(t *testing.T) {
createRoute(t, route)
tree, err := client.Get(ctx, v0alpha1.UserDefinedRoutingTreeName, v1.GetOptions{})
require.NoError(t, err)
expected := []v0alpha1.Matcher{
expected := []v0alpha1.RoutingTreeMatcher{
{
Label: "label_match",
Type: v0alpha1.MatcherTypeEqual,
Type: v0alpha1.RoutingTreeMatcherTypeEqual,
Value: "test-123",
},
{
Label: "label_re",
Type: v0alpha1.MatcherTypeEqualRegex,
Type: v0alpha1.RoutingTreeMatcherTypeEqualRegex,
Value: ".*",
},
{
Label: "label_matchers",
Type: v0alpha1.MatcherTypeEqualRegex,
Type: v0alpha1.RoutingTreeMatcherTypeEqualRegex,
Value: "test-321",
},
{
Label: "object-label-matchers",
Type: v0alpha1.MatcherTypeNotEqualRegex,
Type: v0alpha1.RoutingTreeMatcherTypeNotEqualRegex,
Value: "test-456",
},
}
@@ -554,7 +553,7 @@ func TestIntegrationDataConsistency(t *testing.T) {
t.Run("correctly reads all fields", func(t *testing.T) {
tree, err := client.Get(ctx, v0alpha1.UserDefinedRoutingTreeName, v1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, v0alpha1.RouteDefaults{
assert.Equal(t, v0alpha1.RoutingTreeRouteDefaults{
Receiver: receiver,
GroupBy: []string{"test-123", "test-456"},
GroupWait: util.Pointer("30s"),
@@ -562,7 +561,7 @@ func TestIntegrationDataConsistency(t *testing.T) {
RepeatInterval: util.Pointer("1d"),
}, tree.Spec.Defaults)
assert.Len(t, tree.Spec.Routes, 1)
assert.Equal(t, v0alpha1.Route{
assert.Equal(t, v0alpha1.RoutingTreeRoute{
Continue: true,
Receiver: util.Pointer(receiver),
GroupBy: []string{"test-789"},
@@ -571,25 +570,25 @@ func TestIntegrationDataConsistency(t *testing.T) {
RepeatInterval: util.Pointer("1d6h"),
MuteTimeIntervals: []string{timeInterval},
ActiveTimeIntervals: []string{timeInterval},
Matchers: []v0alpha1.Matcher{
Matchers: []v0alpha1.RoutingTreeMatcher{
{
Label: "m",
Type: v0alpha1.MatcherTypeNotEqual,
Type: v0alpha1.RoutingTreeMatcherTypeNotEqual,
Value: "1",
},
{
Label: "n",
Type: v0alpha1.MatcherTypeEqual,
Type: v0alpha1.RoutingTreeMatcherTypeEqual,
Value: "1",
},
{
Label: "o",
Type: v0alpha1.MatcherTypeEqualRegex,
Type: v0alpha1.RoutingTreeMatcherTypeEqualRegex,
Value: "1",
},
{
Label: "p",
Type: v0alpha1.MatcherTypeNotEqualRegex,
Type: v0alpha1.RoutingTreeMatcherTypeNotEqualRegex,
Value: "1",
},
},
@@ -653,13 +652,13 @@ func TestIntegrationDataConsistency(t *testing.T) {
tree, err := client.Get(ctx, v0alpha1.UserDefinedRoutingTreeName, v1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "foo🙂", tree.Spec.Routes[0].GroupBy[0])
expected := []v0alpha1.Matcher{
{Label: "foo🙂", Type: v0alpha1.MatcherTypeEqual, Value: "bar"},
{Label: "_bar1", Type: v0alpha1.MatcherTypeNotEqual, Value: "baz🙂"},
{Label: "0baz", Type: v0alpha1.MatcherTypeEqualRegex, Value: "[a-zA-Z0-9]+,?"},
{Label: "corge", Type: v0alpha1.MatcherTypeNotEqualRegex, Value: "^[0-9]+((,[0-9]{3})*(,[0-9]{0,3})?)?$"},
{Label: "Προμηθέας", Type: v0alpha1.MatcherTypeEqual, Value: "Prom"},
{Label: "犬", Type: v0alpha1.MatcherTypeNotEqual, Value: "Shiba Inu"},
expected := []v0alpha1.RoutingTreeMatcher{
{Label: "foo🙂", Type: v0alpha1.RoutingTreeMatcherTypeEqual, Value: "bar"},
{Label: "_bar1", Type: v0alpha1.RoutingTreeMatcherTypeNotEqual, Value: "baz🙂"},
{Label: "0baz", Type: v0alpha1.RoutingTreeMatcherTypeEqualRegex, Value: "[a-zA-Z0-9]+,?"},
{Label: "corge", Type: v0alpha1.RoutingTreeMatcherTypeNotEqualRegex, Value: "^[0-9]+((,[0-9]{3})*(,[0-9]{0,3})?)?$"},
{Label: "Προμηθέας", Type: v0alpha1.RoutingTreeMatcherTypeEqual, Value: "Prom"},
{Label: "犬", Type: v0alpha1.RoutingTreeMatcherTypeNotEqual, Value: "Shiba Inu"},
}
assert.ElementsMatch(t, expected, tree.Spec.Routes[0].Matchers)
})
@@ -13,7 +13,7 @@ import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/templategroup/v0alpha1"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/accesscontrol"
@@ -52,7 +52,7 @@ func TestIntegrationResourceIdentifier(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TemplateGroupSpec{
Title: "templateGroup",
Content: `{{ define "test" }} test {{ end }}`,
},
@@ -110,7 +110,7 @@ func TestIntegrationResourceIdentifier(t *testing.T) {
defaultDefn, err := templates.DefaultTemplate()
require.NoError(t, err)
require.Equal(t, v0alpha1.Spec{
require.Equal(t, v0alpha1.TemplateGroupSpec{
Title: v0alpha1.DefaultTemplateTitle,
Content: defaultDefn.Template,
}, actual.Spec)
@@ -226,7 +226,7 @@ func TestIntegrationAccessControl(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TemplateGroupSpec{
Title: fmt.Sprintf("template-group-1-%s", tc.user.Identity.GetLogin()),
Content: `{{ define "test" }} test {{ end }}`,
},
@@ -387,7 +387,7 @@ func TestIntegrationProvisioning(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TemplateGroupSpec{
Title: "template-group-1",
Content: `{{ define "test" }} test {{ end }}`,
},
@@ -432,7 +432,7 @@ func TestIntegrationOptimisticConcurrency(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TemplateGroupSpec{
Title: "template-group-1",
Content: `{{ define "test" }} test {{ end }}`,
},
@@ -516,7 +516,7 @@ func TestIntegrationPatch(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TemplateGroupSpec{
Title: "template-group",
Content: `{{ define "test" }} test {{ end }}`,
},
@@ -576,7 +576,7 @@ func TestIntegrationListSelector(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TemplateGroupSpec{
Title: "test1",
Content: `{{ define "test1" }} test {{ end }}`,
},
@@ -588,7 +588,7 @@ func TestIntegrationListSelector(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TemplateGroupSpec{
Title: "test2",
Content: `{{ define "test2" }} test {{ end }}`,
},
@@ -17,8 +17,8 @@ import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/timeinterval/v0alpha1/fakes"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1"
"github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alerting/v0alpha1/fakes"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/registry/apps/alerting/notifications/routingtree"
@@ -64,7 +64,7 @@ func TestIntegrationResourceIdentifier(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: "time-newInterval",
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(2),
},
@@ -201,7 +201,7 @@ func TestIntegrationTimeIntervalAccessControl(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: fmt.Sprintf("time-interval-1-%s", tc.user.Identity.GetLogin()),
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(2),
},
@@ -361,7 +361,7 @@ func TestIntegrationTimeIntervalProvisioning(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: "time-interval-1",
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(2),
},
@@ -408,7 +408,7 @@ func TestIntegrationTimeIntervalOptimisticConcurrency(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: "time-interval",
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(2),
},
@@ -492,7 +492,7 @@ func TestIntegrationTimeIntervalPatch(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: "time-interval",
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(2),
},
@@ -532,9 +532,9 @@ func TestIntegrationTimeIntervalPatch(t *testing.T) {
result, err := adminClient.Patch(ctx, current.Name, types.JSONPatchType, patchData, v1.PatchOptions{})
require.NoError(t, err)
expectedSpec := v0alpha1.Spec{
expectedSpec := v0alpha1.TimeIntervalSpec{
Name: current.Spec.Name,
TimeIntervals: []v0alpha1.Interval{
TimeIntervals: []v0alpha1.TimeIntervalInterval{
expected,
},
}
@@ -557,7 +557,7 @@ func TestIntegrationTimeIntervalListSelector(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: "test1",
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(2),
},
@@ -569,7 +569,7 @@ func TestIntegrationTimeIntervalListSelector(t *testing.T) {
ObjectMeta: v1.ObjectMeta{
Namespace: "default",
},
Spec: v0alpha1.Spec{
Spec: v0alpha1.TimeIntervalSpec{
Name: "test2",
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(2),
},
@@ -790,20 +790,20 @@ func TestIntegrationTimeIntervalValidation(t *testing.T) {
testCases := []struct {
name string
interval v0alpha1.Spec
interval v0alpha1.TimeIntervalSpec
}{
{
name: "missing name",
interval: v0alpha1.Spec{
interval: v0alpha1.TimeIntervalSpec{
Name: "",
TimeIntervals: fakes.IntervalGenerator{}.GenerateMany(1),
},
},
{
name: "invalid interval",
interval: v0alpha1.Spec{
interval: v0alpha1.TimeIntervalSpec{
Name: "test",
TimeIntervals: []v0alpha1.Interval{
TimeIntervals: []v0alpha1.TimeIntervalInterval{
{
DaysOfMonth: []string{"1-31"},
},
File diff suppressed because it is too large Load Diff