mirror of https://github.com/grafana/grafana
Alerting: Receiver API (#89707)
parent
c575c06d63
commit
e121e2609f
@ -0,0 +1,32 @@ |
|||||||
|
package core |
||||||
|
|
||||||
|
receiver: { |
||||||
|
kind: "Receiver" |
||||||
|
group: "notifications" |
||||||
|
apiResource: { |
||||||
|
groupOverride: "notifications.alerting.grafana.app" |
||||||
|
} |
||||||
|
codegen: { |
||||||
|
frontend: false |
||||||
|
backend: true |
||||||
|
} |
||||||
|
pluralName: "Receivers" |
||||||
|
current: "v0alpha1" |
||||||
|
versions: { |
||||||
|
"v0alpha1": { |
||||||
|
schema: { |
||||||
|
#Integration: { |
||||||
|
uid?: string |
||||||
|
type: string |
||||||
|
disableResolveMessage?: bool |
||||||
|
settings: bytes |
||||||
|
secureFields?: [string]: bool |
||||||
|
} |
||||||
|
spec: { |
||||||
|
title: string |
||||||
|
integrations : [...#Integration] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package v0alpha1 |
||||||
|
|
||||||
|
// Integration defines model for Integration.
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
type Integration struct { |
||||||
|
DisableResolveMessage *bool `json:"disableResolveMessage,omitempty"` |
||||||
|
// +mapType=atomic
|
||||||
|
SecureFields map[string]bool `json:"SecureFields,omitempty"` |
||||||
|
// +listType=atomic
|
||||||
|
Settings []byte `json:"settings"` |
||||||
|
Type string `json:"type"` |
||||||
|
Uid *string `json:"uid,omitempty"` |
||||||
|
} |
||||||
|
|
||||||
|
// ReceiverSpec defines model for Spec.
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
type ReceiverSpec struct { |
||||||
|
// +listType=atomic
|
||||||
|
Integrations []Integration `json:"integrations"` |
||||||
|
Title string `json:"title"` |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1 |
||||||
|
|
||||||
|
// IntegrationApplyConfiguration represents an declarative configuration of the Integration type for use
|
||||||
|
// with apply.
|
||||||
|
type IntegrationApplyConfiguration struct { |
||||||
|
DisableResolveMessage *bool `json:"disableResolveMessage,omitempty"` |
||||||
|
SecureFields map[string]bool `json:"SecureFields,omitempty"` |
||||||
|
Settings []byte `json:"settings,omitempty"` |
||||||
|
Type *string `json:"type,omitempty"` |
||||||
|
Uid *string `json:"uid,omitempty"` |
||||||
|
} |
||||||
|
|
||||||
|
// IntegrationApplyConfiguration constructs an declarative configuration of the Integration type for use with
|
||||||
|
// apply.
|
||||||
|
func Integration() *IntegrationApplyConfiguration { |
||||||
|
return &IntegrationApplyConfiguration{} |
||||||
|
} |
||||||
|
|
||||||
|
// WithDisableResolveMessage sets the DisableResolveMessage field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the DisableResolveMessage field is set to the value of the last call.
|
||||||
|
func (b *IntegrationApplyConfiguration) WithDisableResolveMessage(value bool) *IntegrationApplyConfiguration { |
||||||
|
b.DisableResolveMessage = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithSecureFields puts the entries into the SecureFields field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the SecureFields field,
|
||||||
|
// overwriting an existing map entries in SecureFields field with the same key.
|
||||||
|
func (b *IntegrationApplyConfiguration) WithSecureFields(entries map[string]bool) *IntegrationApplyConfiguration { |
||||||
|
if b.SecureFields == nil && len(entries) > 0 { |
||||||
|
b.SecureFields = make(map[string]bool, len(entries)) |
||||||
|
} |
||||||
|
for k, v := range entries { |
||||||
|
b.SecureFields[k] = v |
||||||
|
} |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithSettings adds the given value to the Settings field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, values provided by each call will be appended to the Settings field.
|
||||||
|
func (b *IntegrationApplyConfiguration) WithSettings(values ...byte) *IntegrationApplyConfiguration { |
||||||
|
for i := range values { |
||||||
|
b.Settings = append(b.Settings, values[i]) |
||||||
|
} |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithType sets the Type field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Type field is set to the value of the last call.
|
||||||
|
func (b *IntegrationApplyConfiguration) WithType(value string) *IntegrationApplyConfiguration { |
||||||
|
b.Type = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithUid sets the Uid field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Uid field is set to the value of the last call.
|
||||||
|
func (b *IntegrationApplyConfiguration) WithUid(value string) *IntegrationApplyConfiguration { |
||||||
|
b.Uid = &value |
||||||
|
return b |
||||||
|
} |
@ -0,0 +1,196 @@ |
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1 |
||||||
|
|
||||||
|
import ( |
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
types "k8s.io/apimachinery/pkg/types" |
||||||
|
v1 "k8s.io/client-go/applyconfigurations/meta/v1" |
||||||
|
) |
||||||
|
|
||||||
|
// ReceiverApplyConfiguration represents an declarative configuration of the Receiver type for use
|
||||||
|
// with apply.
|
||||||
|
type ReceiverApplyConfiguration struct { |
||||||
|
v1.TypeMetaApplyConfiguration `json:",inline"` |
||||||
|
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` |
||||||
|
Spec *ReceiverSpecApplyConfiguration `json:"spec,omitempty"` |
||||||
|
} |
||||||
|
|
||||||
|
// Receiver constructs an declarative configuration of the Receiver type for use with
|
||||||
|
// apply.
|
||||||
|
func Receiver(name, namespace string) *ReceiverApplyConfiguration { |
||||||
|
b := &ReceiverApplyConfiguration{} |
||||||
|
b.WithName(name) |
||||||
|
b.WithNamespace(namespace) |
||||||
|
b.WithKind("Receiver") |
||||||
|
b.WithAPIVersion("notifications.alerting.grafana.app/v0alpha1") |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithKind sets the Kind field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Kind field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithKind(value string) *ReceiverApplyConfiguration { |
||||||
|
b.Kind = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the APIVersion field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithAPIVersion(value string) *ReceiverApplyConfiguration { |
||||||
|
b.APIVersion = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithName sets the Name field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Name field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithName(value string) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.Name = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithGenerateName sets the GenerateName field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the GenerateName field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithGenerateName(value string) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.GenerateName = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithNamespace sets the Namespace field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Namespace field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithNamespace(value string) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.Namespace = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithUID sets the UID field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the UID field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithUID(value types.UID) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.UID = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the ResourceVersion field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithResourceVersion(value string) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.ResourceVersion = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithGeneration sets the Generation field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Generation field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithGeneration(value int64) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.Generation = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the CreationTimestamp field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.CreationTimestamp = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the DeletionTimestamp field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.DeletionTimestamp = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
b.DeletionGracePeriodSeconds = &value |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||||
|
// overwriting an existing map entries in Labels field with the same key.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithLabels(entries map[string]string) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
if b.Labels == nil && len(entries) > 0 { |
||||||
|
b.Labels = make(map[string]string, len(entries)) |
||||||
|
} |
||||||
|
for k, v := range entries { |
||||||
|
b.Labels[k] = v |
||||||
|
} |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||||
|
// overwriting an existing map entries in Annotations field with the same key.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithAnnotations(entries map[string]string) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
if b.Annotations == nil && len(entries) > 0 { |
||||||
|
b.Annotations = make(map[string]string, len(entries)) |
||||||
|
} |
||||||
|
for k, v := range entries { |
||||||
|
b.Annotations[k] = v |
||||||
|
} |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, values provided by each call will be appended to the OwnerReferences field.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
for i := range values { |
||||||
|
if values[i] == nil { |
||||||
|
panic("nil value passed to WithOwnerReferences") |
||||||
|
} |
||||||
|
b.OwnerReferences = append(b.OwnerReferences, *values[i]) |
||||||
|
} |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithFinalizers adds the given value to the Finalizers field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, values provided by each call will be appended to the Finalizers field.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithFinalizers(values ...string) *ReceiverApplyConfiguration { |
||||||
|
b.ensureObjectMetaApplyConfigurationExists() |
||||||
|
for i := range values { |
||||||
|
b.Finalizers = append(b.Finalizers, values[i]) |
||||||
|
} |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
func (b *ReceiverApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { |
||||||
|
if b.ObjectMetaApplyConfiguration == nil { |
||||||
|
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// WithSpec sets the Spec field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Spec field is set to the value of the last call.
|
||||||
|
func (b *ReceiverApplyConfiguration) WithSpec(value *ReceiverSpecApplyConfiguration) *ReceiverApplyConfiguration { |
||||||
|
b.Spec = value |
||||||
|
return b |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1 |
||||||
|
|
||||||
|
// ReceiverSpecApplyConfiguration represents an declarative configuration of the ReceiverSpec type for use
|
||||||
|
// with apply.
|
||||||
|
type ReceiverSpecApplyConfiguration struct { |
||||||
|
Integrations []IntegrationApplyConfiguration `json:"integrations,omitempty"` |
||||||
|
Title *string `json:"title,omitempty"` |
||||||
|
} |
||||||
|
|
||||||
|
// ReceiverSpecApplyConfiguration constructs an declarative configuration of the ReceiverSpec type for use with
|
||||||
|
// apply.
|
||||||
|
func ReceiverSpec() *ReceiverSpecApplyConfiguration { |
||||||
|
return &ReceiverSpecApplyConfiguration{} |
||||||
|
} |
||||||
|
|
||||||
|
// WithIntegrations adds the given value to the Integrations field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, values provided by each call will be appended to the Integrations field.
|
||||||
|
func (b *ReceiverSpecApplyConfiguration) WithIntegrations(values ...*IntegrationApplyConfiguration) *ReceiverSpecApplyConfiguration { |
||||||
|
for i := range values { |
||||||
|
if values[i] == nil { |
||||||
|
panic("nil value passed to WithIntegrations") |
||||||
|
} |
||||||
|
b.Integrations = append(b.Integrations, *values[i]) |
||||||
|
} |
||||||
|
return b |
||||||
|
} |
||||||
|
|
||||||
|
// WithTitle sets the Title field in the declarative configuration to the given value
|
||||||
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the Title field is set to the value of the last call.
|
||||||
|
func (b *ReceiverSpecApplyConfiguration) WithTitle(value string) *ReceiverSpecApplyConfiguration { |
||||||
|
b.Title = &value |
||||||
|
return b |
||||||
|
} |
@ -0,0 +1,140 @@ |
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by client-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package fake |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
json "encoding/json" |
||||||
|
"fmt" |
||||||
|
|
||||||
|
v0alpha1 "github.com/grafana/grafana/pkg/apis/alerting_notifications/v0alpha1" |
||||||
|
alertingnotificationsv0alpha1 "github.com/grafana/grafana/pkg/generated/applyconfiguration/alerting_notifications/v0alpha1" |
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
labels "k8s.io/apimachinery/pkg/labels" |
||||||
|
types "k8s.io/apimachinery/pkg/types" |
||||||
|
watch "k8s.io/apimachinery/pkg/watch" |
||||||
|
testing "k8s.io/client-go/testing" |
||||||
|
) |
||||||
|
|
||||||
|
// FakeReceivers implements ReceiverInterface
|
||||||
|
type FakeReceivers struct { |
||||||
|
Fake *FakeNotificationsV0alpha1 |
||||||
|
ns string |
||||||
|
} |
||||||
|
|
||||||
|
var receiversResource = v0alpha1.SchemeGroupVersion.WithResource("receivers") |
||||||
|
|
||||||
|
var receiversKind = v0alpha1.SchemeGroupVersion.WithKind("Receiver") |
||||||
|
|
||||||
|
// Get takes name of the receiver, and returns the corresponding receiver object, and an error if there is any.
|
||||||
|
func (c *FakeReceivers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
obj, err := c.Fake. |
||||||
|
Invokes(testing.NewGetAction(receiversResource, c.ns, name), &v0alpha1.Receiver{}) |
||||||
|
|
||||||
|
if obj == nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return obj.(*v0alpha1.Receiver), err |
||||||
|
} |
||||||
|
|
||||||
|
// List takes label and field selectors, and returns the list of Receivers that match those selectors.
|
||||||
|
func (c *FakeReceivers) List(ctx context.Context, opts v1.ListOptions) (result *v0alpha1.ReceiverList, err error) { |
||||||
|
obj, err := c.Fake. |
||||||
|
Invokes(testing.NewListAction(receiversResource, receiversKind, c.ns, opts), &v0alpha1.ReceiverList{}) |
||||||
|
|
||||||
|
if obj == nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
label, _, _ := testing.ExtractFromListOptions(opts) |
||||||
|
if label == nil { |
||||||
|
label = labels.Everything() |
||||||
|
} |
||||||
|
list := &v0alpha1.ReceiverList{ListMeta: obj.(*v0alpha1.ReceiverList).ListMeta} |
||||||
|
for _, item := range obj.(*v0alpha1.ReceiverList).Items { |
||||||
|
if label.Matches(labels.Set(item.Labels)) { |
||||||
|
list.Items = append(list.Items, item) |
||||||
|
} |
||||||
|
} |
||||||
|
return list, err |
||||||
|
} |
||||||
|
|
||||||
|
// Watch returns a watch.Interface that watches the requested receivers.
|
||||||
|
func (c *FakeReceivers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { |
||||||
|
return c.Fake. |
||||||
|
InvokesWatch(testing.NewWatchAction(receiversResource, c.ns, opts)) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// Create takes the representation of a receiver and creates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||||
|
func (c *FakeReceivers) Create(ctx context.Context, receiver *v0alpha1.Receiver, opts v1.CreateOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
obj, err := c.Fake. |
||||||
|
Invokes(testing.NewCreateAction(receiversResource, c.ns, receiver), &v0alpha1.Receiver{}) |
||||||
|
|
||||||
|
if obj == nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return obj.(*v0alpha1.Receiver), err |
||||||
|
} |
||||||
|
|
||||||
|
// Update takes the representation of a receiver and updates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||||
|
func (c *FakeReceivers) Update(ctx context.Context, receiver *v0alpha1.Receiver, opts v1.UpdateOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
obj, err := c.Fake. |
||||||
|
Invokes(testing.NewUpdateAction(receiversResource, c.ns, receiver), &v0alpha1.Receiver{}) |
||||||
|
|
||||||
|
if obj == nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return obj.(*v0alpha1.Receiver), err |
||||||
|
} |
||||||
|
|
||||||
|
// Delete takes name of the receiver and deletes it. Returns an error if one occurs.
|
||||||
|
func (c *FakeReceivers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { |
||||||
|
_, err := c.Fake. |
||||||
|
Invokes(testing.NewDeleteActionWithOptions(receiversResource, c.ns, name, opts), &v0alpha1.Receiver{}) |
||||||
|
|
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
// DeleteCollection deletes a collection of objects.
|
||||||
|
func (c *FakeReceivers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { |
||||||
|
action := testing.NewDeleteCollectionAction(receiversResource, c.ns, listOpts) |
||||||
|
|
||||||
|
_, err := c.Fake.Invokes(action, &v0alpha1.ReceiverList{}) |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched receiver.
|
||||||
|
func (c *FakeReceivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v0alpha1.Receiver, err error) { |
||||||
|
obj, err := c.Fake. |
||||||
|
Invokes(testing.NewPatchSubresourceAction(receiversResource, c.ns, name, pt, data, subresources...), &v0alpha1.Receiver{}) |
||||||
|
|
||||||
|
if obj == nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return obj.(*v0alpha1.Receiver), err |
||||||
|
} |
||||||
|
|
||||||
|
// Apply takes the given apply declarative configuration, applies it and returns the applied receiver.
|
||||||
|
func (c *FakeReceivers) Apply(ctx context.Context, receiver *alertingnotificationsv0alpha1.ReceiverApplyConfiguration, opts v1.ApplyOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
if receiver == nil { |
||||||
|
return nil, fmt.Errorf("receiver provided to Apply must not be nil") |
||||||
|
} |
||||||
|
data, err := json.Marshal(receiver) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
name := receiver.Name |
||||||
|
if name == nil { |
||||||
|
return nil, fmt.Errorf("receiver.Name must be provided to Apply") |
||||||
|
} |
||||||
|
obj, err := c.Fake. |
||||||
|
Invokes(testing.NewPatchSubresourceAction(receiversResource, c.ns, *name, types.ApplyPatchType, data), &v0alpha1.Receiver{}) |
||||||
|
|
||||||
|
if obj == nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return obj.(*v0alpha1.Receiver), err |
||||||
|
} |
@ -0,0 +1,194 @@ |
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by client-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1 |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
json "encoding/json" |
||||||
|
"fmt" |
||||||
|
"time" |
||||||
|
|
||||||
|
v0alpha1 "github.com/grafana/grafana/pkg/apis/alerting_notifications/v0alpha1" |
||||||
|
alertingnotificationsv0alpha1 "github.com/grafana/grafana/pkg/generated/applyconfiguration/alerting_notifications/v0alpha1" |
||||||
|
scheme "github.com/grafana/grafana/pkg/generated/clientset/versioned/scheme" |
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
types "k8s.io/apimachinery/pkg/types" |
||||||
|
watch "k8s.io/apimachinery/pkg/watch" |
||||||
|
rest "k8s.io/client-go/rest" |
||||||
|
) |
||||||
|
|
||||||
|
// ReceiversGetter has a method to return a ReceiverInterface.
|
||||||
|
// A group's client should implement this interface.
|
||||||
|
type ReceiversGetter interface { |
||||||
|
Receivers(namespace string) ReceiverInterface |
||||||
|
} |
||||||
|
|
||||||
|
// ReceiverInterface has methods to work with Receiver resources.
|
||||||
|
type ReceiverInterface interface { |
||||||
|
Create(ctx context.Context, receiver *v0alpha1.Receiver, opts v1.CreateOptions) (*v0alpha1.Receiver, error) |
||||||
|
Update(ctx context.Context, receiver *v0alpha1.Receiver, opts v1.UpdateOptions) (*v0alpha1.Receiver, error) |
||||||
|
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error |
||||||
|
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error |
||||||
|
Get(ctx context.Context, name string, opts v1.GetOptions) (*v0alpha1.Receiver, error) |
||||||
|
List(ctx context.Context, opts v1.ListOptions) (*v0alpha1.ReceiverList, error) |
||||||
|
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) |
||||||
|
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v0alpha1.Receiver, err error) |
||||||
|
Apply(ctx context.Context, receiver *alertingnotificationsv0alpha1.ReceiverApplyConfiguration, opts v1.ApplyOptions) (result *v0alpha1.Receiver, err error) |
||||||
|
ReceiverExpansion |
||||||
|
} |
||||||
|
|
||||||
|
// receivers implements ReceiverInterface
|
||||||
|
type receivers struct { |
||||||
|
client rest.Interface |
||||||
|
ns string |
||||||
|
} |
||||||
|
|
||||||
|
// newReceivers returns a Receivers
|
||||||
|
func newReceivers(c *NotificationsV0alpha1Client, namespace string) *receivers { |
||||||
|
return &receivers{ |
||||||
|
client: c.RESTClient(), |
||||||
|
ns: namespace, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Get takes name of the receiver, and returns the corresponding receiver object, and an error if there is any.
|
||||||
|
func (c *receivers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
result = &v0alpha1.Receiver{} |
||||||
|
err = c.client.Get(). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
Name(name). |
||||||
|
VersionedParams(&options, scheme.ParameterCodec). |
||||||
|
Do(ctx). |
||||||
|
Into(result) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// List takes label and field selectors, and returns the list of Receivers that match those selectors.
|
||||||
|
func (c *receivers) List(ctx context.Context, opts v1.ListOptions) (result *v0alpha1.ReceiverList, err error) { |
||||||
|
var timeout time.Duration |
||||||
|
if opts.TimeoutSeconds != nil { |
||||||
|
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second |
||||||
|
} |
||||||
|
result = &v0alpha1.ReceiverList{} |
||||||
|
err = c.client.Get(). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
VersionedParams(&opts, scheme.ParameterCodec). |
||||||
|
Timeout(timeout). |
||||||
|
Do(ctx). |
||||||
|
Into(result) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Watch returns a watch.Interface that watches the requested receivers.
|
||||||
|
func (c *receivers) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { |
||||||
|
var timeout time.Duration |
||||||
|
if opts.TimeoutSeconds != nil { |
||||||
|
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second |
||||||
|
} |
||||||
|
opts.Watch = true |
||||||
|
return c.client.Get(). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
VersionedParams(&opts, scheme.ParameterCodec). |
||||||
|
Timeout(timeout). |
||||||
|
Watch(ctx) |
||||||
|
} |
||||||
|
|
||||||
|
// Create takes the representation of a receiver and creates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||||
|
func (c *receivers) Create(ctx context.Context, receiver *v0alpha1.Receiver, opts v1.CreateOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
result = &v0alpha1.Receiver{} |
||||||
|
err = c.client.Post(). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
VersionedParams(&opts, scheme.ParameterCodec). |
||||||
|
Body(receiver). |
||||||
|
Do(ctx). |
||||||
|
Into(result) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Update takes the representation of a receiver and updates it. Returns the server's representation of the receiver, and an error, if there is any.
|
||||||
|
func (c *receivers) Update(ctx context.Context, receiver *v0alpha1.Receiver, opts v1.UpdateOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
result = &v0alpha1.Receiver{} |
||||||
|
err = c.client.Put(). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
Name(receiver.Name). |
||||||
|
VersionedParams(&opts, scheme.ParameterCodec). |
||||||
|
Body(receiver). |
||||||
|
Do(ctx). |
||||||
|
Into(result) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Delete takes name of the receiver and deletes it. Returns an error if one occurs.
|
||||||
|
func (c *receivers) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { |
||||||
|
return c.client.Delete(). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
Name(name). |
||||||
|
Body(&opts). |
||||||
|
Do(ctx). |
||||||
|
Error() |
||||||
|
} |
||||||
|
|
||||||
|
// DeleteCollection deletes a collection of objects.
|
||||||
|
func (c *receivers) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { |
||||||
|
var timeout time.Duration |
||||||
|
if listOpts.TimeoutSeconds != nil { |
||||||
|
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second |
||||||
|
} |
||||||
|
return c.client.Delete(). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
VersionedParams(&listOpts, scheme.ParameterCodec). |
||||||
|
Timeout(timeout). |
||||||
|
Body(&opts). |
||||||
|
Do(ctx). |
||||||
|
Error() |
||||||
|
} |
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched receiver.
|
||||||
|
func (c *receivers) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v0alpha1.Receiver, err error) { |
||||||
|
result = &v0alpha1.Receiver{} |
||||||
|
err = c.client.Patch(pt). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
Name(name). |
||||||
|
SubResource(subresources...). |
||||||
|
VersionedParams(&opts, scheme.ParameterCodec). |
||||||
|
Body(data). |
||||||
|
Do(ctx). |
||||||
|
Into(result) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Apply takes the given apply declarative configuration, applies it and returns the applied receiver.
|
||||||
|
func (c *receivers) Apply(ctx context.Context, receiver *alertingnotificationsv0alpha1.ReceiverApplyConfiguration, opts v1.ApplyOptions) (result *v0alpha1.Receiver, err error) { |
||||||
|
if receiver == nil { |
||||||
|
return nil, fmt.Errorf("receiver provided to Apply must not be nil") |
||||||
|
} |
||||||
|
patchOpts := opts.ToPatchOptions() |
||||||
|
data, err := json.Marshal(receiver) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
name := receiver.Name |
||||||
|
if name == nil { |
||||||
|
return nil, fmt.Errorf("receiver.Name must be provided to Apply") |
||||||
|
} |
||||||
|
result = &v0alpha1.Receiver{} |
||||||
|
err = c.client.Patch(types.ApplyPatchType). |
||||||
|
Namespace(c.ns). |
||||||
|
Resource("receivers"). |
||||||
|
Name(*name). |
||||||
|
VersionedParams(&patchOpts, scheme.ParameterCodec). |
||||||
|
Body(data). |
||||||
|
Do(ctx). |
||||||
|
Into(result) |
||||||
|
return |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by informer-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1 |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
time "time" |
||||||
|
|
||||||
|
alertingnotificationsv0alpha1 "github.com/grafana/grafana/pkg/apis/alerting_notifications/v0alpha1" |
||||||
|
versioned "github.com/grafana/grafana/pkg/generated/clientset/versioned" |
||||||
|
internalinterfaces "github.com/grafana/grafana/pkg/generated/informers/externalversions/internalinterfaces" |
||||||
|
v0alpha1 "github.com/grafana/grafana/pkg/generated/listers/alerting_notifications/v0alpha1" |
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime" |
||||||
|
watch "k8s.io/apimachinery/pkg/watch" |
||||||
|
cache "k8s.io/client-go/tools/cache" |
||||||
|
) |
||||||
|
|
||||||
|
// ReceiverInformer provides access to a shared informer and lister for
|
||||||
|
// Receivers.
|
||||||
|
type ReceiverInformer interface { |
||||||
|
Informer() cache.SharedIndexInformer |
||||||
|
Lister() v0alpha1.ReceiverLister |
||||||
|
} |
||||||
|
|
||||||
|
type receiverInformer struct { |
||||||
|
factory internalinterfaces.SharedInformerFactory |
||||||
|
tweakListOptions internalinterfaces.TweakListOptionsFunc |
||||||
|
namespace string |
||||||
|
} |
||||||
|
|
||||||
|
// NewReceiverInformer constructs a new informer for Receiver type.
|
||||||
|
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||||
|
// one. This reduces memory footprint and number of connections to the server.
|
||||||
|
func NewReceiverInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { |
||||||
|
return NewFilteredReceiverInformer(client, namespace, resyncPeriod, indexers, nil) |
||||||
|
} |
||||||
|
|
||||||
|
// NewFilteredReceiverInformer constructs a new informer for Receiver type.
|
||||||
|
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||||
|
// one. This reduces memory footprint and number of connections to the server.
|
||||||
|
func NewFilteredReceiverInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { |
||||||
|
return cache.NewSharedIndexInformer( |
||||||
|
&cache.ListWatch{ |
||||||
|
ListFunc: func(options v1.ListOptions) (runtime.Object, error) { |
||||||
|
if tweakListOptions != nil { |
||||||
|
tweakListOptions(&options) |
||||||
|
} |
||||||
|
return client.NotificationsV0alpha1().Receivers(namespace).List(context.TODO(), options) |
||||||
|
}, |
||||||
|
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { |
||||||
|
if tweakListOptions != nil { |
||||||
|
tweakListOptions(&options) |
||||||
|
} |
||||||
|
return client.NotificationsV0alpha1().Receivers(namespace).Watch(context.TODO(), options) |
||||||
|
}, |
||||||
|
}, |
||||||
|
&alertingnotificationsv0alpha1.Receiver{}, |
||||||
|
resyncPeriod, |
||||||
|
indexers, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
func (f *receiverInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { |
||||||
|
return NewFilteredReceiverInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) |
||||||
|
} |
||||||
|
|
||||||
|
func (f *receiverInformer) Informer() cache.SharedIndexInformer { |
||||||
|
return f.factory.InformerFor(&alertingnotificationsv0alpha1.Receiver{}, f.defaultInformer) |
||||||
|
} |
||||||
|
|
||||||
|
func (f *receiverInformer) Lister() v0alpha1.ReceiverLister { |
||||||
|
return v0alpha1.NewReceiverLister(f.Informer().GetIndexer()) |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// Code generated by lister-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0alpha1 |
||||||
|
|
||||||
|
import ( |
||||||
|
v0alpha1 "github.com/grafana/grafana/pkg/apis/alerting_notifications/v0alpha1" |
||||||
|
"k8s.io/apimachinery/pkg/api/errors" |
||||||
|
"k8s.io/apimachinery/pkg/labels" |
||||||
|
"k8s.io/client-go/tools/cache" |
||||||
|
) |
||||||
|
|
||||||
|
// ReceiverLister helps list Receivers.
|
||||||
|
// All objects returned here must be treated as read-only.
|
||||||
|
type ReceiverLister interface { |
||||||
|
// List lists all Receivers in the indexer.
|
||||||
|
// Objects returned here must be treated as read-only.
|
||||||
|
List(selector labels.Selector) (ret []*v0alpha1.Receiver, err error) |
||||||
|
// Receivers returns an object that can list and get Receivers.
|
||||||
|
Receivers(namespace string) ReceiverNamespaceLister |
||||||
|
ReceiverListerExpansion |
||||||
|
} |
||||||
|
|
||||||
|
// receiverLister implements the ReceiverLister interface.
|
||||||
|
type receiverLister struct { |
||||||
|
indexer cache.Indexer |
||||||
|
} |
||||||
|
|
||||||
|
// NewReceiverLister returns a new ReceiverLister.
|
||||||
|
func NewReceiverLister(indexer cache.Indexer) ReceiverLister { |
||||||
|
return &receiverLister{indexer: indexer} |
||||||
|
} |
||||||
|
|
||||||
|
// List lists all Receivers in the indexer.
|
||||||
|
func (s *receiverLister) List(selector labels.Selector) (ret []*v0alpha1.Receiver, err error) { |
||||||
|
err = cache.ListAll(s.indexer, selector, func(m interface{}) { |
||||||
|
ret = append(ret, m.(*v0alpha1.Receiver)) |
||||||
|
}) |
||||||
|
return ret, err |
||||||
|
} |
||||||
|
|
||||||
|
// Receivers returns an object that can list and get Receivers.
|
||||||
|
func (s *receiverLister) Receivers(namespace string) ReceiverNamespaceLister { |
||||||
|
return receiverNamespaceLister{indexer: s.indexer, namespace: namespace} |
||||||
|
} |
||||||
|
|
||||||
|
// ReceiverNamespaceLister helps list and get Receivers.
|
||||||
|
// All objects returned here must be treated as read-only.
|
||||||
|
type ReceiverNamespaceLister interface { |
||||||
|
// List lists all Receivers in the indexer for a given namespace.
|
||||||
|
// Objects returned here must be treated as read-only.
|
||||||
|
List(selector labels.Selector) (ret []*v0alpha1.Receiver, err error) |
||||||
|
// Get retrieves the Receiver from the indexer for a given namespace and name.
|
||||||
|
// Objects returned here must be treated as read-only.
|
||||||
|
Get(name string) (*v0alpha1.Receiver, error) |
||||||
|
ReceiverNamespaceListerExpansion |
||||||
|
} |
||||||
|
|
||||||
|
// receiverNamespaceLister implements the ReceiverNamespaceLister
|
||||||
|
// interface.
|
||||||
|
type receiverNamespaceLister struct { |
||||||
|
indexer cache.Indexer |
||||||
|
namespace string |
||||||
|
} |
||||||
|
|
||||||
|
// List lists all Receivers in the indexer for a given namespace.
|
||||||
|
func (s receiverNamespaceLister) List(selector labels.Selector) (ret []*v0alpha1.Receiver, err error) { |
||||||
|
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { |
||||||
|
ret = append(ret, m.(*v0alpha1.Receiver)) |
||||||
|
}) |
||||||
|
return ret, err |
||||||
|
} |
||||||
|
|
||||||
|
// Get retrieves the Receiver from the indexer for a given namespace and name.
|
||||||
|
func (s receiverNamespaceLister) Get(name string) (*v0alpha1.Receiver, error) { |
||||||
|
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
if !exists { |
||||||
|
return nil, errors.NewNotFound(v0alpha1.Resource("receiver"), name) |
||||||
|
} |
||||||
|
return obj.(*v0alpha1.Receiver), nil |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
package receiver |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
|
||||||
|
"k8s.io/apiserver/pkg/authorization/authorizer" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/appcontext" |
||||||
|
"github.com/grafana/grafana/pkg/services/accesscontrol" |
||||||
|
) |
||||||
|
|
||||||
|
func Authorize(ctx context.Context, ac accesscontrol.AccessControl, attr authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { |
||||||
|
if attr.GetResource() != resourceInfo.GroupResource().Resource { |
||||||
|
return authorizer.DecisionNoOpinion, "", nil |
||||||
|
} |
||||||
|
user, err := appcontext.User(ctx) |
||||||
|
if err != nil { |
||||||
|
return authorizer.DecisionDeny, "valid user is required", err |
||||||
|
} |
||||||
|
|
||||||
|
var action accesscontrol.Evaluator |
||||||
|
switch attr.GetVerb() { |
||||||
|
case "patch": |
||||||
|
fallthrough |
||||||
|
case "create": |
||||||
|
fallthrough // TODO: Add alert.notifications.receivers:create permission
|
||||||
|
case "update": |
||||||
|
action = accesscontrol.EvalAny( |
||||||
|
accesscontrol.EvalPermission(accesscontrol.ActionAlertingNotificationsWrite), // TODO: Add alert.notifications.receivers:write permission
|
||||||
|
) |
||||||
|
case "deletecollection": |
||||||
|
fallthrough |
||||||
|
case "delete": |
||||||
|
action = accesscontrol.EvalAny( |
||||||
|
accesscontrol.EvalPermission(accesscontrol.ActionAlertingNotificationsWrite), // TODO: Add alert.notifications.receivers:delete permission
|
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
eval := accesscontrol.EvalAny( |
||||||
|
accesscontrol.EvalPermission(accesscontrol.ActionAlertingReceiversRead), |
||||||
|
accesscontrol.EvalPermission(accesscontrol.ActionAlertingReceiversReadSecrets), |
||||||
|
accesscontrol.EvalPermission(accesscontrol.ActionAlertingNotificationsRead), |
||||||
|
) |
||||||
|
if action != nil { |
||||||
|
eval = accesscontrol.EvalAll(eval, action) |
||||||
|
} |
||||||
|
|
||||||
|
ok, err := ac.Evaluate(ctx, user, eval) |
||||||
|
if ok { |
||||||
|
return authorizer.DecisionAllow, "", nil |
||||||
|
} |
||||||
|
return authorizer.DecisionDeny, "", err |
||||||
|
} |
@ -0,0 +1,101 @@ |
|||||||
|
package receiver |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"hash/fnv" |
||||||
|
|
||||||
|
"github.com/prometheus/alertmanager/config" |
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
"k8s.io/apimachinery/pkg/types" |
||||||
|
|
||||||
|
model "github.com/grafana/grafana/pkg/apis/alerting_notifications/v0alpha1" |
||||||
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" |
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" |
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/models" |
||||||
|
) |
||||||
|
|
||||||
|
func getUID(t definitions.GettableApiReceiver) string { |
||||||
|
sum := fnv.New64() |
||||||
|
_, _ = sum.Write([]byte(t.Name)) |
||||||
|
return fmt.Sprintf("%016x", sum.Sum64()) |
||||||
|
} |
||||||
|
|
||||||
|
func convertToK8sResources(orgID int64, receivers []definitions.GettableApiReceiver, namespacer request.NamespaceMapper) (*model.ReceiverList, error) { |
||||||
|
result := &model.ReceiverList{ |
||||||
|
Items: make([]model.Receiver, 0, len(receivers)), |
||||||
|
} |
||||||
|
for _, receiver := range receivers { |
||||||
|
k8sResource, err := convertToK8sResource(orgID, receiver, namespacer) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
result.Items = append(result.Items, *k8sResource) |
||||||
|
} |
||||||
|
return result, nil |
||||||
|
} |
||||||
|
|
||||||
|
func convertToK8sResource(orgID int64, receiver definitions.GettableApiReceiver, namespacer request.NamespaceMapper) (*model.Receiver, error) { |
||||||
|
spec := model.ReceiverSpec{ |
||||||
|
Title: receiver.Receiver.Name, |
||||||
|
} |
||||||
|
provenance := definitions.Provenance(models.ProvenanceNone) |
||||||
|
for _, integration := range receiver.GrafanaManagedReceivers { |
||||||
|
if integration.Provenance != receiver.GrafanaManagedReceivers[0].Provenance { |
||||||
|
return nil, fmt.Errorf("all integrations must have the same provenance") |
||||||
|
} |
||||||
|
provenance = integration.Provenance |
||||||
|
spec.Integrations = append(spec.Integrations, model.Integration{ |
||||||
|
Uid: &integration.UID, |
||||||
|
Type: integration.Type, |
||||||
|
DisableResolveMessage: &integration.DisableResolveMessage, |
||||||
|
Settings: integration.Settings, |
||||||
|
SecureFields: integration.SecureFields, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
uid := getUID(receiver) // TODO replace to stable UID when we switch to normal storage
|
||||||
|
return &model.Receiver{ |
||||||
|
TypeMeta: resourceInfo.TypeMeta(), |
||||||
|
ObjectMeta: metav1.ObjectMeta{ |
||||||
|
UID: types.UID(uid), // This is needed to make PATCH work
|
||||||
|
Name: uid, // TODO replace to stable UID when we switch to normal storage
|
||||||
|
Namespace: namespacer(orgID), |
||||||
|
Annotations: map[string]string{ // TODO find a better place for provenance?
|
||||||
|
"grafana.com/provenance": string(provenance), |
||||||
|
}, |
||||||
|
ResourceVersion: "", // TODO: Implement optimistic concurrency.
|
||||||
|
}, |
||||||
|
Spec: spec, |
||||||
|
}, nil |
||||||
|
} |
||||||
|
|
||||||
|
func convertToDomainModel(receiver *model.Receiver) (definitions.GettableApiReceiver, error) { |
||||||
|
// TODO: Using GettableApiReceiver instead of PostableApiReceiver so that SecureFields type matches.
|
||||||
|
gettable := definitions.GettableApiReceiver{ |
||||||
|
Receiver: config.Receiver{ |
||||||
|
Name: receiver.Spec.Title, |
||||||
|
}, |
||||||
|
GettableGrafanaReceivers: definitions.GettableGrafanaReceivers{ |
||||||
|
GrafanaManagedReceivers: []*definitions.GettableGrafanaReceiver{}, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
for _, integration := range receiver.Spec.Integrations { |
||||||
|
grafanaIntegration := definitions.GettableGrafanaReceiver{ |
||||||
|
Name: receiver.Spec.Title, |
||||||
|
Type: integration.Type, |
||||||
|
Settings: integration.Settings, |
||||||
|
SecureFields: integration.SecureFields, |
||||||
|
//Provenance: "", //TODO: Convert provenance?
|
||||||
|
} |
||||||
|
if integration.Uid != nil { |
||||||
|
grafanaIntegration.UID = *integration.Uid |
||||||
|
} |
||||||
|
if integration.DisableResolveMessage != nil { |
||||||
|
grafanaIntegration.DisableResolveMessage = *integration.DisableResolveMessage |
||||||
|
} |
||||||
|
gettable.GettableGrafanaReceivers.GrafanaManagedReceivers = append(gettable.GettableGrafanaReceivers.GrafanaManagedReceivers, &grafanaIntegration) |
||||||
|
} |
||||||
|
|
||||||
|
return gettable, nil |
||||||
|
} |
@ -0,0 +1,225 @@ |
|||||||
|
package receiver |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors" |
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/internalversion" |
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
"k8s.io/apimachinery/pkg/runtime" |
||||||
|
"k8s.io/apiserver/pkg/registry/rest" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity" |
||||||
|
notifications "github.com/grafana/grafana/pkg/apis/alerting_notifications/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" |
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/models" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
_ grafanaRest.LegacyStorage = (*legacyStorage)(nil) |
||||||
|
) |
||||||
|
|
||||||
|
var resourceInfo = notifications.ReceiverResourceInfo |
||||||
|
|
||||||
|
type ReceiverService interface { |
||||||
|
GetReceiver(ctx context.Context, q models.GetReceiverQuery, user identity.Requester) (definitions.GettableApiReceiver, error) |
||||||
|
GetReceivers(ctx context.Context, q models.GetReceiversQuery, user identity.Requester) ([]definitions.GettableApiReceiver, error) |
||||||
|
CreateReceiver(ctx context.Context, r definitions.GettableApiReceiver, orgID int64) (definitions.GettableApiReceiver, error) // TODO: Uses Gettable for Write, consider creating new struct.
|
||||||
|
UpdateReceiver(ctx context.Context, r definitions.GettableApiReceiver, orgID int64) (definitions.GettableApiReceiver, error) // TODO: Uses Gettable for Write, consider creating new struct.
|
||||||
|
DeleteReceiver(ctx context.Context, name string, orgID int64, provenance definitions.Provenance, version string) error |
||||||
|
} |
||||||
|
|
||||||
|
type legacyStorage struct { |
||||||
|
service ReceiverService |
||||||
|
namespacer request.NamespaceMapper |
||||||
|
tableConverter rest.TableConvertor |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) New() runtime.Object { |
||||||
|
return resourceInfo.NewFunc() |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) Destroy() {} |
||||||
|
|
||||||
|
func (s *legacyStorage) NamespaceScoped() bool { |
||||||
|
return true // namespace == org
|
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) GetSingularName() string { |
||||||
|
return resourceInfo.GetSingularName() |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) NewList() runtime.Object { |
||||||
|
return resourceInfo.NewListFunc() |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) { |
||||||
|
return s.tableConverter.ConvertToTable(ctx, object, tableOptions) |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) List(ctx context.Context, _ *internalversion.ListOptions) (runtime.Object, error) { |
||||||
|
orgId, err := request.OrgIDForList(ctx) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
q := models.GetReceiversQuery{ |
||||||
|
OrgID: orgId, |
||||||
|
//Names: ctx.QueryStrings("names"), // TODO: Query params.
|
||||||
|
//Limit: ctx.QueryInt("limit"),
|
||||||
|
//Offset: ctx.QueryInt("offset"),
|
||||||
|
//Decrypt: ctx.QueryBool("decrypt"),
|
||||||
|
} |
||||||
|
|
||||||
|
user, err := identity.GetRequester(ctx) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
res, err := s.service.GetReceivers(ctx, q, user) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
return convertToK8sResources(orgId, res, s.namespacer) |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) Get(ctx context.Context, uid string, _ *metav1.GetOptions) (runtime.Object, error) { |
||||||
|
info, err := request.NamespaceInfoFrom(ctx, true) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
q := models.GetReceiverQuery{ |
||||||
|
OrgID: info.OrgID, |
||||||
|
Name: uid, // TODO: Name/UID mapping or change signature of service.
|
||||||
|
//Decrypt: ctx.QueryBool("decrypt"), // TODO: Query params.
|
||||||
|
} |
||||||
|
|
||||||
|
user, err := identity.GetRequester(ctx) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
res, err := s.service.GetReceiver(ctx, q, user) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
return convertToK8sResource(info.OrgID, res, s.namespacer) |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) Create(ctx context.Context, |
||||||
|
obj runtime.Object, |
||||||
|
createValidation rest.ValidateObjectFunc, |
||||||
|
_ *metav1.CreateOptions, |
||||||
|
) (runtime.Object, error) { |
||||||
|
info, err := request.NamespaceInfoFrom(ctx, true) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
if createValidation != nil { |
||||||
|
if err := createValidation(ctx, obj.DeepCopyObject()); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
} |
||||||
|
p, ok := obj.(*notifications.Receiver) |
||||||
|
if !ok { |
||||||
|
return nil, fmt.Errorf("expected receiver but got %s", obj.GetObjectKind().GroupVersionKind()) |
||||||
|
} |
||||||
|
if p.ObjectMeta.Name != "" { // TODO remove when metadata.name can be defined by user
|
||||||
|
return nil, errors.NewBadRequest("object's metadata.name should be empty") |
||||||
|
} |
||||||
|
model, err := convertToDomainModel(p) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
out, err := s.service.CreateReceiver(ctx, model, info.OrgID) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return convertToK8sResource(info.OrgID, out, s.namespacer) |
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) Update(ctx context.Context, |
||||||
|
uid string, |
||||||
|
objInfo rest.UpdatedObjectInfo, |
||||||
|
createValidation rest.ValidateObjectFunc, |
||||||
|
updateValidation rest.ValidateObjectUpdateFunc, |
||||||
|
_ bool, |
||||||
|
_ *metav1.UpdateOptions, |
||||||
|
) (runtime.Object, bool, error) { |
||||||
|
info, err := request.NamespaceInfoFrom(ctx, true) |
||||||
|
if err != nil { |
||||||
|
return nil, false, err |
||||||
|
} |
||||||
|
|
||||||
|
old, err := s.Get(ctx, uid, nil) |
||||||
|
if err != nil { |
||||||
|
return old, false, err |
||||||
|
} |
||||||
|
obj, err := objInfo.UpdatedObject(ctx, old) |
||||||
|
if err != nil { |
||||||
|
return old, false, err |
||||||
|
} |
||||||
|
if updateValidation != nil { |
||||||
|
if err := updateValidation(ctx, obj, old); err != nil { |
||||||
|
return nil, false, err |
||||||
|
} |
||||||
|
} |
||||||
|
p, ok := obj.(*notifications.Receiver) |
||||||
|
if !ok { |
||||||
|
return nil, false, fmt.Errorf("expected receiver but got %s", obj.GetObjectKind().GroupVersionKind()) |
||||||
|
} |
||||||
|
model, err := convertToDomainModel(p) |
||||||
|
if err != nil { |
||||||
|
return old, false, err |
||||||
|
} |
||||||
|
|
||||||
|
if p.ObjectMeta.Name != getUID(model) { |
||||||
|
return nil, false, errors.NewBadRequest("title cannot be changed. Consider creating a new resource.") |
||||||
|
} |
||||||
|
|
||||||
|
updated, err := s.service.UpdateReceiver(ctx, model, info.OrgID) |
||||||
|
if err != nil { |
||||||
|
return nil, false, err |
||||||
|
} |
||||||
|
|
||||||
|
r, err := convertToK8sResource(info.OrgID, updated, s.namespacer) |
||||||
|
return r, false, err |
||||||
|
} |
||||||
|
|
||||||
|
// GracefulDeleter
|
||||||
|
func (s *legacyStorage) Delete(ctx context.Context, uid string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { |
||||||
|
info, err := request.NamespaceInfoFrom(ctx, true) |
||||||
|
if err != nil { |
||||||
|
return nil, false, err |
||||||
|
} |
||||||
|
old, err := s.Get(ctx, uid, nil) |
||||||
|
if err != nil { |
||||||
|
return old, false, err |
||||||
|
} |
||||||
|
if deleteValidation != nil { |
||||||
|
if err = deleteValidation(ctx, old); err != nil { |
||||||
|
return nil, false, err |
||||||
|
} |
||||||
|
} |
||||||
|
version := "" |
||||||
|
if options.Preconditions != nil && options.Preconditions.ResourceVersion != nil { |
||||||
|
version = *options.Preconditions.ResourceVersion |
||||||
|
} |
||||||
|
p, ok := old.(*notifications.Receiver) |
||||||
|
if !ok { |
||||||
|
return nil, false, fmt.Errorf("expected receiver but got %s", old.GetObjectKind().GroupVersionKind()) |
||||||
|
} |
||||||
|
|
||||||
|
err = s.service.DeleteReceiver(ctx, p.Spec.Title, info.OrgID, definitions.Provenance(models.ProvenanceNone), version) // TODO add support for dry-run option
|
||||||
|
return old, false, err // false - will be deleted async
|
||||||
|
} |
||||||
|
|
||||||
|
func (s *legacyStorage) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *internalversion.ListOptions) (runtime.Object, error) { |
||||||
|
return nil, errors.NewMethodNotSupported(resourceInfo.GroupResource(), "deleteCollection") |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
package receiver |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
||||||
|
"k8s.io/apimachinery/pkg/runtime" |
||||||
|
"k8s.io/apiserver/pkg/registry/generic" |
||||||
|
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" |
||||||
|
"k8s.io/apiserver/pkg/registry/rest" |
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus" |
||||||
|
|
||||||
|
model "github.com/grafana/grafana/pkg/apis/alerting_notifications/v0alpha1" |
||||||
|
grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" |
||||||
|
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" |
||||||
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" |
||||||
|
"github.com/grafana/grafana/pkg/services/apiserver/utils" |
||||||
|
) |
||||||
|
|
||||||
|
var _ grafanarest.Storage = (*storage)(nil) |
||||||
|
|
||||||
|
type storage struct { |
||||||
|
*genericregistry.Store |
||||||
|
} |
||||||
|
|
||||||
|
func (s storage) Compare(storageObj, legacyObj runtime.Object) bool { |
||||||
|
// TODO implement when supported dual write mode is not Mode0
|
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
func NewStorage( |
||||||
|
legacySvc ReceiverService, |
||||||
|
namespacer request.NamespaceMapper, |
||||||
|
scheme *runtime.Scheme, |
||||||
|
desiredMode grafanarest.DualWriterMode, |
||||||
|
optsGetter generic.RESTOptionsGetter, |
||||||
|
reg prometheus.Registerer) (rest.Storage, error) { |
||||||
|
legacyStore := &legacyStorage{ |
||||||
|
service: legacySvc, |
||||||
|
namespacer: namespacer, |
||||||
|
tableConverter: utils.NewTableConverter( |
||||||
|
resourceInfo.GroupResource(), |
||||||
|
[]metav1.TableColumnDefinition{ |
||||||
|
{Name: "Name", Type: "string", Format: "name"}, |
||||||
|
{Name: "Title", Type: "string", Format: "string", Description: "The receiver name"}, // TODO: Add integration types.
|
||||||
|
}, |
||||||
|
func(obj any) ([]interface{}, error) { |
||||||
|
r, ok := obj.(*model.Receiver) |
||||||
|
if ok { |
||||||
|
return []interface{}{ |
||||||
|
r.Name, |
||||||
|
r.Spec.Title, |
||||||
|
// r.Spec, //TODO implement formatting for Spec, same as UI?
|
||||||
|
}, nil |
||||||
|
} |
||||||
|
return nil, fmt.Errorf("expected resource or info") |
||||||
|
}), |
||||||
|
} |
||||||
|
if optsGetter != nil && desiredMode != grafanarest.Mode0 { |
||||||
|
strategy := grafanaregistry.NewStrategy(scheme) |
||||||
|
s := &genericregistry.Store{ |
||||||
|
NewFunc: resourceInfo.NewFunc, |
||||||
|
NewListFunc: resourceInfo.NewListFunc, |
||||||
|
PredicateFunc: grafanaregistry.Matcher, |
||||||
|
DefaultQualifiedResource: resourceInfo.GroupResource(), |
||||||
|
SingularQualifiedResource: resourceInfo.SingularGroupResource(), |
||||||
|
TableConvertor: legacyStore.tableConverter, |
||||||
|
CreateStrategy: strategy, |
||||||
|
UpdateStrategy: strategy, |
||||||
|
DeleteStrategy: strategy, |
||||||
|
} |
||||||
|
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: grafanaregistry.GetAttrs} |
||||||
|
if err := s.CompleteWithOptions(options); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return grafanarest.NewDualWriter(desiredMode, legacyStore, storage{Store: s}, reg), nil |
||||||
|
} |
||||||
|
return legacyStore, nil |
||||||
|
} |
Loading…
Reference in new issue