From ffdc5321da707137cc7fba26bcfd3cb83c0b4aeb Mon Sep 17 00:00:00 2001 From: Steffen Baarsgaard Date: Tue, 26 Nov 2024 09:14:10 +0100 Subject: [PATCH] Refactor: Common opts structs and ResyncPeriod (#1765) * feat: New common struct * refactor: Embed GrafanaCommonSpec into all crds except Grafanas * refactor: Immutability tests for all crds * docs: Generate * refactor: Use of ResyncPeriod in all reconcilers --------- Co-authored-by: Igor Beliakov <46579601+weisdd@users.noreply.github.com> --- api/v1beta1/common.go | 25 +++++- api/v1beta1/grafanaalertrulegroup_types.go | 16 +--- .../grafanaalertrulegroup_types_test.go | 8 +- api/v1beta1/grafanacontactpoint_types.go | 16 +--- api/v1beta1/grafanacontactpoint_types_test.go | 8 +- api/v1beta1/grafanadashboard_types.go | 36 +------- api/v1beta1/grafanadashboard_types_test.go | 16 ++-- api/v1beta1/grafanadatasource_types.go | 35 +------- api/v1beta1/grafanadatasource_types_test.go | 8 +- api/v1beta1/grafanafolder_types.go | 35 +------- api/v1beta1/grafanafolder_types_test.go | 8 +- .../grafananotificationpolicy_types.go | 11 +-- .../grafananotificationpolicy_types_test.go | 8 +- api/v1beta1/zz_generated.deepcopy.go | 90 +++++++------------ ...ntegreatly.org_grafanaalertrulegroups.yaml | 10 ++- ....integreatly.org_grafanacontactpoints.yaml | 10 ++- ...ana.integreatly.org_grafanadashboards.yaml | 14 +-- ...na.integreatly.org_grafanadatasources.yaml | 14 +-- ...rafana.integreatly.org_grafanafolders.yaml | 14 +-- ...eatly.org_grafananotificationpolicies.yaml | 12 ++- controllers/dashboard_controller.go | 2 +- controllers/dashboard_controller_test.go | 16 ++-- controllers/datasource_controller.go | 2 +- controllers/grafanafolder_controller.go | 2 +- ...ntegreatly.org_grafanaalertrulegroups.yaml | 10 ++- ....integreatly.org_grafanacontactpoints.yaml | 10 ++- ...ana.integreatly.org_grafanadashboards.yaml | 14 +-- ...na.integreatly.org_grafanadatasources.yaml | 14 +-- ...rafana.integreatly.org_grafanafolders.yaml | 14 +-- ...eatly.org_grafananotificationpolicies.yaml | 12 ++- deploy/kustomize/base/crds.yaml | 74 ++++++++------- docs/docs/api.md | 77 ++++++++-------- 32 files changed, 292 insertions(+), 349 deletions(-) diff --git a/api/v1beta1/common.go b/api/v1beta1/common.go index e9825d05e..3872b6c19 100644 --- a/api/v1beta1/common.go +++ b/api/v1beta1/common.go @@ -1,6 +1,9 @@ package v1beta1 -import v1 "k8s.io/api/core/v1" +import ( + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) type ValueFrom struct { TargetPath string `json:"targetPath"` @@ -16,3 +19,23 @@ type ValueFromSource struct { // +optional SecretKeyRef *v1.SecretKeySelector `json:"secretKeyRef,omitempty"` } + +// Common Options that all CRs should embed, excluding GrafanaSpec +// Ensure alignment on handling ResyncPeriod, InstanceSelector, and AllowCrossNamespaceImport +type GrafanaCommonSpec struct { + // How often the resource is synced, defaults to 10m0s if not set + // +optional + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Format=duration + // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" + // +kubebuilder:default="10m0s" + ResyncPeriod metav1.Duration `json:"resyncPeriod,omitempty"` + + // Selects Grafana instances for import + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.instanceSelector is immutable" + InstanceSelector *metav1.LabelSelector `json:"instanceSelector"` + + // Allow the Operator to match this resource with Grafanas outside the current namespace + // +optional + AllowCrossNamespaceImport *bool `json:"allowCrossNamespaceImport,omitempty"` +} diff --git a/api/v1beta1/grafanaalertrulegroup_types.go b/api/v1beta1/grafanaalertrulegroup_types.go index d00d81f1e..e37d73286 100644 --- a/api/v1beta1/grafanaalertrulegroup_types.go +++ b/api/v1beta1/grafanaalertrulegroup_types.go @@ -27,21 +27,12 @@ import ( // +kubebuilder:validation:XValidation:rule="(has(self.folderUID) && !(has(self.folderRef))) || (has(self.folderRef) && !(has(self.folderUID)))", message="Only one of FolderUID or FolderRef can be set" // +kubebuilder:validation:XValidation:rule="((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))", message="spec.editable is immutable" type GrafanaAlertRuleGroupSpec struct { + GrafanaCommonSpec `json:",inline"` + // +optional // Name of the alert rule group. If not specified, the resource name will be used. Name string `json:"name,omitempty"` - // +optional - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=duration - // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" - // +kubebuilder:default="10m" - ResyncPeriod metav1.Duration `json:"resyncPeriod,omitempty"` - - // selects Grafanas for import - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" - InstanceSelector *metav1.LabelSelector `json:"instanceSelector"` - // UID of the folder containing this rule group // Overrides the FolderSelector FolderUID string `json:"folderUID,omitempty"` @@ -57,9 +48,6 @@ type GrafanaAlertRuleGroupSpec struct { // +kubebuilder:validation:Required Interval metav1.Duration `json:"interval"` - // +optional - AllowCrossNamespaceImport *bool `json:"allowCrossNamespaceImport,omitempty"` - // Whether to enable or disable editing of the alert rule group in Grafana UI // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" // +optional diff --git a/api/v1beta1/grafanaalertrulegroup_types_test.go b/api/v1beta1/grafanaalertrulegroup_types_test.go index 1f3824e68..9a805b54a 100644 --- a/api/v1beta1/grafanaalertrulegroup_types_test.go +++ b/api/v1beta1/grafanaalertrulegroup_types_test.go @@ -22,9 +22,11 @@ func newAlertRuleGroup(name string, editable *bool) *GrafanaAlertRuleGroup { Name: name, Editable: editable, FolderRef: "DummyFolderRef", - InstanceSelector: &v1.LabelSelector{ - MatchLabels: map[string]string{ - "test": "alertrulegroup", + GrafanaCommonSpec: GrafanaCommonSpec{ + InstanceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{ + "test": "alertrulegroup", + }, }, }, Rules: []AlertRule{}, diff --git a/api/v1beta1/grafanacontactpoint_types.go b/api/v1beta1/grafanacontactpoint_types.go index e32488c92..74c6dfed9 100644 --- a/api/v1beta1/grafanacontactpoint_types.go +++ b/api/v1beta1/grafanacontactpoint_types.go @@ -27,22 +27,13 @@ import ( // GrafanaContactPointSpec defines the desired state of GrafanaContactPoint // +kubebuilder:validation:XValidation:rule="((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))", message="spec.uid is immutable" type GrafanaContactPointSpec struct { + GrafanaCommonSpec `json:",inline"` + // Manually specify the UID the Contact Point is created with // +optional // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.uid is immutable" CustomUID string `json:"uid,omitempty"` - // +optional - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=duration - // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" - // +kubebuilder:default="10m" - ResyncPeriod metav1.Duration `json:"resyncPeriod,omitempty"` - - // selects Grafanas for import - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" - InstanceSelector *metav1.LabelSelector `json:"instanceSelector"` - // +optional DisableResolveMessage bool `json:"disableResolveMessage,omitempty"` @@ -56,9 +47,6 @@ type GrafanaContactPointSpec struct { // +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"` - - // +optional - AllowCrossNamespaceImport *bool `json:"allowCrossNamespaceImport,omitempty"` } // GrafanaContactPointStatus defines the observed state of GrafanaContactPoint diff --git a/api/v1beta1/grafanacontactpoint_types_test.go b/api/v1beta1/grafanacontactpoint_types_test.go index 665c485a4..4359c0018 100644 --- a/api/v1beta1/grafanacontactpoint_types_test.go +++ b/api/v1beta1/grafanacontactpoint_types_test.go @@ -27,9 +27,11 @@ func newContactPoint(name string, uid string) *GrafanaContactPoint { }, Spec: GrafanaContactPointSpec{ CustomUID: uid, - InstanceSelector: &v1.LabelSelector{ - MatchLabels: map[string]string{ - "test": "datasource", + GrafanaCommonSpec: GrafanaCommonSpec{ + InstanceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{ + "test": "datasource", + }, }, }, Settings: settings, diff --git a/api/v1beta1/grafanadashboard_types.go b/api/v1beta1/grafanadashboard_types.go index 1ce879a83..21e14e78c 100644 --- a/api/v1beta1/grafanadashboard_types.go +++ b/api/v1beta1/grafanadashboard_types.go @@ -37,7 +37,6 @@ const ( DashboardSourceTypeJsonnet DashboardSourceType = "jsonnet" DashboardSourceTypeGrafanaCom DashboardSourceType = "grafana" DashboardSourceConfigMap DashboardSourceType = "configmap" - DefaultResyncPeriod = "5m" ) type GrafanaDashboardDatasource struct { @@ -62,6 +61,8 @@ type GrafanaDashboardUrlAuthorization struct { // +kubebuilder:validation:XValidation:rule="(has(self.folder) && !(has(self.folderRef) || has(self.folderUID))) || !(has(self.folder))", message="folder field cannot be set when folderUID or folderRef is already declared" // +kubebuilder:validation:XValidation:rule="((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))", message="spec.uid is immutable" type GrafanaDashboardSpec struct { + GrafanaCommonSpec `json:",inline"` + // Manually specify the uid for the dashboard, overwrites uids already present in the json model // +optional // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.uid is immutable" @@ -98,10 +99,6 @@ type GrafanaDashboardSpec struct { // +optional ConfigMapRef *v1.ConfigMapKeySelector `json:"configMapRef,omitempty"` - // selects Grafanas for import - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" - InstanceSelector *metav1.LabelSelector `json:"instanceSelector"` - // folder assignment for dashboard // +optional FolderTitle string `json:"folder,omitempty"` @@ -122,22 +119,10 @@ type GrafanaDashboardSpec struct { // +optional ContentCacheDuration metav1.Duration `json:"contentCacheDuration,omitempty"` - // how often the dashboard is refreshed, defaults to 5m if not set - // +optional - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=duration - // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" - // +kubebuilder:default="5m" - ResyncPeriod string `json:"resyncPeriod,omitempty"` - // maps required data sources to existing ones // +optional Datasources []GrafanaDashboardDatasource `json:"datasources,omitempty"` - // allow to import this resources from an operator in a different namespace - // +optional - AllowCrossNamespaceImport *bool `json:"allowCrossNamespaceImport,omitempty"` - // environments variables as a map // +optional Envs []GrafanaDashboardEnv `json:"envs,omitempty"` @@ -261,25 +246,10 @@ func (in *GrafanaDashboard) Unchanged(hash string) bool { } func (in *GrafanaDashboard) ResyncPeriodHasElapsed() bool { - deadline := in.Status.LastResync.Add(in.GetResyncPeriod()) + deadline := in.Status.LastResync.Add(in.Spec.ResyncPeriod.Duration) return time.Now().After(deadline) } -func (in *GrafanaDashboard) GetResyncPeriod() time.Duration { - if in.Spec.ResyncPeriod == "" { - in.Spec.ResyncPeriod = DefaultResyncPeriod - return in.GetResyncPeriod() - } - - duration, err := time.ParseDuration(in.Spec.ResyncPeriod) - if err != nil { - in.Spec.ResyncPeriod = DefaultResyncPeriod - return in.GetResyncPeriod() - } - - return duration -} - func (in *GrafanaDashboard) GetSourceTypes() []DashboardSourceType { var sourceTypes []DashboardSourceType diff --git a/api/v1beta1/grafanadashboard_types_test.go b/api/v1beta1/grafanadashboard_types_test.go index c5e7dc298..d552b78ca 100644 --- a/api/v1beta1/grafanadashboard_types_test.go +++ b/api/v1beta1/grafanadashboard_types_test.go @@ -265,9 +265,11 @@ func getDashboardCR(t *testing.T, crUID string, statusUID string, specUID string UID: types.UID(crUID), }, Spec: GrafanaDashboardSpec{ - InstanceSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "dashboard": "grafana", + GrafanaCommonSpec: GrafanaCommonSpec{ + InstanceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "dashboard": "grafana", + }, }, }, CustomUID: specUID, @@ -293,9 +295,11 @@ func newDashboard(name string, uid string) *GrafanaDashboard { }, Spec: GrafanaDashboardSpec{ CustomUID: uid, - InstanceSelector: &v1.LabelSelector{ - MatchLabels: map[string]string{ - "test": "datasource", + GrafanaCommonSpec: GrafanaCommonSpec{ + InstanceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{ + "test": "datasource", + }, }, }, Json: "", diff --git a/api/v1beta1/grafanadatasource_types.go b/api/v1beta1/grafanadatasource_types.go index dbdcd5a4e..ebc2b48e5 100644 --- a/api/v1beta1/grafanadatasource_types.go +++ b/api/v1beta1/grafanadatasource_types.go @@ -60,6 +60,8 @@ type GrafanaDatasourceInternal struct { // GrafanaDatasourceSpec defines the desired state of GrafanaDatasource // +kubebuilder:validation:XValidation:rule="((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))", message="spec.uid is immutable" type GrafanaDatasourceSpec struct { + GrafanaCommonSpec `json:",inline"` + // The UID, for the datasource, fallback to the deprecated spec.datasource.uid and metadata.uid // +optional // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.uid is immutable" @@ -67,10 +69,6 @@ type GrafanaDatasourceSpec struct { Datasource *GrafanaDatasourceInternal `json:"datasource"` - // selects Grafana instances for import - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" - InstanceSelector *metav1.LabelSelector `json:"instanceSelector"` - // plugins // +optional Plugins PluginList `json:"plugins,omitempty"` @@ -79,18 +77,6 @@ type GrafanaDatasourceSpec struct { // +optional // +kubebuilder:validation:MaxItems=99 ValuesFrom []ValueFrom `json:"valuesFrom,omitempty"` - - // how often the datasource is refreshed, defaults to 5m if not set - // +optional - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=duration - // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" - // +kubebuilder:default="5m" - ResyncPeriod string `json:"resyncPeriod,omitempty"` - - // allow to import this resources from an operator in a different namespace - // +optional - AllowCrossNamespaceImport *bool `json:"allowCrossNamespaceImport,omitempty"` } // GrafanaDatasourceStatus defines the observed state of GrafanaDatasource @@ -129,23 +115,8 @@ type GrafanaDatasourceList struct { Items []GrafanaDatasource `json:"items"` } -func (in *GrafanaDatasource) GetResyncPeriod() time.Duration { - if in.Spec.ResyncPeriod == "" { - in.Spec.ResyncPeriod = DefaultResyncPeriod - return in.GetResyncPeriod() - } - - duration, err := time.ParseDuration(in.Spec.ResyncPeriod) - if err != nil { - in.Spec.ResyncPeriod = DefaultResyncPeriod - return in.GetResyncPeriod() - } - - return duration -} - func (in *GrafanaDatasource) ResyncPeriodHasElapsed() bool { - deadline := in.Status.LastResync.Add(in.GetResyncPeriod()) + deadline := in.Status.LastResync.Add(in.Spec.ResyncPeriod.Duration) return time.Now().After(deadline) } diff --git a/api/v1beta1/grafanadatasource_types_test.go b/api/v1beta1/grafanadatasource_types_test.go index a7872d49e..571d13d78 100644 --- a/api/v1beta1/grafanadatasource_types_test.go +++ b/api/v1beta1/grafanadatasource_types_test.go @@ -20,9 +20,11 @@ func newDatasource(name string, uid string) *GrafanaDatasource { }, Spec: GrafanaDatasourceSpec{ CustomUID: uid, - InstanceSelector: &v1.LabelSelector{ - MatchLabels: map[string]string{ - "test": "datasource", + GrafanaCommonSpec: GrafanaCommonSpec{ + InstanceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{ + "test": "datasource", + }, }, }, Datasource: &GrafanaDatasourceInternal{ diff --git a/api/v1beta1/grafanafolder_types.go b/api/v1beta1/grafanafolder_types.go index 88b3ac0da..cbde5117f 100644 --- a/api/v1beta1/grafanafolder_types.go +++ b/api/v1beta1/grafanafolder_types.go @@ -32,6 +32,8 @@ import ( // +kubebuilder:validation:XValidation:rule="(has(self.parentFolderUID) && !(has(self.parentFolderRef))) || (has(self.parentFolderRef) && !(has(self.parentFolderUID))) || !(has(self.parentFolderRef) && (has(self.parentFolderUID)))", message="Only one of parentFolderUID or parentFolderRef can be set" // +kubebuilder:validation:XValidation:rule="((!has(oldSelf.uid) && !has(self.uid)) || (has(oldSelf.uid) && has(self.uid)))", message="spec.uid is immutable" type GrafanaFolderSpec struct { + GrafanaCommonSpec `json:",inline"` + // Manually specify the UID the Folder is created with // +optional // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="spec.uid is immutable" @@ -45,14 +47,6 @@ type GrafanaFolderSpec struct { // +optional Permissions string `json:"permissions,omitempty"` - // Selects Grafanas for import - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" - InstanceSelector *metav1.LabelSelector `json:"instanceSelector"` - - // Enable matching Grafana instances outside the current namespace - // +optional - AllowCrossNamespaceImport *bool `json:"allowCrossNamespaceImport,omitempty"` - // UID of the folder in which the current folder should be created // +optional ParentFolderUID string `json:"parentFolderUID,omitempty"` @@ -60,14 +54,6 @@ type GrafanaFolderSpec struct { // Reference to an existing GrafanaFolder CR in the same namespace // +optional ParentFolderRef string `json:"parentFolderRef,omitempty"` - - // How often the folder is synced, defaults to 5m if not set - // +optional - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=duration - // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" - // +kubebuilder:default="5m" - ResyncPeriod string `json:"resyncPeriod,omitempty"` } // GrafanaFolderStatus defines the observed state of GrafanaFolder @@ -180,22 +166,7 @@ func (in *GrafanaFolder) GetTitle() string { return in.Name } -func (in *GrafanaFolder) GetResyncPeriod() time.Duration { - if in.Spec.ResyncPeriod == "" { - in.Spec.ResyncPeriod = DefaultResyncPeriod - return in.GetResyncPeriod() - } - - duration, err := time.ParseDuration(in.Spec.ResyncPeriod) - if err != nil { - in.Spec.ResyncPeriod = DefaultResyncPeriod - return in.GetResyncPeriod() - } - - return duration -} - func (in *GrafanaFolder) ResyncPeriodHasElapsed() bool { - deadline := in.Status.LastResync.Add(in.GetResyncPeriod()) + deadline := in.Status.LastResync.Add(in.Spec.ResyncPeriod.Duration) return time.Now().After(deadline) } diff --git a/api/v1beta1/grafanafolder_types_test.go b/api/v1beta1/grafanafolder_types_test.go index 5b043a083..9217dcc10 100644 --- a/api/v1beta1/grafanafolder_types_test.go +++ b/api/v1beta1/grafanafolder_types_test.go @@ -89,9 +89,11 @@ func newFolder(name string, uid string) *GrafanaFolder { }, Spec: GrafanaFolderSpec{ CustomUID: uid, - InstanceSelector: &v1.LabelSelector{ - MatchLabels: map[string]string{ - "test": "folder", + GrafanaCommonSpec: GrafanaCommonSpec{ + InstanceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{ + "test": "folder", + }, }, }, }, diff --git a/api/v1beta1/grafananotificationpolicy_types.go b/api/v1beta1/grafananotificationpolicy_types.go index 6c74643e1..2a11ada30 100644 --- a/api/v1beta1/grafananotificationpolicy_types.go +++ b/api/v1beta1/grafananotificationpolicy_types.go @@ -26,16 +26,7 @@ import ( // GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPolicy // +kubebuilder:validation:XValidation:rule="((!has(oldSelf.editable) && !has(self.editable)) || (has(oldSelf.editable) && has(self.editable)))", message="spec.editable is immutable" type GrafanaNotificationPolicySpec struct { - // +optional - // +kubebuilder:validation:Type=string - // +kubebuilder:validation:Format=duration - // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$" - // +kubebuilder:default="10m" - ResyncPeriod metav1.Duration `json:"resyncPeriod,omitempty"` - - // selects Grafanas for import - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable" - InstanceSelector *metav1.LabelSelector `json:"instanceSelector"` + GrafanaCommonSpec `json:",inline"` // Routes for alerts to match against Route *Route `json:"route"` diff --git a/api/v1beta1/grafananotificationpolicy_types_test.go b/api/v1beta1/grafananotificationpolicy_types_test.go index b5c43b376..d7d43fe78 100644 --- a/api/v1beta1/grafananotificationpolicy_types_test.go +++ b/api/v1beta1/grafananotificationpolicy_types_test.go @@ -20,9 +20,11 @@ func newNotificationPolicy(name string, editable *bool) *GrafanaNotificationPoli }, Spec: GrafanaNotificationPolicySpec{ Editable: editable, - InstanceSelector: &v1.LabelSelector{ - MatchLabels: map[string]string{ - "test": "notificationpolicy", + GrafanaCommonSpec: GrafanaCommonSpec{ + InstanceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{ + "test": "notificationpolicy", + }, }, }, Route: &Route{ diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index e05be5bc0..82321b190 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -477,12 +477,7 @@ func (in *GrafanaAlertRuleGroupList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaAlertRuleGroupSpec) DeepCopyInto(out *GrafanaAlertRuleGroupSpec) { *out = *in - out.ResyncPeriod = in.ResyncPeriod - if in.InstanceSelector != nil { - in, out := &in.InstanceSelector, &out.InstanceSelector - *out = new(metav1.LabelSelector) - (*in).DeepCopyInto(*out) - } + in.GrafanaCommonSpec.DeepCopyInto(&out.GrafanaCommonSpec) if in.Rules != nil { in, out := &in.Rules, &out.Rules *out = make([]AlertRule, len(*in)) @@ -491,11 +486,6 @@ func (in *GrafanaAlertRuleGroupSpec) DeepCopyInto(out *GrafanaAlertRuleGroupSpec } } out.Interval = in.Interval - if in.AllowCrossNamespaceImport != nil { - in, out := &in.AllowCrossNamespaceImport, &out.AllowCrossNamespaceImport - *out = new(bool) - **out = **in - } if in.Editable != nil { in, out := &in.Editable, &out.Editable *out = new(bool) @@ -592,6 +582,32 @@ func (in *GrafanaComDashboardReference) DeepCopy() *GrafanaComDashboardReference return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GrafanaCommonSpec) DeepCopyInto(out *GrafanaCommonSpec) { + *out = *in + out.ResyncPeriod = in.ResyncPeriod + if in.InstanceSelector != nil { + in, out := &in.InstanceSelector, &out.InstanceSelector + *out = new(metav1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.AllowCrossNamespaceImport != nil { + in, out := &in.AllowCrossNamespaceImport, &out.AllowCrossNamespaceImport + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaCommonSpec. +func (in *GrafanaCommonSpec) DeepCopy() *GrafanaCommonSpec { + if in == nil { + return nil + } + out := new(GrafanaCommonSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaContactPoint) DeepCopyInto(out *GrafanaContactPoint) { *out = *in @@ -654,12 +670,7 @@ func (in *GrafanaContactPointList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaContactPointSpec) DeepCopyInto(out *GrafanaContactPointSpec) { *out = *in - out.ResyncPeriod = in.ResyncPeriod - if in.InstanceSelector != nil { - in, out := &in.InstanceSelector, &out.InstanceSelector - *out = new(metav1.LabelSelector) - (*in).DeepCopyInto(*out) - } + in.GrafanaCommonSpec.DeepCopyInto(&out.GrafanaCommonSpec) if in.Settings != nil { in, out := &in.Settings, &out.Settings *out = new(apiextensionsv1.JSON) @@ -672,11 +683,6 @@ func (in *GrafanaContactPointSpec) DeepCopyInto(out *GrafanaContactPointSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.AllowCrossNamespaceImport != nil { - in, out := &in.AllowCrossNamespaceImport, &out.AllowCrossNamespaceImport - *out = new(bool) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaContactPointSpec. @@ -829,6 +835,7 @@ func (in *GrafanaDashboardList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaDashboardSpec) DeepCopyInto(out *GrafanaDashboardSpec) { *out = *in + in.GrafanaCommonSpec.DeepCopyInto(&out.GrafanaCommonSpec) if in.GzipJson != nil { in, out := &in.GzipJson, &out.GzipJson *out = make([]byte, len(*in)) @@ -854,11 +861,6 @@ func (in *GrafanaDashboardSpec) DeepCopyInto(out *GrafanaDashboardSpec) { *out = new(v1.ConfigMapKeySelector) (*in).DeepCopyInto(*out) } - if in.InstanceSelector != nil { - in, out := &in.InstanceSelector, &out.InstanceSelector - *out = new(metav1.LabelSelector) - (*in).DeepCopyInto(*out) - } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make(PluginList, len(*in)) @@ -870,11 +872,6 @@ func (in *GrafanaDashboardSpec) DeepCopyInto(out *GrafanaDashboardSpec) { *out = make([]GrafanaDashboardDatasource, len(*in)) copy(*out, *in) } - if in.AllowCrossNamespaceImport != nil { - in, out := &in.AllowCrossNamespaceImport, &out.AllowCrossNamespaceImport - *out = new(bool) - **out = **in - } if in.Envs != nil { in, out := &in.Envs, &out.Envs *out = make([]GrafanaDashboardEnv, len(*in)) @@ -1082,16 +1079,12 @@ func (in *GrafanaDatasourceList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaDatasourceSpec) DeepCopyInto(out *GrafanaDatasourceSpec) { *out = *in + in.GrafanaCommonSpec.DeepCopyInto(&out.GrafanaCommonSpec) if in.Datasource != nil { in, out := &in.Datasource, &out.Datasource *out = new(GrafanaDatasourceInternal) (*in).DeepCopyInto(*out) } - if in.InstanceSelector != nil { - in, out := &in.InstanceSelector, &out.InstanceSelector - *out = new(metav1.LabelSelector) - (*in).DeepCopyInto(*out) - } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make(PluginList, len(*in)) @@ -1104,11 +1097,6 @@ func (in *GrafanaDatasourceSpec) DeepCopyInto(out *GrafanaDatasourceSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.AllowCrossNamespaceImport != nil { - in, out := &in.AllowCrossNamespaceImport, &out.AllowCrossNamespaceImport - *out = new(bool) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaDatasourceSpec. @@ -1199,16 +1187,7 @@ func (in *GrafanaFolderList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaFolderSpec) DeepCopyInto(out *GrafanaFolderSpec) { *out = *in - if in.InstanceSelector != nil { - in, out := &in.InstanceSelector, &out.InstanceSelector - *out = new(metav1.LabelSelector) - (*in).DeepCopyInto(*out) - } - if in.AllowCrossNamespaceImport != nil { - in, out := &in.AllowCrossNamespaceImport, &out.AllowCrossNamespaceImport - *out = new(bool) - **out = **in - } + in.GrafanaCommonSpec.DeepCopyInto(&out.GrafanaCommonSpec) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaFolderSpec. @@ -1338,12 +1317,7 @@ func (in *GrafanaNotificationPolicyList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GrafanaNotificationPolicySpec) DeepCopyInto(out *GrafanaNotificationPolicySpec) { *out = *in - out.ResyncPeriod = in.ResyncPeriod - if in.InstanceSelector != nil { - in, out := &in.InstanceSelector, &out.InstanceSelector - *out = new(metav1.LabelSelector) - (*in).DeepCopyInto(*out) - } + in.GrafanaCommonSpec.DeepCopyInto(&out.GrafanaCommonSpec) if in.Route != nil { in, out := &in.Route, &out.Route *out = new(Route) diff --git a/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml b/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml index cce7dc33c..79cccd919 100644 --- a/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml +++ b/config/crd/bases/grafana.integreatly.org_grafanaalertrulegroups.yaml @@ -43,6 +43,8 @@ spec: description: GrafanaAlertRuleGroupSpec defines the desired state of GrafanaAlertRuleGroup properties: allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean editable: description: Whether to enable or disable editing of the alert rule @@ -60,7 +62,7 @@ spec: Overrides the FolderSelector type: string instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -106,7 +108,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf interval: format: duration @@ -117,7 +119,9 @@ spec: name will be used. type: string resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/config/crd/bases/grafana.integreatly.org_grafanacontactpoints.yaml b/config/crd/bases/grafana.integreatly.org_grafanacontactpoints.yaml index 056320b0e..0119938cd 100644 --- a/config/crd/bases/grafana.integreatly.org_grafanacontactpoints.yaml +++ b/config/crd/bases/grafana.integreatly.org_grafanacontactpoints.yaml @@ -43,11 +43,13 @@ spec: description: GrafanaContactPointSpec defines the desired state of GrafanaContactPoint properties: allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean disableResolveMessage: type: boolean instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -93,12 +95,14 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf name: type: string resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/config/crd/bases/grafana.integreatly.org_grafanadashboards.yaml b/config/crd/bases/grafana.integreatly.org_grafanadashboards.yaml index 0c4113303..29d8349f2 100644 --- a/config/crd/bases/grafana.integreatly.org_grafanadashboards.yaml +++ b/config/crd/bases/grafana.integreatly.org_grafanadashboards.yaml @@ -53,8 +53,8 @@ spec: description: GrafanaDashboardSpec defines the desired state of GrafanaDashboard properties: allowCrossNamespaceImport: - description: allow to import this resources from an operator in a - different namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean configMapRef: description: dashboard from configmap @@ -238,7 +238,7 @@ spec: format: byte type: string instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -284,7 +284,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf json: description: dashboard json @@ -322,9 +322,9 @@ spec: type: object type: array resyncPeriod: - default: 5m - description: how often the dashboard is refreshed, defaults to 5m - if not set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/config/crd/bases/grafana.integreatly.org_grafanadatasources.yaml b/config/crd/bases/grafana.integreatly.org_grafanadatasources.yaml index 28596b2a5..86de49754 100644 --- a/config/crd/bases/grafana.integreatly.org_grafanadatasources.yaml +++ b/config/crd/bases/grafana.integreatly.org_grafanadatasources.yaml @@ -53,8 +53,8 @@ spec: description: GrafanaDatasourceSpec defines the desired state of GrafanaDatasource properties: allowCrossNamespaceImport: - description: allow to import this resources from an operator in a - different namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean datasource: properties: @@ -95,7 +95,7 @@ spec: type: string type: object instanceSelector: - description: selects Grafana instances for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -141,7 +141,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf plugins: description: plugins @@ -157,9 +157,9 @@ spec: type: object type: array resyncPeriod: - default: 5m - description: how often the datasource is refreshed, defaults to 5m - if not set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/config/crd/bases/grafana.integreatly.org_grafanafolders.yaml b/config/crd/bases/grafana.integreatly.org_grafanafolders.yaml index 080826c69..39d98e19d 100644 --- a/config/crd/bases/grafana.integreatly.org_grafanafolders.yaml +++ b/config/crd/bases/grafana.integreatly.org_grafanafolders.yaml @@ -49,11 +49,11 @@ spec: description: GrafanaFolderSpec defines the desired state of GrafanaFolder properties: allowCrossNamespaceImport: - description: Enable matching Grafana instances outside the current - namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean instanceSelector: - description: Selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -99,7 +99,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf parentFolderRef: description: Reference to an existing GrafanaFolder CR in the same @@ -114,9 +114,9 @@ spec: from Grafana type: string resyncPeriod: - default: 5m - description: How often the folder is synced, defaults to 5m if not - set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/config/crd/bases/grafana.integreatly.org_grafananotificationpolicies.yaml b/config/crd/bases/grafana.integreatly.org_grafananotificationpolicies.yaml index 9270f4559..f7cb57d81 100644 --- a/config/crd/bases/grafana.integreatly.org_grafananotificationpolicies.yaml +++ b/config/crd/bases/grafana.integreatly.org_grafananotificationpolicies.yaml @@ -43,6 +43,10 @@ spec: description: GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPolicy properties: + allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace + type: boolean editable: description: Whether to enable or disable editing of the notification policy in Grafana UI @@ -51,7 +55,7 @@ spec: - message: Value is immutable rule: self == oldSelf instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -97,10 +101,12 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/controllers/dashboard_controller.go b/controllers/dashboard_controller.go index 210380b79..fb85ef0d6 100644 --- a/controllers/dashboard_controller.go +++ b/controllers/dashboard_controller.go @@ -289,7 +289,7 @@ func (r *GrafanaDashboardReconciler) Reconcile(ctx context.Context, req ctrl.Req } cr.Status.Hash = hash cr.Status.UID = uid - return ctrl.Result{RequeueAfter: cr.GetResyncPeriod()}, r.Client.Status().Update(ctx, cr) + return ctrl.Result{RequeueAfter: cr.Spec.ResyncPeriod.Duration}, r.Client.Status().Update(ctx, cr) } return ctrl.Result{RequeueAfter: RequeueDelay}, nil diff --git a/controllers/dashboard_controller_test.go b/controllers/dashboard_controller_test.go index f14f919d3..a93495a99 100644 --- a/controllers/dashboard_controller_test.go +++ b/controllers/dashboard_controller_test.go @@ -42,9 +42,11 @@ func TestGetDashboardsToDelete(t *testing.T) { Namespace: "grafana-operator-system", }, Spec: v1beta1.GrafanaDashboardSpec{ - InstanceSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "dashboard": "external", + GrafanaCommonSpec: v1beta1.GrafanaCommonSpec{ + InstanceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "dashboard": "external", + }, }, }, }, @@ -56,9 +58,11 @@ func TestGetDashboardsToDelete(t *testing.T) { Namespace: "grafana-operator-system", }, Spec: v1beta1.GrafanaDashboardSpec{ - InstanceSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "dashboard": "internal", + GrafanaCommonSpec: v1beta1.GrafanaCommonSpec{ + InstanceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "dashboard": "external", + }, }, }, }, diff --git a/controllers/datasource_controller.go b/controllers/datasource_controller.go index c99a3cc66..951d27e5b 100644 --- a/controllers/datasource_controller.go +++ b/controllers/datasource_controller.go @@ -262,7 +262,7 @@ func (r *GrafanaDatasourceReconciler) Reconcile(ctx context.Context, req ctrl.Re cr.Status.LastResync = metav1.Time{Time: time.Now()} } cr.Status.UID = cr.CustomUIDOrUID() - return ctrl.Result{RequeueAfter: cr.GetResyncPeriod()}, r.Client.Status().Update(ctx, cr) + return ctrl.Result{RequeueAfter: cr.Spec.ResyncPeriod.Duration}, r.Client.Status().Update(ctx, cr) } else { // if there was an issue with the datasource, update the status return ctrl.Result{RequeueAfter: RequeueDelay}, r.Client.Status().Update(ctx, cr) diff --git a/controllers/grafanafolder_controller.go b/controllers/grafanafolder_controller.go index 139b44cde..0f3ddb034 100644 --- a/controllers/grafanafolder_controller.go +++ b/controllers/grafanafolder_controller.go @@ -238,7 +238,7 @@ func (r *GrafanaFolderReconciler) Reconcile(ctx context.Context, req ctrl.Reques if folder.ResyncPeriodHasElapsed() { folder.Status.LastResync = metav1.Time{Time: time.Now()} } - return ctrl.Result{RequeueAfter: folder.GetResyncPeriod()}, nil + return ctrl.Result{RequeueAfter: folder.Spec.ResyncPeriod.Duration}, nil } // SetupWithManager sets up the controller with the Manager. diff --git a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml index cce7dc33c..79cccd919 100644 --- a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml +++ b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanaalertrulegroups.yaml @@ -43,6 +43,8 @@ spec: description: GrafanaAlertRuleGroupSpec defines the desired state of GrafanaAlertRuleGroup properties: allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean editable: description: Whether to enable or disable editing of the alert rule @@ -60,7 +62,7 @@ spec: Overrides the FolderSelector type: string instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -106,7 +108,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf interval: format: duration @@ -117,7 +119,9 @@ spec: name will be used. type: string resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanacontactpoints.yaml b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanacontactpoints.yaml index 056320b0e..0119938cd 100644 --- a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanacontactpoints.yaml +++ b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanacontactpoints.yaml @@ -43,11 +43,13 @@ spec: description: GrafanaContactPointSpec defines the desired state of GrafanaContactPoint properties: allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean disableResolveMessage: type: boolean instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -93,12 +95,14 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf name: type: string resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadashboards.yaml b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadashboards.yaml index 0c4113303..29d8349f2 100644 --- a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadashboards.yaml +++ b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadashboards.yaml @@ -53,8 +53,8 @@ spec: description: GrafanaDashboardSpec defines the desired state of GrafanaDashboard properties: allowCrossNamespaceImport: - description: allow to import this resources from an operator in a - different namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean configMapRef: description: dashboard from configmap @@ -238,7 +238,7 @@ spec: format: byte type: string instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -284,7 +284,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf json: description: dashboard json @@ -322,9 +322,9 @@ spec: type: object type: array resyncPeriod: - default: 5m - description: how often the dashboard is refreshed, defaults to 5m - if not set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadatasources.yaml b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadatasources.yaml index 28596b2a5..86de49754 100644 --- a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadatasources.yaml +++ b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanadatasources.yaml @@ -53,8 +53,8 @@ spec: description: GrafanaDatasourceSpec defines the desired state of GrafanaDatasource properties: allowCrossNamespaceImport: - description: allow to import this resources from an operator in a - different namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean datasource: properties: @@ -95,7 +95,7 @@ spec: type: string type: object instanceSelector: - description: selects Grafana instances for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -141,7 +141,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf plugins: description: plugins @@ -157,9 +157,9 @@ spec: type: object type: array resyncPeriod: - default: 5m - description: how often the datasource is refreshed, defaults to 5m - if not set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanafolders.yaml b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanafolders.yaml index 080826c69..39d98e19d 100644 --- a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanafolders.yaml +++ b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafanafolders.yaml @@ -49,11 +49,11 @@ spec: description: GrafanaFolderSpec defines the desired state of GrafanaFolder properties: allowCrossNamespaceImport: - description: Enable matching Grafana instances outside the current - namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean instanceSelector: - description: Selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -99,7 +99,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf parentFolderRef: description: Reference to an existing GrafanaFolder CR in the same @@ -114,9 +114,9 @@ spec: from Grafana type: string resyncPeriod: - default: 5m - description: How often the folder is synced, defaults to 5m if not - set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafananotificationpolicies.yaml b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafananotificationpolicies.yaml index 9270f4559..f7cb57d81 100644 --- a/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafananotificationpolicies.yaml +++ b/deploy/helm/grafana-operator/crds/grafana.integreatly.org_grafananotificationpolicies.yaml @@ -43,6 +43,10 @@ spec: description: GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPolicy properties: + allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace + type: boolean editable: description: Whether to enable or disable editing of the notification policy in Grafana UI @@ -51,7 +55,7 @@ spec: - message: Value is immutable rule: self == oldSelf instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -97,10 +101,12 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/deploy/kustomize/base/crds.yaml b/deploy/kustomize/base/crds.yaml index f8ad98dc9..025b8b262 100644 --- a/deploy/kustomize/base/crds.yaml +++ b/deploy/kustomize/base/crds.yaml @@ -42,6 +42,8 @@ spec: description: GrafanaAlertRuleGroupSpec defines the desired state of GrafanaAlertRuleGroup properties: allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean editable: description: Whether to enable or disable editing of the alert rule @@ -59,7 +61,7 @@ spec: Overrides the FolderSelector type: string instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -105,7 +107,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf interval: format: duration @@ -116,7 +118,9 @@ spec: name will be used. type: string resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string @@ -354,11 +358,13 @@ spec: description: GrafanaContactPointSpec defines the desired state of GrafanaContactPoint properties: allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean disableResolveMessage: type: boolean instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -404,12 +410,14 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf name: type: string resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string @@ -646,8 +654,8 @@ spec: description: GrafanaDashboardSpec defines the desired state of GrafanaDashboard properties: allowCrossNamespaceImport: - description: allow to import this resources from an operator in a - different namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean configMapRef: description: dashboard from configmap @@ -831,7 +839,7 @@ spec: format: byte type: string instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -877,7 +885,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf json: description: dashboard json @@ -915,9 +923,9 @@ spec: type: object type: array resyncPeriod: - default: 5m - description: how often the dashboard is refreshed, defaults to 5m - if not set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string @@ -1141,8 +1149,8 @@ spec: description: GrafanaDatasourceSpec defines the desired state of GrafanaDatasource properties: allowCrossNamespaceImport: - description: allow to import this resources from an operator in a - different namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean datasource: properties: @@ -1183,7 +1191,7 @@ spec: type: string type: object instanceSelector: - description: selects Grafana instances for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -1229,7 +1237,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf plugins: description: plugins @@ -1245,9 +1253,9 @@ spec: type: object type: array resyncPeriod: - default: 5m - description: how often the datasource is refreshed, defaults to 5m - if not set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string @@ -1406,11 +1414,11 @@ spec: description: GrafanaFolderSpec defines the desired state of GrafanaFolder properties: allowCrossNamespaceImport: - description: Enable matching Grafana instances outside the current - namespace + description: Allow the Operator to match this resource with Grafanas + outside the current namespace type: boolean instanceSelector: - description: Selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -1456,7 +1464,7 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf parentFolderRef: description: Reference to an existing GrafanaFolder CR in the same @@ -1471,9 +1479,9 @@ spec: from Grafana type: string resyncPeriod: - default: 5m - description: How often the folder is synced, defaults to 5m if not - set + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string @@ -1620,6 +1628,10 @@ spec: description: GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPolicy properties: + allowCrossNamespaceImport: + description: Allow the Operator to match this resource with Grafanas + outside the current namespace + type: boolean editable: description: Whether to enable or disable editing of the notification policy in Grafana UI @@ -1628,7 +1640,7 @@ spec: - message: Value is immutable rule: self == oldSelf instanceSelector: - description: selects Grafanas for import + description: Selects Grafana instances for import properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -1674,10 +1686,12 @@ spec: type: object x-kubernetes-map-type: atomic x-kubernetes-validations: - - message: Value is immutable + - message: spec.instanceSelector is immutable rule: self == oldSelf resyncPeriod: - default: 10m + default: 10m0s + description: How often the resource is synced, defaults to 10m0s if + not set format: duration pattern: ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ type: string diff --git a/docs/docs/api.md b/docs/docs/api.md index a5d283a5f..149d955d3 100644 --- a/docs/docs/api.md +++ b/docs/docs/api.md @@ -104,9 +104,9 @@ GrafanaAlertRuleGroupSpec defines the desired state of GrafanaAlertRuleGroup instanceSelector object - selects Grafanas for import
+ Selects Grafana instances for import

- Validations:
  • self == oldSelf: Value is immutable
  • + Validations:
  • self == oldSelf: spec.instanceSelector is immutable
  • true @@ -129,7 +129,7 @@ GrafanaAlertRuleGroupSpec defines the desired state of GrafanaAlertRuleGroup allowCrossNamespaceImport boolean -
    + Allow the Operator to match this resource with Grafanas outside the current namespace
    false @@ -167,10 +167,10 @@ Overrides the FolderSelector
    resyncPeriod string -
    + How often the resource is synced, defaults to 10m0s if not set

    Format: duration
    - Default: 10m
    + Default: 10m0s
    false @@ -182,7 +182,7 @@ Overrides the FolderSelector
    -selects Grafanas for import +Selects Grafana instances for import @@ -697,9 +697,9 @@ GrafanaContactPointSpec defines the desired state of GrafanaContactPoint @@ -720,7 +720,7 @@ GrafanaContactPointSpec defines the desired state of GrafanaContactPoint @@ -734,10 +734,10 @@ GrafanaContactPointSpec defines the desired state of GrafanaContactPoint @@ -774,7 +774,7 @@ GrafanaContactPointSpec defines the desired state of GrafanaContactPoint -selects Grafanas for import +Selects Grafana instances for import
    instanceSelector object - selects Grafanas for import
    + Selects Grafana instances for import

    - Validations:
  • self == oldSelf: Value is immutable
  • + Validations:
  • self == oldSelf: spec.instanceSelector is immutable
  • true
    allowCrossNamespaceImport boolean -
    + Allow the Operator to match this resource with Grafanas outside the current namespace
    false
    resyncPeriod string -
    + How often the resource is synced, defaults to 10m0s if not set

    Format: duration
    - Default: 10m
    + Default: 10m0s
    false
    @@ -1195,16 +1195,16 @@ GrafanaDashboardSpec defines the desired state of GrafanaDashboard @@ -1311,10 +1311,10 @@ GrafanaDashboardSpec defines the desired state of GrafanaDashboard @@ -1349,7 +1349,7 @@ GrafanaDashboardSpec defines the desired state of GrafanaDashboard -selects Grafanas for import +Selects Grafana instances for import
    instanceSelector object - selects Grafanas for import
    + Selects Grafana instances for import

    - Validations:
  • self == oldSelf: Value is immutable
  • + Validations:
  • self == oldSelf: spec.instanceSelector is immutable
  • true
    allowCrossNamespaceImport boolean - allow to import this resources from an operator in a different namespace
    + Allow the Operator to match this resource with Grafanas outside the current namespace
    false
    resyncPeriod string - how often the dashboard is refreshed, defaults to 5m if not set
    + How often the resource is synced, defaults to 10m0s if not set

    Format: duration
    - Default: 5m
    + Default: 10m0s
    false
    @@ -2311,16 +2311,16 @@ GrafanaDatasourceSpec defines the desired state of GrafanaDatasource @@ -2334,10 +2334,10 @@ GrafanaDatasourceSpec defines the desired state of GrafanaDatasource @@ -2485,7 +2485,7 @@ GrafanaDatasourceSpec defines the desired state of GrafanaDatasource -selects Grafana instances for import +Selects Grafana instances for import
    instanceSelector object - selects Grafana instances for import
    + Selects Grafana instances for import

    - Validations:
  • self == oldSelf: Value is immutable
  • + Validations:
  • self == oldSelf: spec.instanceSelector is immutable
  • true
    allowCrossNamespaceImport boolean - allow to import this resources from an operator in a different namespace
    + Allow the Operator to match this resource with Grafanas outside the current namespace
    false
    resyncPeriod string - how often the datasource is refreshed, defaults to 5m if not set
    + How often the resource is synced, defaults to 10m0s if not set

    Format: duration
    - Default: 5m
    + Default: 10m0s
    false
    @@ -2892,16 +2892,16 @@ GrafanaFolderSpec defines the desired state of GrafanaFolder @@ -2929,10 +2929,10 @@ GrafanaFolderSpec defines the desired state of GrafanaFolder @@ -2960,7 +2960,7 @@ GrafanaFolderSpec defines the desired state of GrafanaFolder -Selects Grafanas for import +Selects Grafana instances for import
    instanceSelector object - Selects Grafanas for import
    + Selects Grafana instances for import

    - Validations:
  • self == oldSelf: Value is immutable
  • + Validations:
  • self == oldSelf: spec.instanceSelector is immutable
  • true
    allowCrossNamespaceImport boolean - Enable matching Grafana instances outside the current namespace
    + Allow the Operator to match this resource with Grafanas outside the current namespace
    false
    resyncPeriod string - How often the folder is synced, defaults to 5m if not set
    + How often the resource is synced, defaults to 10m0s if not set

    Format: duration
    - Default: 5m
    + Default: 10m0s
    false
    @@ -3240,9 +3240,9 @@ GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPo @@ -3252,6 +3252,13 @@ GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPo Routes for alerts to match against
    + + + + + @@ -3265,10 +3272,10 @@ GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPo @@ -3280,7 +3287,7 @@ GrafanaNotificationPolicySpec defines the desired state of GrafanaNotificationPo -selects Grafanas for import +Selects Grafana instances for import
    instanceSelector object - selects Grafanas for import
    + Selects Grafana instances for import

    - Validations:
  • self == oldSelf: Value is immutable
  • + Validations:
  • self == oldSelf: spec.instanceSelector is immutable
  • true
    true
    allowCrossNamespaceImportboolean + Allow the Operator to match this resource with Grafanas outside the current namespace
    +
    false
    editable booleanresyncPeriod string -
    + How often the resource is synced, defaults to 10m0s if not set

    Format: duration
    - Default: 10m
    + Default: 10m0s
    false