mirror of https://github.com/grafana/grafana.git
174 lines
5.6 KiB
Go
174 lines
5.6 KiB
Go
package receiver
|
|
|
|
import (
|
|
"fmt"
|
|
"maps"
|
|
|
|
alertingNotify "github.com/grafana/alerting/notify"
|
|
"github.com/grafana/alerting/receivers/schema"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/fields"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
|
|
model "github.com/grafana/grafana/apps/alerting/notifications/pkg/apis/alertingnotifications/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"
|
|
)
|
|
|
|
func convertToK8sResources(
|
|
orgID int64,
|
|
receivers []*ngmodels.Receiver,
|
|
accesses map[string]ngmodels.ReceiverPermissionSet,
|
|
metadatas map[string]ngmodels.ReceiverMetadata,
|
|
namespacer request.NamespaceMapper,
|
|
selector fields.Selector,
|
|
) (*model.ReceiverList, error) {
|
|
result := &model.ReceiverList{
|
|
Items: make([]model.Receiver, 0, len(receivers)),
|
|
}
|
|
for _, receiver := range receivers {
|
|
var access *ngmodels.ReceiverPermissionSet
|
|
if accesses != nil {
|
|
if a, ok := accesses[receiver.GetUID()]; ok {
|
|
access = &a
|
|
}
|
|
}
|
|
var metadata *ngmodels.ReceiverMetadata
|
|
if metadatas != nil {
|
|
if m, ok := metadatas[receiver.GetUID()]; ok {
|
|
metadata = &m
|
|
}
|
|
}
|
|
k8sResource, err := convertToK8sResource(orgID, receiver, access, metadata, namespacer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if selector != nil && !selector.Empty() && !selector.Matches(model.ReceiverSelectableFields(k8sResource)) {
|
|
continue
|
|
}
|
|
result.Items = append(result.Items, *k8sResource)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func convertToK8sResource(
|
|
orgID int64,
|
|
receiver *ngmodels.Receiver,
|
|
access *ngmodels.ReceiverPermissionSet,
|
|
metadata *ngmodels.ReceiverMetadata,
|
|
namespacer request.NamespaceMapper,
|
|
) (*model.Receiver, error) {
|
|
spec := model.ReceiverSpec{
|
|
Title: receiver.Name,
|
|
Integrations: make([]model.ReceiverIntegration, 0, len(receiver.Integrations)),
|
|
}
|
|
for _, integration := range receiver.Integrations {
|
|
spec.Integrations = append(spec.Integrations, model.ReceiverIntegration{
|
|
Uid: &integration.UID,
|
|
Type: string(integration.Config.Type()),
|
|
Version: string(integration.Config.Version),
|
|
DisableResolveMessage: &integration.DisableResolveMessage,
|
|
Settings: maps.Clone(integration.Settings),
|
|
SecureFields: integration.SecureFields(),
|
|
})
|
|
}
|
|
|
|
r := &model.Receiver{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
UID: types.UID(receiver.GetUID()), // This is needed to make PATCH work
|
|
Name: receiver.GetUID(),
|
|
Namespace: namespacer(orgID),
|
|
ResourceVersion: receiver.Version,
|
|
},
|
|
Spec: spec,
|
|
}
|
|
r.SetProvenanceStatus(string(receiver.Provenance))
|
|
|
|
if access != nil {
|
|
for _, action := range ngmodels.ReceiverPermissions() {
|
|
mappedAction, ok := permissionMapper[action]
|
|
if !ok {
|
|
return nil, fmt.Errorf("unknown action %v", action)
|
|
}
|
|
if can, _ := access.Has(action); can {
|
|
r.SetAccessControl(mappedAction)
|
|
}
|
|
}
|
|
}
|
|
|
|
if metadata != nil {
|
|
rules := make([]string, 0, len(metadata.InUseByRules))
|
|
for _, rule := range metadata.InUseByRules {
|
|
rules = append(rules, rule.UID)
|
|
}
|
|
r.SetInUse(metadata.InUseByRoutes, rules)
|
|
r.SetCanUse(metadata.CanUse)
|
|
}
|
|
r.UID = gapiutil.CalculateClusterWideUID(r)
|
|
return r, nil
|
|
}
|
|
|
|
var permissionMapper = map[ngmodels.ReceiverPermission]string{
|
|
ngmodels.ReceiverPermissionReadSecret: "canReadSecrets",
|
|
ngmodels.ReceiverPermissionAdmin: "canAdmin",
|
|
ngmodels.ReceiverPermissionWrite: "canWrite",
|
|
ngmodels.ReceiverPermissionDelete: "canDelete",
|
|
}
|
|
|
|
func convertToDomainModel(receiver *model.Receiver) (*ngmodels.Receiver, map[string][]string, error) {
|
|
domain := &ngmodels.Receiver{
|
|
UID: receiver.Name,
|
|
Name: receiver.Spec.Title,
|
|
Integrations: make([]*ngmodels.Integration, 0, len(receiver.Spec.Integrations)),
|
|
Version: receiver.ResourceVersion,
|
|
Provenance: ngmodels.ProvenanceNone,
|
|
Origin: ngmodels.ResourceOriginGrafana, // Set to Grafana by default.
|
|
}
|
|
storedSecureFields := make(map[string][]string, len(receiver.Spec.Integrations))
|
|
for _, integration := range receiver.Spec.Integrations {
|
|
t, err := alertingNotify.IntegrationTypeFromString(integration.Type)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
var config schema.IntegrationSchemaVersion
|
|
typeSchema, _ := alertingNotify.GetSchemaForIntegration(t)
|
|
if integration.Version != "" {
|
|
var ok bool
|
|
config, ok = typeSchema.GetVersion(schema.Version(integration.Version))
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("invalid version %s for integration type %s", integration.Version, integration.Type)
|
|
}
|
|
} else {
|
|
config = typeSchema.GetCurrentVersion()
|
|
}
|
|
grafanaIntegration := ngmodels.Integration{
|
|
Name: receiver.Spec.Title,
|
|
Config: config,
|
|
Settings: maps.Clone(integration.Settings),
|
|
SecureSettings: make(map[string]string),
|
|
}
|
|
if integration.Uid != nil {
|
|
grafanaIntegration.UID = *integration.Uid
|
|
}
|
|
if integration.DisableResolveMessage != nil {
|
|
grafanaIntegration.DisableResolveMessage = *integration.DisableResolveMessage
|
|
}
|
|
|
|
domain.Integrations = append(domain.Integrations, &grafanaIntegration)
|
|
|
|
if grafanaIntegration.UID != "" {
|
|
// This is an existing integration, so we track the secure fields being requested to copy over from existing values.
|
|
secureFields := make([]string, 0, len(integration.SecureFields))
|
|
for k, isSecure := range integration.SecureFields {
|
|
if isSecure {
|
|
secureFields = append(secureFields, k)
|
|
}
|
|
}
|
|
storedSecureFields[grafanaIntegration.UID] = secureFields
|
|
}
|
|
}
|
|
|
|
return domain, storedSecureFields, nil
|
|
}
|