Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: contact point overrides #1670

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions api/v1beta1/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package v1beta1

import v1 "k8s.io/api/core/v1"

type ValueFrom struct {
TargetPath string `json:"targetPath"`
ValueFrom ValueFromSource `json:"valueFrom"`
}

type ValueFromSource struct {
// Selects a key of a ConfigMap.
// +optional
ConfigMapKeyRef *v1.ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
// Selects a key of a Secret.
// +optional
SecretKeyRef *v1.SecretKeySelector `json:"secretKeyRef,omitempty"`
}
2 changes: 2 additions & 0 deletions api/v1beta1/grafanacontactpoint_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type GrafanaContactPointSpec struct {

Settings *apiextensions.JSON `json:"settings"`

ValuesFrom []ValueFrom `json:"valuesFrom,omitempty"`

// +kubebuilder:validation:Enum=alertmanager;prometheus-alertmanager;dingding;discord;email;googlechat;kafka;line;opsgenie;pagerduty;pushover;sensugo;sensu;slack;teams;telegram;threema;victorops;webhook;wecom;hipchat;oncall
Type string `json:"type,omitempty"`

Expand Down
18 changes: 1 addition & 17 deletions api/v1beta1/grafanadatasource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ import (
"fmt"
"time"

v1 "k8s.io/api/core/v1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -72,7 +70,7 @@ type GrafanaDatasourceSpec struct {

// environments variables from secrets or config maps
// +optional
ValuesFrom []GrafanaDatasourceValueFrom `json:"valuesFrom,omitempty"`
ValuesFrom []ValueFrom `json:"valuesFrom,omitempty"`

// how often the datasource is refreshed, defaults to 5m if not set
// +optional
Expand All @@ -87,20 +85,6 @@ type GrafanaDatasourceSpec struct {
AllowCrossNamespaceImport *bool `json:"allowCrossNamespaceImport,omitempty"`
}

type GrafanaDatasourceValueFrom struct {
TargetPath string `json:"targetPath"`
ValueFrom GrafanaDatasourceValueFromSource `json:"valueFrom"`
}

type GrafanaDatasourceValueFromSource struct {
// Selects a key of a ConfigMap.
// +optional
ConfigMapKeyRef *v1.ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`
// Selects a key of a Secret.
// +optional
SecretKeyRef *v1.SecretKeySelector `json:"secretKeyRef,omitempty"`
}

// GrafanaDatasourceStatus defines the observed state of GrafanaDatasource
type GrafanaDatasourceStatus struct {
Hash string `json:"hash,omitempty"`
Expand Down
91 changes: 49 additions & 42 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,70 @@ spec:
- hipchat
- oncall
type: string
valuesFrom:
items:
properties:
targetPath:
type: string
valueFrom:
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the ConfigMap or its key
must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
TODO: Add other useful fields. apiVersion, kind, uid?
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- targetPath
- valueFrom
type: object
type: array
required:
- instanceSelector
- name
Expand Down
28 changes: 28 additions & 0 deletions controllers/controller_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana-operator/v5/api/v1beta1"
grafanav1beta1 "github.com/grafana/grafana-operator/v5/api/v1beta1"
"github.com/grafana/grafana-operator/v5/controllers/model"
corev1 "k8s.io/api/core/v1"
kuberr "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -230,3 +231,30 @@ func buildSynchronizedCondition(resource string, syncType string, generation int
}
return condition
}

func getReferencedValue(ctx context.Context, cl client.Client, cr metav1.ObjectMetaAccessor, source v1beta1.ValueFromSource) (string, string, error) {
objMeta := cr.GetObjectMeta()
if source.SecretKeyRef != nil {
s := &corev1.Secret{}
err := cl.Get(ctx, client.ObjectKey{Namespace: objMeta.GetNamespace(), Name: source.SecretKeyRef.Name}, s)
if err != nil {
return "", "", err
}
if val, ok := s.Data[source.SecretKeyRef.Key]; ok {
return string(val), source.SecretKeyRef.Key, nil
} else {
return "", "", fmt.Errorf("missing key %s in secret %s", source.SecretKeyRef.Key, source.SecretKeyRef.Name)
}
} else {
s := &corev1.ConfigMap{}
err := cl.Get(ctx, client.ObjectKey{Namespace: objMeta.GetNamespace(), Name: source.ConfigMapKeyRef.Name}, s)
if err != nil {
return "", "", err
}
if val, ok := s.Data[source.ConfigMapKeyRef.Key]; ok {
return val, source.ConfigMapKeyRef.Key, nil
} else {
return "", "", fmt.Errorf("missing key %s in configmap %s", source.ConfigMapKeyRef.Key, source.ConfigMapKeyRef.Name)
}
}
}
30 changes: 1 addition & 29 deletions controllers/datasource_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import (
"strings"
"time"

v1 "k8s.io/api/core/v1"

simplejson "github.com/bitly/go-simplejson"
"github.com/grafana/grafana-openapi-client-go/client/datasources"
"github.com/grafana/grafana-openapi-client-go/models"
Expand Down Expand Up @@ -453,7 +451,7 @@ func (r *GrafanaDatasourceReconciler) getDatasourceContent(ctx context.Context,

for _, ref := range cr.Spec.ValuesFrom {
ref := ref
val, key, err := r.getReferencedValue(ctx, cr, &ref.ValueFrom)
val, key, err := getReferencedValue(ctx, r.Client, cr, ref.ValueFrom)
if err != nil {
return nil, "", err
}
Expand Down Expand Up @@ -485,29 +483,3 @@ func (r *GrafanaDatasourceReconciler) getDatasourceContent(ctx context.Context,

return &res, fmt.Sprintf("%x", hash.Sum(nil)), nil
}

func (r *GrafanaDatasourceReconciler) getReferencedValue(ctx context.Context, cr *v1beta1.GrafanaDatasource, source *v1beta1.GrafanaDatasourceValueFromSource) (string, string, error) {
if source.SecretKeyRef != nil {
s := &v1.Secret{}
err := r.Client.Get(ctx, client.ObjectKey{Namespace: cr.Namespace, Name: source.SecretKeyRef.Name}, s)
if err != nil {
return "", "", err
}
if val, ok := s.Data[source.SecretKeyRef.Key]; ok {
return string(val), source.SecretKeyRef.Key, nil
} else {
return "", "", fmt.Errorf("missing key %s in secret %s", source.SecretKeyRef.Key, source.SecretKeyRef.Name)
}
} else {
s := &v1.ConfigMap{}
err := r.Client.Get(ctx, client.ObjectKey{Namespace: cr.Namespace, Name: source.ConfigMapKeyRef.Name}, s)
if err != nil {
return "", "", err
}
if val, ok := s.Data[source.ConfigMapKeyRef.Key]; ok {
return val, source.ConfigMapKeyRef.Key, nil
} else {
return "", "", fmt.Errorf("missing key %s in configmap %s", source.ConfigMapKeyRef.Key, source.ConfigMapKeyRef.Name)
}
}
}
Loading
Loading