From d4c52f4ef772420a09e1d25106312f7a9dbcb62b Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Tue, 7 Jan 2025 15:54:39 -0500 Subject: [PATCH 01/14] Remove Requirements for UIPlugin > monitoring > thanosQuerier and alertManager. This is because we want to be able to have the options of creating a Perses proxy only and not include thanosQuerier and the alertManager. --- .../manifests/observability.openshift.io_uiplugins.yaml | 8 +------- .../crds/common/observability.openshift.io_uiplugins.yaml | 4 ---- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/bundle/manifests/observability.openshift.io_uiplugins.yaml b/bundle/manifests/observability.openshift.io_uiplugins.yaml index c302643a4..641503eb2 100644 --- a/bundle/manifests/observability.openshift.io_uiplugins.yaml +++ b/bundle/manifests/observability.openshift.io_uiplugins.yaml @@ -152,8 +152,6 @@ spec: description: Url of the Alertmanager to proxy to. minLength: 1 type: string - required: - - url type: object x-kubernetes-map-type: atomic thanosQuerier: @@ -164,13 +162,9 @@ spec: description: Url of the ThanosQuerier to proxy to. minLength: 1 type: string - required: - - url type: object x-kubernetes-map-type: atomic - required: - - alertmanager - - thanosQuerier + type: object troubleshootingPanel: description: TroubleshootingPanel contains configuration for the troubleshooting diff --git a/deploy/crds/common/observability.openshift.io_uiplugins.yaml b/deploy/crds/common/observability.openshift.io_uiplugins.yaml index 238a79a94..4f335ee4d 100644 --- a/deploy/crds/common/observability.openshift.io_uiplugins.yaml +++ b/deploy/crds/common/observability.openshift.io_uiplugins.yaml @@ -152,8 +152,6 @@ spec: description: Url of the Alertmanager to proxy to. minLength: 1 type: string - required: - - url type: object x-kubernetes-map-type: atomic thanosQuerier: @@ -164,8 +162,6 @@ spec: description: Url of the ThanosQuerier to proxy to. minLength: 1 type: string - required: - - url type: object x-kubernetes-map-type: atomic required: From 4055b0e6c22e3a1e47e88054704fdb85360f1522 Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Thu, 9 Jan 2025 13:51:19 -0500 Subject: [PATCH 02/14] Add perses-dashboards to compatbility matrix and test --- .../uiplugin/compatibility_matrix.go | 25 ++++++++ .../uiplugin/compatibility_matrix_test.go | 58 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/pkg/controllers/uiplugin/compatibility_matrix.go b/pkg/controllers/uiplugin/compatibility_matrix.go index 4b8bc2dce..97c923d10 100644 --- a/pkg/controllers/uiplugin/compatibility_matrix.go +++ b/pkg/controllers/uiplugin/compatibility_matrix.go @@ -120,6 +120,31 @@ var compatibilityMatrix = []CompatibilityEntry{ "dev-alerts", }, }, + { + PluginType: uiv1alpha1.TypeMonitoring, + MinClusterVersion: "v4.19", + MaxClusterVersion: "", + ImageKey: "ui-monitoring", + MinAcmVersion: "v2.11", + MaxAcmVersion: "", + SupportLevel: DevPreview, + Features: []string{ + "perses-dashboards", + "acm-alerting", + }, + }, + { + PluginType: uiv1alpha1.TypeMonitoring, + MinClusterVersion: "v4.19", + MaxClusterVersion: "", + ImageKey: "ui-monitoring", + MinAcmVersion: "", + MaxAcmVersion: "", + SupportLevel: DevPreview, + Features: []string{ + "perses-dashboards", + }, + }, { PluginType: uiv1alpha1.TypeMonitoring, MinClusterVersion: "v4.14", diff --git a/pkg/controllers/uiplugin/compatibility_matrix_test.go b/pkg/controllers/uiplugin/compatibility_matrix_test.go index 4952faceb..ed33b29d4 100644 --- a/pkg/controllers/uiplugin/compatibility_matrix_test.go +++ b/pkg/controllers/uiplugin/compatibility_matrix_test.go @@ -2,6 +2,7 @@ package uiplugin import ( "fmt" + "log" "testing" "golang.org/x/mod/semver" @@ -29,6 +30,15 @@ func TestCompatibilityMatrixVersions(t *testing.T) { } } +func contains(array []string, value string) bool { + for _, v := range array { + if v == value { + return true + } + } + return false +} + // Ensure that there's only one empty max version per plugin. func TestCompatibilityMatrixMaxVersions(t *testing.T) { cm := map[uiv1alpha1.UIPluginType]struct{}{} @@ -37,6 +47,11 @@ func TestCompatibilityMatrixMaxVersions(t *testing.T) { continue } + // exception for montioring-plugin usage of perses-dashboards + if v.PluginType == "Monitoring" && contains(v.Features, "perses-dashboards") { + continue + } + _, found := cm[v.PluginType] assert.Assert(t, !found, string(v.PluginType)) cm[v.PluginType] = struct{}{} @@ -242,6 +257,46 @@ func TestLookupImageAndFeatures(t *testing.T) { expectedFeatures: []string{"acm-alerting"}, expectedErr: nil, }, + { + pluginType: uiv1alpha1.TypeMonitoring, + clusterVersion: "v4.19", + acmVersion: "v2.11.3", + expectedKey: "ui-monitoring", + expectedFeatures: []string{"perses-dashboards", "acm-alerting"}, + expectedErr: nil, + }, + { + pluginType: uiv1alpha1.TypeMonitoring, + clusterVersion: "v4.19.0-0.nightly-2024-06-06-064349", + acmVersion: "v2.11.3", + expectedKey: "ui-monitoring", + expectedFeatures: []string{"perses-dashboards", "acm-alerting"}, + expectedErr: nil, + }, + { + pluginType: uiv1alpha1.TypeMonitoring, + clusterVersion: "v4.19", + acmVersion: "", + expectedKey: "ui-monitoring", + expectedFeatures: []string{"perses-dashboards"}, + expectedErr: nil, + }, + { + pluginType: uiv1alpha1.TypeMonitoring, + clusterVersion: "v4.19.0-0.nightly-2024-06-06-064349", + acmVersion: "", + expectedKey: "ui-monitoring", + expectedFeatures: []string{"perses-dashboards"}, + expectedErr: nil, + }, + { + pluginType: uiv1alpha1.TypeMonitoring, + clusterVersion: "v4.19", + acmVersion: "v2.10", + expectedKey: "ui-monitoring", + expectedFeatures: []string{"perses-dashboards"}, + expectedErr: nil, + }, } { t.Run(fmt.Sprintf("%s/%s", tc.pluginType, tc.clusterVersion), func(t *testing.T) { info, err := lookupImageAndFeatures(tc.pluginType, tc.clusterVersion, tc.acmVersion) @@ -253,6 +308,9 @@ func TestLookupImageAndFeatures(t *testing.T) { assert.NilError(t, err) + log.Printf("expected Features: %s", tc.expectedFeatures) + log.Printf("Features: %s", info.Features) + t.Logf("%s == %s", tc.expectedKey, info.ImageKey) assert.Equal(t, tc.expectedKey, info.ImageKey) From 5738f0c5c254157a5e1ff6640bbffc8c9d5327ad Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Thu, 9 Jan 2025 18:25:09 -0500 Subject: [PATCH 03/14] Add Perses Dashboards Proxy QUESTION : where is the perses dashboard proxy URL coming from, we may need to adjust the code because right now it assumes it is in plugin.Spec.Montioring --- pkg/apis/uiplugin/v1alpha1/types.go | 17 +++++ .../uiplugin/compatibility_matrix_test.go | 9 --- pkg/controllers/uiplugin/monitoring.go | 41 +++++++++++ pkg/controllers/uiplugin/monitoring_test.go | 70 +++++++++++++++++++ pkg/controllers/uiplugin/utils.go | 10 +++ 5 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 pkg/controllers/uiplugin/monitoring_test.go create mode 100644 pkg/controllers/uiplugin/utils.go diff --git a/pkg/apis/uiplugin/v1alpha1/types.go b/pkg/apis/uiplugin/v1alpha1/types.go index e5c408de3..d28d112cb 100644 --- a/pkg/apis/uiplugin/v1alpha1/types.go +++ b/pkg/apis/uiplugin/v1alpha1/types.go @@ -146,6 +146,11 @@ type MonitoringConfig struct { // // +kubebuilder:validation:Required ThanosQuerier ThanosQuerierReference `json:"thanosQuerier"` + + // PersesDashboards points to the perses-dashboards service of which it should create a proxy to. + // + // +kubebuilder:validation:Required + PersesDashboards PersesDashboardsReference `json:"persesDashboards"` } // Alertmanager is used to configure a reference to a alertmanage that should be used @@ -172,6 +177,18 @@ type ThanosQuerierReference struct { Url string `json:"url"` } +// PersesDashboards is used to configure a reference to a perses-dashbaords service that should be used +// by the monitoring console plugin. +// +// +structType=atomic +type PersesDashboardsReference struct { + // Url of the ThanosQuerier to proxy to. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength:=1 + Url string `json:"url"` +} + // UIPluginSpec is the specification for desired state of UIPlugin. // // +kubebuilder:validation:XValidation:rule="self.type == 'TroubleshootingPanel' || !has(self.troubleshootingPanel)", message="Troubleshooting Panel configuration is only supported with the TroubleshootingPanel type" diff --git a/pkg/controllers/uiplugin/compatibility_matrix_test.go b/pkg/controllers/uiplugin/compatibility_matrix_test.go index ed33b29d4..4631f6b87 100644 --- a/pkg/controllers/uiplugin/compatibility_matrix_test.go +++ b/pkg/controllers/uiplugin/compatibility_matrix_test.go @@ -30,15 +30,6 @@ func TestCompatibilityMatrixVersions(t *testing.T) { } } -func contains(array []string, value string) bool { - for _, v := range array { - if v == value { - return true - } - } - return false -} - // Ensure that there's only one empty max version per plugin. func TestCompatibilityMatrixMaxVersions(t *testing.T) { cm := map[uiv1alpha1.UIPluginType]struct{}{} diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index 29e9e712e..2032d3d09 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -15,6 +15,7 @@ import ( func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, image string, features []string) (*UIPluginInfo, error) { config := plugin.Spec.Monitoring + persesDashboardsFeatureEnabled := contains(features, "perses-dashboards") if config == nil { return nil, fmt.Errorf("monitoring configuration can not be empty for plugin type %s", plugin.Spec.Type) } @@ -25,6 +26,10 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im if config.ThanosQuerier.Url == "" { return nil, fmt.Errorf("ThanosQuerier location can not be empty for plugin type %s", plugin.Spec.Type) } + // JZ OPEN QUESTION : Where is the PerseDashboards service URL coming from? + if persesDashboardsFeatureEnabled && config.PersesDashboards.Url == "" { + return nil, fmt.Errorf("PersesDashboards location can not be empty for plugin type %s", plugin.Spec.Type) + } pluginInfo := &UIPluginInfo{ Image: image, @@ -111,6 +116,35 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im }, } + if persesDashboardsFeatureEnabled { + // JZ OPEN QUESTION: Need to align on PORT number, name, and namespace...with Perses Operator? + proxy := osv1.ConsolePluginProxy{ + Alias: "perses-dashboards-proxy", + Authorization: "UserToken", + Endpoint: osv1.ConsolePluginProxyEndpoint{ + Type: osv1.ProxyTypeService, + Service: &osv1.ConsolePluginProxyServiceConfig{ + Name: name, + Namespace: namespace, + Port: 9446, + }, + }, + } + legacyProxy := osv1alpha1.ConsolePluginProxy{ + Type: "Service", + Alias: "perses-dashboards-proxy", + Authorize: true, + Service: osv1alpha1.ConsolePluginProxyServiceConfig{ + Name: name, + Namespace: namespace, + Port: 9446, + }, + } + pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards=%s", config.PersesDashboards.Url)) + pluginInfo.Proxies = append(pluginInfo.Proxies, proxy) + pluginInfo.LegacyProxies = append(pluginInfo.LegacyProxies, legacyProxy) + } + return pluginInfo, nil } @@ -150,6 +184,13 @@ func newMonitoringService(name string, namespace string) *corev1.Service { Protocol: corev1.ProtocolTCP, TargetPort: intstr.FromInt32(9445), }, + // JZ OPEN QUESTION: Need to align on PORT number...with Perses Operator? + { + Port: 9446, + Name: "perses-dashboards-proxy", + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt32(9446), + }, }, Selector: componentLabels(name), Type: corev1.ServiceTypeClusterIP, diff --git a/pkg/controllers/uiplugin/monitoring_test.go b/pkg/controllers/uiplugin/monitoring_test.go new file mode 100644 index 000000000..136c93307 --- /dev/null +++ b/pkg/controllers/uiplugin/monitoring_test.go @@ -0,0 +1,70 @@ +package uiplugin + +import ( + "encoding/json" + "fmt" + "log" + "testing" + + "gotest.tools/v3/assert" + + uiv1alpha1 "github.com/rhobs/observability-operator/pkg/apis/uiplugin/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var plugin = &uiv1alpha1.UIPlugin{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "observability.openshift.io/v1alpha1", + Kind: "UIPlugin", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "monitoring-plugin", + }, + Spec: uiv1alpha1.UIPluginSpec{ + Type: "monitoring", + + Monitoring: &uiv1alpha1.MonitoringConfig{ + Alertmanager: uiv1alpha1.AlertmanagerReference{ + Url: "https://alertmanager.open-cluster-management-observability.svc:9095", + }, + ThanosQuerier: uiv1alpha1.ThanosQuerierReference{ + Url: "https://rbac-query-proxy.open-cluster-management-observability.svc:8443", + }, + PersesDashboards: uiv1alpha1.PersesDashboardsReference{ + Url: "https://perses-dashboards.svc:8443", + }, + }, + }, +} +var namespace = "openshift-operators" +var name = "monitoring" +var image = "quay.io/monitoring-foo-test:123" +var features = []string{"perses-dashboards", "acm-alerting"} + +func TestCreateMonitoringPluginInfo(t *testing.T) { + t.Run("Test createMontiroingPluginInfo", func(t *testing.T) { + pluginInfo, _ := createMonitoringPluginInfo(plugin, namespace, name, image, features) + + containsPersesProxy := func() bool { + for _, proxy := range pluginInfo.Proxies { + if proxy.Alias == "perses-dashboards-proxy" { + return true + } + } + return false + } + + assert.Assert(t, containsPersesProxy() == true) + + // JZ TO REMOVE -- for testing only to output pluginInfo object + // prettyJSON, err := json.MarshalIndent(pluginInfo, "", " ") + // if err != nil { + // log.Fatalf("Error pretty printing JSON: %v", err) + // } + // if error != nil { + // log.Fatalf("Error pretty printing JSON: %v", err) + // } + // fmt.Println(string(prettyJSON)) + // assert.Equal(t, pluginInfo, true) + }) +} diff --git a/pkg/controllers/uiplugin/utils.go b/pkg/controllers/uiplugin/utils.go new file mode 100644 index 000000000..55cb12b7b --- /dev/null +++ b/pkg/controllers/uiplugin/utils.go @@ -0,0 +1,10 @@ +package uiplugin + +func contains(array []string, value string) bool { + for _, v := range array { + if v == value { + return true + } + } + return false +} From ea5d2a224baaaeefda7b85b496c7994966a00d1a Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 11:10:51 -0500 Subject: [PATCH 04/14] Adjust kubebuilder configs so that Alertmanager, Thanos Querier and PersesDashboards are not required attributes. Then run `make generate` to update CRDs (rather than manual editing). --- .../observability.openshift.io_uiplugins.yaml | 19 ++++++++-- docs/api.md | 38 ++++++++++++++++++- pkg/apis/uiplugin/v1alpha1/types.go | 6 +-- .../v1alpha1/zz_generated.deepcopy.go | 16 ++++++++ 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/deploy/crds/common/observability.openshift.io_uiplugins.yaml b/deploy/crds/common/observability.openshift.io_uiplugins.yaml index 4f335ee4d..01e6a340d 100644 --- a/deploy/crds/common/observability.openshift.io_uiplugins.yaml +++ b/deploy/crds/common/observability.openshift.io_uiplugins.yaml @@ -152,6 +152,20 @@ spec: description: Url of the Alertmanager to proxy to. minLength: 1 type: string + required: + - url + type: object + x-kubernetes-map-type: atomic + persesDashboards: + description: PersesDashboards points to the perses-dashboards + service of which it should create a proxy to. + properties: + url: + description: Url of the ThanosQuerier to proxy to. + minLength: 1 + type: string + required: + - url type: object x-kubernetes-map-type: atomic thanosQuerier: @@ -162,11 +176,10 @@ spec: description: Url of the ThanosQuerier to proxy to. minLength: 1 type: string + required: + - url type: object x-kubernetes-map-type: atomic - required: - - alertmanager - - thanosQuerier type: object troubleshootingPanel: description: TroubleshootingPanel contains configuration for the troubleshooting diff --git a/docs/api.md b/docs/api.md index 790ff4662..ebde9a1ca 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4173,14 +4173,21 @@ Monitoring contains configuration for the monitoring console plugin. Alertmanager points to the alertmanager instance of which it should create a proxy to.
- true + false + + persesDashboards + object + + PersesDashboards points to the perses-dashboards service of which it should create a proxy to.
+ + false thanosQuerier object ThanosQuerier points to the thanos-querier service of which it should create a proxy to.
- true + false @@ -4212,6 +4219,33 @@ Alertmanager points to the alertmanager instance of which it should create a pro +### UIPlugin.spec.monitoring.persesDashboards +[↩ Parent](#uipluginspecmonitoring) + + + +PersesDashboards points to the perses-dashboards service of which it should create a proxy to. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
urlstring + Url of the ThanosQuerier to proxy to.
+
true
+ + ### UIPlugin.spec.monitoring.thanosQuerier [↩ Parent](#uipluginspecmonitoring) diff --git a/pkg/apis/uiplugin/v1alpha1/types.go b/pkg/apis/uiplugin/v1alpha1/types.go index d28d112cb..015957567 100644 --- a/pkg/apis/uiplugin/v1alpha1/types.go +++ b/pkg/apis/uiplugin/v1alpha1/types.go @@ -139,17 +139,17 @@ type LokiStackReference struct { type MonitoringConfig struct { // Alertmanager points to the alertmanager instance of which it should create a proxy to. // - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional Alertmanager AlertmanagerReference `json:"alertmanager"` // ThanosQuerier points to the thanos-querier service of which it should create a proxy to. // - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional ThanosQuerier ThanosQuerierReference `json:"thanosQuerier"` // PersesDashboards points to the perses-dashboards service of which it should create a proxy to. // - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional PersesDashboards PersesDashboardsReference `json:"persesDashboards"` } diff --git a/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go index 2e35968fa..3dd7f381a 100644 --- a/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go @@ -136,6 +136,7 @@ func (in *MonitoringConfig) DeepCopyInto(out *MonitoringConfig) { *out = *in out.Alertmanager = in.Alertmanager out.ThanosQuerier = in.ThanosQuerier + out.PersesDashboards = in.PersesDashboards } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonitoringConfig. @@ -148,6 +149,21 @@ func (in *MonitoringConfig) DeepCopy() *MonitoringConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PersesDashboardsReference) DeepCopyInto(out *PersesDashboardsReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PersesDashboardsReference. +func (in *PersesDashboardsReference) DeepCopy() *PersesDashboardsReference { + if in == nil { + return nil + } + out := new(PersesDashboardsReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ThanosQuerierReference) DeepCopyInto(out *ThanosQuerierReference) { *out = *in From cacd54525039771fd1817a77e7689db2c96f9531 Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 11:17:08 -0500 Subject: [PATCH 05/14] Run `make bundle` to update uiplugins CRD /bundle/manifests/observability.openshift.io_uiplugins.yaml --- ...vability-operator.clusterserviceversion.yaml | 2 +- .../observability.openshift.io_uiplugins.yaml | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/bundle/manifests/observability-operator.clusterserviceversion.yaml b/bundle/manifests/observability-operator.clusterserviceversion.yaml index ccdd6420f..984913b1b 100644 --- a/bundle/manifests/observability-operator.clusterserviceversion.yaml +++ b/bundle/manifests/observability-operator.clusterserviceversion.yaml @@ -42,7 +42,7 @@ metadata: categories: Monitoring certified: "false" containerImage: observability-operator:1.0.0 - createdAt: "2024-12-11T10:22:00Z" + createdAt: "2025-01-13T16:14:17Z" description: A Go based Kubernetes operator to setup and manage highly available Monitoring Stack using Prometheus, Alertmanager and Thanos Querier. operatorframework.io/cluster-monitoring: "true" diff --git a/bundle/manifests/observability.openshift.io_uiplugins.yaml b/bundle/manifests/observability.openshift.io_uiplugins.yaml index 641503eb2..2d6cbf37d 100644 --- a/bundle/manifests/observability.openshift.io_uiplugins.yaml +++ b/bundle/manifests/observability.openshift.io_uiplugins.yaml @@ -152,6 +152,20 @@ spec: description: Url of the Alertmanager to proxy to. minLength: 1 type: string + required: + - url + type: object + x-kubernetes-map-type: atomic + persesDashboards: + description: PersesDashboards points to the perses-dashboards + service of which it should create a proxy to. + properties: + url: + description: Url of the ThanosQuerier to proxy to. + minLength: 1 + type: string + required: + - url type: object x-kubernetes-map-type: atomic thanosQuerier: @@ -162,9 +176,10 @@ spec: description: Url of the ThanosQuerier to proxy to. minLength: 1 type: string + required: + - url type: object x-kubernetes-map-type: atomic - type: object troubleshootingPanel: description: TroubleshootingPanel contains configuration for the troubleshooting From 0a435b91e57619f51707154d9e79de69a4785101 Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 15:17:14 -0500 Subject: [PATCH 06/14] Update UIPlugin controller to use Service and UserToken Alias:"perses" instead of "perses-dashboard-proxy". --- pkg/controllers/uiplugin/monitoring.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index 2032d3d09..bdf7217b7 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -117,9 +117,9 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im } if persesDashboardsFeatureEnabled { - // JZ OPEN QUESTION: Need to align on PORT number, name, and namespace...with Perses Operator? - proxy := osv1.ConsolePluginProxy{ - Alias: "perses-dashboards-proxy", + pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards=%s", config.PersesDashboards.Url)) + pluginInfo.Proxies = append(pluginInfo.Proxies, osv1.ConsolePluginProxy{ + Alias: "perses", Authorization: "UserToken", Endpoint: osv1.ConsolePluginProxyEndpoint{ Type: osv1.ProxyTypeService, @@ -129,20 +129,17 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im Port: 9446, }, }, - } - legacyProxy := osv1alpha1.ConsolePluginProxy{ + }) + pluginInfo.LegacyProxies = append(pluginInfo.LegacyProxies, osv1alpha1.ConsolePluginProxy{ Type: "Service", - Alias: "perses-dashboards-proxy", + Alias: "perses", Authorize: true, Service: osv1alpha1.ConsolePluginProxyServiceConfig{ Name: name, Namespace: namespace, Port: 9446, }, - } - pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards=%s", config.PersesDashboards.Url)) - pluginInfo.Proxies = append(pluginInfo.Proxies, proxy) - pluginInfo.LegacyProxies = append(pluginInfo.LegacyProxies, legacyProxy) + }) } return pluginInfo, nil @@ -187,7 +184,7 @@ func newMonitoringService(name string, namespace string) *corev1.Service { // JZ OPEN QUESTION: Need to align on PORT number...with Perses Operator? { Port: 9446, - Name: "perses-dashboards-proxy", + Name: "perses", Protocol: corev1.ProtocolTCP, TargetPort: intstr.FromInt32(9446), }, From d97b6a5548d71b12c598824140db58b8842a7bb2 Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 15:38:30 -0500 Subject: [PATCH 07/14] Update UIPlugin CRDs so that PersesDashboards require a 'serviceName' rather than a URL. This because COO controls Perses Operator so COO just needs the ServiceName and Namespace to fetch the Perses Service. Requiring the exact endpoint is less flexible. --- Makefile | 13 +++++++++++-- ...bservability-operator.clusterserviceversion.yaml | 2 +- .../observability.openshift.io_uiplugins.yaml | 6 +++--- .../observability.openshift.io_uiplugins.yaml | 6 +++--- docs/api.md | 4 ++-- pkg/apis/uiplugin/v1alpha1/types.go | 8 ++++---- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 1d3015ea4..ccfe61452 100644 --- a/Makefile +++ b/Makefile @@ -160,6 +160,16 @@ BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) endif BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) +# Adjust sed command to include '' if on MacOS (Darwin) +ifeq ($(shell uname), Darwin) + BUNDLE_SED_COMMAND = sed -e 's||$(OPERATOR_IMG)|g' \ + -i '' bundle/manifests/observability-operator.clusterserviceversion.yaml +else + BUNDLE_SED_COMMAND = sed -e 's||$(OPERATOR_IMG)|g' \ + -i bundle/manifests/observability-operator.clusterserviceversion.yaml +endif + + .PHONY: bundle bundle: $(KUSTOMIZE) $(OPERATOR_SDK) generate @@ -170,8 +180,7 @@ bundle: $(KUSTOMIZE) $(OPERATOR_SDK) generate --kustomize-dir=deploy/olm \ --package=observability-operator \ $(BUNDLE_METADATA_OPTS) - sed -e 's||$(OPERATOR_IMG)|g' \ - -i bundle/manifests/observability-operator.clusterserviceversion.yaml + $(BUNDLE_SED_COMMAND) $(OPERATOR_SDK) bundle validate ./bundle \ --select-optional name=operatorhub \ --optional-values=k8s-version=1.21 \ diff --git a/bundle/manifests/observability-operator.clusterserviceversion.yaml b/bundle/manifests/observability-operator.clusterserviceversion.yaml index 984913b1b..0a9471b49 100644 --- a/bundle/manifests/observability-operator.clusterserviceversion.yaml +++ b/bundle/manifests/observability-operator.clusterserviceversion.yaml @@ -42,7 +42,7 @@ metadata: categories: Monitoring certified: "false" containerImage: observability-operator:1.0.0 - createdAt: "2025-01-13T16:14:17Z" + createdAt: "2025-01-13T20:38:02Z" description: A Go based Kubernetes operator to setup and manage highly available Monitoring Stack using Prometheus, Alertmanager and Thanos Querier. operatorframework.io/cluster-monitoring: "true" diff --git a/bundle/manifests/observability.openshift.io_uiplugins.yaml b/bundle/manifests/observability.openshift.io_uiplugins.yaml index 2d6cbf37d..d024faf51 100644 --- a/bundle/manifests/observability.openshift.io_uiplugins.yaml +++ b/bundle/manifests/observability.openshift.io_uiplugins.yaml @@ -160,12 +160,12 @@ spec: description: PersesDashboards points to the perses-dashboards service of which it should create a proxy to. properties: - url: - description: Url of the ThanosQuerier to proxy to. + serviceName: + description: Name of the Perses Service to proxy to. minLength: 1 type: string required: - - url + - serviceName type: object x-kubernetes-map-type: atomic thanosQuerier: diff --git a/deploy/crds/common/observability.openshift.io_uiplugins.yaml b/deploy/crds/common/observability.openshift.io_uiplugins.yaml index 01e6a340d..6979894f5 100644 --- a/deploy/crds/common/observability.openshift.io_uiplugins.yaml +++ b/deploy/crds/common/observability.openshift.io_uiplugins.yaml @@ -160,12 +160,12 @@ spec: description: PersesDashboards points to the perses-dashboards service of which it should create a proxy to. properties: - url: - description: Url of the ThanosQuerier to proxy to. + serviceName: + description: Name of the Perses Service to proxy to. minLength: 1 type: string required: - - url + - serviceName type: object x-kubernetes-map-type: atomic thanosQuerier: diff --git a/docs/api.md b/docs/api.md index ebde9a1ca..e9dc7e557 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4236,10 +4236,10 @@ PersesDashboards points to the perses-dashboards service of which it should crea - url + serviceName string - Url of the ThanosQuerier to proxy to.
+ Name of the Perses Service to proxy to.
true diff --git a/pkg/apis/uiplugin/v1alpha1/types.go b/pkg/apis/uiplugin/v1alpha1/types.go index 015957567..9ccfd2c37 100644 --- a/pkg/apis/uiplugin/v1alpha1/types.go +++ b/pkg/apis/uiplugin/v1alpha1/types.go @@ -162,7 +162,7 @@ type AlertmanagerReference struct { // // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength:=1 - Url string `json:"url"` + Url string `json:"url,omitempty"` } // ThanosQuerier is used to configure a reference to a thanos-querier service that should be used @@ -174,7 +174,7 @@ type ThanosQuerierReference struct { // // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength:=1 - Url string `json:"url"` + Url string `json:"url,omitempty"` } // PersesDashboards is used to configure a reference to a perses-dashbaords service that should be used @@ -182,11 +182,11 @@ type ThanosQuerierReference struct { // // +structType=atomic type PersesDashboardsReference struct { - // Url of the ThanosQuerier to proxy to. + // Name of the Perses Service to proxy to. // // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength:=1 - Url string `json:"url"` + ServiceName string `json:"serviceName,omitempty"` } // UIPluginSpec is the specification for desired state of UIPlugin. From fc32261ea34c6f4ebcb59c7b17a6fc4beda04de3 Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 16:06:03 -0500 Subject: [PATCH 08/14] Remove the need for "config.PersesDashboards.Url" because we only need the name, namespace, and port to connect to the Perses Service. --- pkg/controllers/uiplugin/monitoring.go | 5 ----- pkg/controllers/uiplugin/monitoring_test.go | 6 ------ 2 files changed, 11 deletions(-) diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index bdf7217b7..ad8c9c48d 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -26,10 +26,6 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im if config.ThanosQuerier.Url == "" { return nil, fmt.Errorf("ThanosQuerier location can not be empty for plugin type %s", plugin.Spec.Type) } - // JZ OPEN QUESTION : Where is the PerseDashboards service URL coming from? - if persesDashboardsFeatureEnabled && config.PersesDashboards.Url == "" { - return nil, fmt.Errorf("PersesDashboards location can not be empty for plugin type %s", plugin.Spec.Type) - } pluginInfo := &UIPluginInfo{ Image: image, @@ -117,7 +113,6 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im } if persesDashboardsFeatureEnabled { - pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards=%s", config.PersesDashboards.Url)) pluginInfo.Proxies = append(pluginInfo.Proxies, osv1.ConsolePluginProxy{ Alias: "perses", Authorization: "UserToken", diff --git a/pkg/controllers/uiplugin/monitoring_test.go b/pkg/controllers/uiplugin/monitoring_test.go index 136c93307..98909d237 100644 --- a/pkg/controllers/uiplugin/monitoring_test.go +++ b/pkg/controllers/uiplugin/monitoring_test.go @@ -1,9 +1,6 @@ package uiplugin import ( - "encoding/json" - "fmt" - "log" "testing" "gotest.tools/v3/assert" @@ -30,9 +27,6 @@ var plugin = &uiv1alpha1.UIPlugin{ ThanosQuerier: uiv1alpha1.ThanosQuerierReference{ Url: "https://rbac-query-proxy.open-cluster-management-observability.svc:8443", }, - PersesDashboards: uiv1alpha1.PersesDashboardsReference{ - Url: "https://perses-dashboards.svc:8443", - }, }, }, } From 75dce847c5b1987af5669b1d2a1ba33fd4ffc9db Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 16:10:06 -0500 Subject: [PATCH 09/14] Update monitoring_test.go to align with Alias name change "perses". --- pkg/controllers/uiplugin/monitoring_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controllers/uiplugin/monitoring_test.go b/pkg/controllers/uiplugin/monitoring_test.go index 98909d237..ea50cc26a 100644 --- a/pkg/controllers/uiplugin/monitoring_test.go +++ b/pkg/controllers/uiplugin/monitoring_test.go @@ -41,7 +41,7 @@ func TestCreateMonitoringPluginInfo(t *testing.T) { containsPersesProxy := func() bool { for _, proxy := range pluginInfo.Proxies { - if proxy.Alias == "perses-dashboards-proxy" { + if proxy.Alias == "perses" { return true } } From d06ca79af85600e01411333d7246aa7a9bca5796 Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 16:28:30 -0500 Subject: [PATCH 10/14] Utilize library "slices" for "slices.Contains" instead of using our own contains() function. --- pkg/controllers/uiplugin/compatibility_matrix_test.go | 3 ++- pkg/controllers/uiplugin/monitoring.go | 3 ++- pkg/controllers/uiplugin/utils.go | 10 ---------- 3 files changed, 4 insertions(+), 12 deletions(-) delete mode 100644 pkg/controllers/uiplugin/utils.go diff --git a/pkg/controllers/uiplugin/compatibility_matrix_test.go b/pkg/controllers/uiplugin/compatibility_matrix_test.go index 4631f6b87..a485d7101 100644 --- a/pkg/controllers/uiplugin/compatibility_matrix_test.go +++ b/pkg/controllers/uiplugin/compatibility_matrix_test.go @@ -3,6 +3,7 @@ package uiplugin import ( "fmt" "log" + "slices" "testing" "golang.org/x/mod/semver" @@ -39,7 +40,7 @@ func TestCompatibilityMatrixMaxVersions(t *testing.T) { } // exception for montioring-plugin usage of perses-dashboards - if v.PluginType == "Monitoring" && contains(v.Features, "perses-dashboards") { + if v.PluginType == "Monitoring" && slices.Contains(v.Features, "perses-dashboards") { continue } diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index ad8c9c48d..1a37fd785 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -2,6 +2,7 @@ package uiplugin import ( "fmt" + "slices" "strings" osv1 "github.com/openshift/api/console/v1" @@ -15,7 +16,7 @@ import ( func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, image string, features []string) (*UIPluginInfo, error) { config := plugin.Spec.Monitoring - persesDashboardsFeatureEnabled := contains(features, "perses-dashboards") + persesDashboardsFeatureEnabled := slices.Contains(features, "perses-dashboards") if config == nil { return nil, fmt.Errorf("monitoring configuration can not be empty for plugin type %s", plugin.Spec.Type) } diff --git a/pkg/controllers/uiplugin/utils.go b/pkg/controllers/uiplugin/utils.go deleted file mode 100644 index 55cb12b7b..000000000 --- a/pkg/controllers/uiplugin/utils.go +++ /dev/null @@ -1,10 +0,0 @@ -package uiplugin - -func contains(array []string, value string) bool { - for _, v := range array { - if v == value { - return true - } - } - return false -} From 1bd6d054829e697b3b44cff09bc0f207a6aaa037 Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 16:33:37 -0500 Subject: [PATCH 11/14] Update monitoring.go to append PersesDashboards.ServiceName as an 'ExtraArgs' in the PluginInfo --- pkg/controllers/uiplugin/monitoring.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index 1a37fd785..9a3cb5f56 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -27,6 +27,9 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im if config.ThanosQuerier.Url == "" { return nil, fmt.Errorf("ThanosQuerier location can not be empty for plugin type %s", plugin.Spec.Type) } + if persesDashboardsFeatureEnabled && config.PersesDashboards.ServiceName == "" { + return nil, fmt.Errorf("PersesDashboards location can not be empty for plugin type %s", plugin.Spec.Type) + } pluginInfo := &UIPluginInfo{ Image: image, @@ -114,6 +117,7 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im } if persesDashboardsFeatureEnabled { + pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards=%s", config.PersesDashboards.ServiceName)) pluginInfo.Proxies = append(pluginInfo.Proxies, osv1.ConsolePluginProxy{ Alias: "perses", Authorization: "UserToken", From cc65187c45e841aaa74fc270df6e41ff7290ba4e Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 13 Jan 2025 16:58:25 -0500 Subject: [PATCH 12/14] Update montiroing_test.go to align with changes, PersesDashboards.ServiceName instead of PersesDashboards.Url should be present in UIPlugin CR --- pkg/controllers/uiplugin/monitoring.go | 2 +- pkg/controllers/uiplugin/monitoring_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index 9a3cb5f56..7a09fdb81 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -117,7 +117,7 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im } if persesDashboardsFeatureEnabled { - pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards=%s", config.PersesDashboards.ServiceName)) + pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards-service-name=%s", config.PersesDashboards.ServiceName)) pluginInfo.Proxies = append(pluginInfo.Proxies, osv1.ConsolePluginProxy{ Alias: "perses", Authorization: "UserToken", diff --git a/pkg/controllers/uiplugin/monitoring_test.go b/pkg/controllers/uiplugin/monitoring_test.go index ea50cc26a..da8e09228 100644 --- a/pkg/controllers/uiplugin/monitoring_test.go +++ b/pkg/controllers/uiplugin/monitoring_test.go @@ -27,6 +27,9 @@ var plugin = &uiv1alpha1.UIPlugin{ ThanosQuerier: uiv1alpha1.ThanosQuerierReference{ Url: "https://rbac-query-proxy.open-cluster-management-observability.svc:8443", }, + PersesDashboards: uiv1alpha1.PersesDashboardsReference{ + ServiceName: "perses-api-http", + }, }, }, } @@ -55,9 +58,6 @@ func TestCreateMonitoringPluginInfo(t *testing.T) { // if err != nil { // log.Fatalf("Error pretty printing JSON: %v", err) // } - // if error != nil { - // log.Fatalf("Error pretty printing JSON: %v", err) - // } // fmt.Println(string(prettyJSON)) // assert.Equal(t, pluginInfo, true) }) From db53dc13522eb91e3c011d60dfd11dfd7e83fa6a Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Tue, 14 Jan 2025 17:17:39 -0500 Subject: [PATCH 13/14] observability-ui-plugins.md to include Perses in UIPlugin Custom Resource. Update createMonitoringPluginInfo to include name (of service) and namespace. Update CRD (custom resource defintiion) to reflect this too. --- ...bility-operator.clusterserviceversion.yaml | 2 +- .../observability.openshift.io_uiplugins.yaml | 15 ++++++---- .../observability.openshift.io_uiplugins.yaml | 15 ++++++---- docs/api.md | 17 +++++++---- docs/user-guides/observability-ui-plugins.md | 16 ++++++++-- pkg/apis/uiplugin/v1alpha1/types.go | 15 ++++++---- .../v1alpha1/zz_generated.deepcopy.go | 10 +++---- pkg/controllers/uiplugin/monitoring.go | 30 +++++++++++-------- pkg/controllers/uiplugin/monitoring_test.go | 5 ++-- 9 files changed, 82 insertions(+), 43 deletions(-) diff --git a/bundle/manifests/observability-operator.clusterserviceversion.yaml b/bundle/manifests/observability-operator.clusterserviceversion.yaml index 0a9471b49..f1b6cde8b 100644 --- a/bundle/manifests/observability-operator.clusterserviceversion.yaml +++ b/bundle/manifests/observability-operator.clusterserviceversion.yaml @@ -42,7 +42,7 @@ metadata: categories: Monitoring certified: "false" containerImage: observability-operator:1.0.0 - createdAt: "2025-01-13T20:38:02Z" + createdAt: "2025-01-14T21:22:22Z" description: A Go based Kubernetes operator to setup and manage highly available Monitoring Stack using Prometheus, Alertmanager and Thanos Querier. operatorframework.io/cluster-monitoring: "true" diff --git a/bundle/manifests/observability.openshift.io_uiplugins.yaml b/bundle/manifests/observability.openshift.io_uiplugins.yaml index d024faf51..1ece566c0 100644 --- a/bundle/manifests/observability.openshift.io_uiplugins.yaml +++ b/bundle/manifests/observability.openshift.io_uiplugins.yaml @@ -156,16 +156,21 @@ spec: - url type: object x-kubernetes-map-type: atomic - persesDashboards: - description: PersesDashboards points to the perses-dashboards - service of which it should create a proxy to. + perses: + description: Perses points to the perses instance service of which + it should create a proxy to. properties: - serviceName: + name: description: Name of the Perses Service to proxy to. minLength: 1 type: string + namespace: + description: Namespace of the Perses Service to proxy to. + minLength: 1 + type: string required: - - serviceName + - name + - namespace type: object x-kubernetes-map-type: atomic thanosQuerier: diff --git a/deploy/crds/common/observability.openshift.io_uiplugins.yaml b/deploy/crds/common/observability.openshift.io_uiplugins.yaml index 6979894f5..18e53717a 100644 --- a/deploy/crds/common/observability.openshift.io_uiplugins.yaml +++ b/deploy/crds/common/observability.openshift.io_uiplugins.yaml @@ -156,16 +156,21 @@ spec: - url type: object x-kubernetes-map-type: atomic - persesDashboards: - description: PersesDashboards points to the perses-dashboards - service of which it should create a proxy to. + perses: + description: Perses points to the perses instance service of which + it should create a proxy to. properties: - serviceName: + name: description: Name of the Perses Service to proxy to. minLength: 1 type: string + namespace: + description: Namespace of the Perses Service to proxy to. + minLength: 1 + type: string required: - - serviceName + - name + - namespace type: object x-kubernetes-map-type: atomic thanosQuerier: diff --git a/docs/api.md b/docs/api.md index e9dc7e557..79fa32c61 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4175,10 +4175,10 @@ Monitoring contains configuration for the monitoring console plugin. false - persesDashboards + perses object - PersesDashboards points to the perses-dashboards service of which it should create a proxy to.
+ Perses points to the perses instance service of which it should create a proxy to.
false @@ -4219,12 +4219,12 @@ Alertmanager points to the alertmanager instance of which it should create a pro -### UIPlugin.spec.monitoring.persesDashboards +### UIPlugin.spec.monitoring.perses [↩ Parent](#uipluginspecmonitoring) -PersesDashboards points to the perses-dashboards service of which it should create a proxy to. +Perses points to the perses instance service of which it should create a proxy to. @@ -4236,12 +4236,19 @@ PersesDashboards points to the perses-dashboards service of which it should crea - + + + + + +
serviceNamename string Name of the Perses Service to proxy to.
true
namespacestring + Namespace of the Perses Service to proxy to.
+
true
diff --git a/docs/user-guides/observability-ui-plugins.md b/docs/user-guides/observability-ui-plugins.md index 56e22d77e..85ab66506 100644 --- a/docs/user-guides/observability-ui-plugins.md +++ b/docs/user-guides/observability-ui-plugins.md @@ -136,17 +136,22 @@ spec: ### Monitoring -The plugin adds monitoring related UI features to the OpenShift web console, mostly related to the ACM perspective. A number of new pages and features are enabled through this plugin. Including, but not limited to: +The plugin adds monitoring related UI features to the OpenShift web console, related to the Advance Cluster Management (ACM) perspective and [Perses](https://github.com/perses/perses). A number of new pages and features are enabled through this plugin. Including, but not limited to: - `ACM > Observe > Alerting` - `ACM > Observe > Alerting > Silences` - `ACM > Observe > Alerting > Alert rules` +- `Observe > Dashboards > Perses Dashboards` -This plugin is only able to be deployed by COO with the `acm-alerting` configuration enabled. Other pages which are typically distributed with the monitoring-plugin, such as `Admin > Observe > Dashboards`, are only available in the monitoring-plugin when deployed through [CMO](https://github.com/openshift/cluster-monitoring-operator). +To deploy ACM related features the `acm-alerting` configuration must be enabled. In the UIPlugin Custom Resource (CR) you must pass the Alertmanager and ThanosQuerier Service endpoint (e.g. `https://alertmanager.open-cluster-management-observability.svc:9095` and `https://rbac-query-proxy.open-cluster-management-observability.svc:8443`). See the example in the next section `Plugin Creation`. -#### Plugin Creation +Other pages which are typically distributed with the monitoring-plugin, such as `Admin > Observe > Dashboards`, are only available in the monitoring-plugin when deployed through [CMO](https://github.com/openshift/cluster-monitoring-operator). + +To deploy the Perses dashboard feature the `perses-dashboards` configuration must be enabled. In the UIPlugin CR you can optionally pass the service name and namespace of your Perses instance. Otherwise it will default to the service name `perses-api-http` and namespace `perses-operator`. See the example in the next section `Plugin Creation`. +#### Plugin Creation To enable to monitoring console plugin, create a `UIPlugin` CR. The following example shows how to create a CR to enable the monitoring console plugin: + ```yaml apiVersion: observability.openshift.io/v1alpha1 kind: UIPlugin @@ -159,6 +164,9 @@ spec: url: 'https://alertmanager.open-cluster-management-observability.svc:9095' thanosQuerier: url: 'https://rbac-query-proxy.open-cluster-management-observability.svc:8443' + perses: + name: 'perses-api-http' + namespace: 'perses-operator' ``` #### Feature List @@ -166,9 +174,11 @@ spec: | __Feature__ | __Description__ | | -------------- | --------------------------------------------------------------------------------------------------------------- | | `acm-alerting` | Adds alerting UI to multi-cluster view. Configures proxies to connect with any alertmanager and thanos-querier. | +| `perses-dashboards` | Adds perses UI to Observe > Dashboards view. Configures proxies to connect with a Perses instance. | #### Feature Matrix | __COO Version__ | __OCP Versions__ | __Features__ | | --------------- | ------------------- | -------------- | | 1.0.0+ | 4.14+ | `acm-alerting` | +| 1.1.0+ | 4.19+ | `acm-alerting, perses-dashboards` | \ No newline at end of file diff --git a/pkg/apis/uiplugin/v1alpha1/types.go b/pkg/apis/uiplugin/v1alpha1/types.go index 9ccfd2c37..e3ab02720 100644 --- a/pkg/apis/uiplugin/v1alpha1/types.go +++ b/pkg/apis/uiplugin/v1alpha1/types.go @@ -147,10 +147,10 @@ type MonitoringConfig struct { // +kubebuilder:validation:Optional ThanosQuerier ThanosQuerierReference `json:"thanosQuerier"` - // PersesDashboards points to the perses-dashboards service of which it should create a proxy to. + // Perses points to the perses instance service of which it should create a proxy to. // // +kubebuilder:validation:Optional - PersesDashboards PersesDashboardsReference `json:"persesDashboards"` + Perses PersesReference `json:"perses"` } // Alertmanager is used to configure a reference to a alertmanage that should be used @@ -177,16 +177,21 @@ type ThanosQuerierReference struct { Url string `json:"url,omitempty"` } -// PersesDashboards is used to configure a reference to a perses-dashbaords service that should be used +// Perses is used to configure a reference to a perses service that should be used // by the monitoring console plugin. // // +structType=atomic -type PersesDashboardsReference struct { +type PersesReference struct { // Name of the Perses Service to proxy to. // // +kubebuilder:validation:Required // +kubebuilder:validation:MinLength:=1 - ServiceName string `json:"serviceName,omitempty"` + Name string `json:"name,omitempty"` + // Namespace of the Perses Service to proxy to. + // + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength:=1 + Namespace string `json:"namespace,omitempty"` } // UIPluginSpec is the specification for desired state of UIPlugin. diff --git a/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go index 3dd7f381a..897bbc0da 100644 --- a/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/uiplugin/v1alpha1/zz_generated.deepcopy.go @@ -136,7 +136,7 @@ func (in *MonitoringConfig) DeepCopyInto(out *MonitoringConfig) { *out = *in out.Alertmanager = in.Alertmanager out.ThanosQuerier = in.ThanosQuerier - out.PersesDashboards = in.PersesDashboards + out.Perses = in.Perses } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MonitoringConfig. @@ -150,16 +150,16 @@ func (in *MonitoringConfig) DeepCopy() *MonitoringConfig { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PersesDashboardsReference) DeepCopyInto(out *PersesDashboardsReference) { +func (in *PersesReference) DeepCopyInto(out *PersesReference) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PersesDashboardsReference. -func (in *PersesDashboardsReference) DeepCopy() *PersesDashboardsReference { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PersesReference. +func (in *PersesReference) DeepCopy() *PersesReference { if in == nil { return nil } - out := new(PersesDashboardsReference) + out := new(PersesReference) in.DeepCopyInto(out) return out } diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index 7a09fdb81..1c59cdb12 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -14,9 +14,16 @@ import ( uiv1alpha1 "github.com/rhobs/observability-operator/pkg/apis/uiplugin/v1alpha1" ) +// JZ Notes = plugin is the user generated CR + func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, image string, features []string) (*UIPluginInfo, error) { config := plugin.Spec.Monitoring persesDashboardsFeatureEnabled := slices.Contains(features, "perses-dashboards") + + // Default service name and namespace for Perses + var persesName = "perses-api-http" + var persesNamespace = "perses-operator" + if config == nil { return nil, fmt.Errorf("monitoring configuration can not be empty for plugin type %s", plugin.Spec.Type) } @@ -27,8 +34,9 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im if config.ThanosQuerier.Url == "" { return nil, fmt.Errorf("ThanosQuerier location can not be empty for plugin type %s", plugin.Spec.Type) } - if persesDashboardsFeatureEnabled && config.PersesDashboards.ServiceName == "" { - return nil, fmt.Errorf("PersesDashboards location can not be empty for plugin type %s", plugin.Spec.Type) + if persesDashboardsFeatureEnabled && config.Perses.Name != "" && config.Perses.Namespace != "" { + persesName = config.Perses.Name + persesNamespace = config.Perses.Namespace } pluginInfo := &UIPluginInfo{ @@ -117,16 +125,15 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im } if persesDashboardsFeatureEnabled { - pluginInfo.ExtraArgs = append(pluginInfo.ExtraArgs, fmt.Sprintf("-perses-dashboards-service-name=%s", config.PersesDashboards.ServiceName)) pluginInfo.Proxies = append(pluginInfo.Proxies, osv1.ConsolePluginProxy{ Alias: "perses", Authorization: "UserToken", Endpoint: osv1.ConsolePluginProxyEndpoint{ Type: osv1.ProxyTypeService, Service: &osv1.ConsolePluginProxyServiceConfig{ - Name: name, - Namespace: namespace, - Port: 9446, + Name: persesName, + Namespace: persesNamespace, + Port: 8080, }, }, }) @@ -135,9 +142,9 @@ func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, im Alias: "perses", Authorize: true, Service: osv1alpha1.ConsolePluginProxyServiceConfig{ - Name: name, - Namespace: namespace, - Port: 9446, + Name: persesName, + Namespace: persesNamespace, + Port: 8080, }, }) } @@ -181,12 +188,11 @@ func newMonitoringService(name string, namespace string) *corev1.Service { Protocol: corev1.ProtocolTCP, TargetPort: intstr.FromInt32(9445), }, - // JZ OPEN QUESTION: Need to align on PORT number...with Perses Operator? { - Port: 9446, + Port: 8080, Name: "perses", Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt32(9446), + TargetPort: intstr.FromInt32(8080), }, }, Selector: componentLabels(name), diff --git a/pkg/controllers/uiplugin/monitoring_test.go b/pkg/controllers/uiplugin/monitoring_test.go index da8e09228..c05cb9319 100644 --- a/pkg/controllers/uiplugin/monitoring_test.go +++ b/pkg/controllers/uiplugin/monitoring_test.go @@ -27,8 +27,9 @@ var plugin = &uiv1alpha1.UIPlugin{ ThanosQuerier: uiv1alpha1.ThanosQuerierReference{ Url: "https://rbac-query-proxy.open-cluster-management-observability.svc:8443", }, - PersesDashboards: uiv1alpha1.PersesDashboardsReference{ - ServiceName: "perses-api-http", + Perses: uiv1alpha1.PersesReference{ + Name: "perses-api-http", + Namespace: "perses-operator", }, }, }, From c3938bd28bcb1afab94df3711e4d933c5985758e Mon Sep 17 00:00:00 2001 From: Jenny Zhu Date: Mon, 20 Jan 2025 14:17:48 -0500 Subject: [PATCH 14/14] BROKEN add log statements -- won't work on cluster --- cmd/operator/main.go | 4 ++-- pkg/controllers/uiplugin/compatibility_matrix.go | 1 + pkg/controllers/uiplugin/compatibility_matrix_test.go | 5 +---- pkg/controllers/uiplugin/controller.go | 10 ++++++++++ pkg/controllers/uiplugin/monitoring.go | 2 -- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/cmd/operator/main.go b/cmd/operator/main.go index 1fb59facf..fbff588e5 100644 --- a/cmd/operator/main.go +++ b/cmd/operator/main.go @@ -43,7 +43,7 @@ var defaultImages = map[string]string{ "ui-troubleshooting-panel": "quay.io/openshift-observability-ui/troubleshooting-panel-console-plugin:v0.3.0", "ui-distributed-tracing": "quay.io/openshift-observability-ui/distributed-tracing-console-plugin:v0.3.0", "ui-logging": "quay.io/openshift-observability-ui/logging-view-plugin:v6.0.0", - "ui-monitoring": "quay.io/openshift-observability-ui/monitoring-console-plugin:latest", + "ui-monitoring": "quay.io/rh-ee-pyurkovi/monitoring-plugin:perses", // JZ NEED THIS FOR TEST WITH 'PERSES-DASHBOARD' FEATURE FLAG ON MONTIORING-CONSOLE-PLUGIN "korrel8r": "quay.io/korrel8r/korrel8r:0.7.4", } @@ -91,7 +91,7 @@ func main() { flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&healthProbeAddr, "health-probe-bind-address", ":8081", "The address the health probe endpoint binds to.") flag.Var(images, "images", fmt.Sprintf("Full images refs to use for containers managed by the operator. E.g thanos=quay.io/thanos/thanos:v0.33.0. Images used are %v", imagesUsed())) - flag.BoolVar(&openShiftEnabled, "openshift.enabled", false, "Enable OpenShift specific features such as Console Plugins.") + flag.BoolVar(&openShiftEnabled, "openshift.enabled", true, "Enable OpenShift specific features such as Console Plugins.") opts := zap.Options{ Development: true, diff --git a/pkg/controllers/uiplugin/compatibility_matrix.go b/pkg/controllers/uiplugin/compatibility_matrix.go index 97c923d10..bd5acd617 100644 --- a/pkg/controllers/uiplugin/compatibility_matrix.go +++ b/pkg/controllers/uiplugin/compatibility_matrix.go @@ -160,6 +160,7 @@ var compatibilityMatrix = []CompatibilityEntry{ } func lookupImageAndFeatures(pluginType uiv1alpha1.UIPluginType, clusterVersion string, acmVersion string) (CompatibilityEntry, error) { + if !strings.HasPrefix(clusterVersion, "v") { clusterVersion = "v" + clusterVersion } diff --git a/pkg/controllers/uiplugin/compatibility_matrix_test.go b/pkg/controllers/uiplugin/compatibility_matrix_test.go index a485d7101..c909cf656 100644 --- a/pkg/controllers/uiplugin/compatibility_matrix_test.go +++ b/pkg/controllers/uiplugin/compatibility_matrix_test.go @@ -2,7 +2,7 @@ package uiplugin import ( "fmt" - "log" + // "log" "slices" "testing" @@ -300,9 +300,6 @@ func TestLookupImageAndFeatures(t *testing.T) { assert.NilError(t, err) - log.Printf("expected Features: %s", tc.expectedFeatures) - log.Printf("Features: %s", info.Features) - t.Logf("%s == %s", tc.expectedKey, info.ImageKey) assert.Equal(t, tc.expectedKey, info.ImageKey) diff --git a/pkg/controllers/uiplugin/controller.go b/pkg/controllers/uiplugin/controller.go index 714e43b68..308621c1b 100644 --- a/pkg/controllers/uiplugin/controller.go +++ b/pkg/controllers/uiplugin/controller.go @@ -185,6 +185,8 @@ func (rm resourceManager) Reconcile(ctx context.Context, req ctrl.Request) (ctrl return ctrl.Result{}, nil } + logger.Info("JZ plugin: ", plugin) + // Check if the plugin is being deleted if !plugin.ObjectMeta.DeletionTimestamp.IsZero() { logger.V(6).Info("deregistering plugin from the console") @@ -227,11 +229,19 @@ func (rm resourceManager) Reconcile(ctx context.Context, req ctrl.Request) (ctrl } } + // JZ TESTING TO BE REMOVED + logger.Info("JZ plugin.Spec.Type", plugin.Spec.Type) + logger.Info("JZ rm.clusterVersion", rm.clusterVersion) + logger.Info("JZ acmVersion", acmVersion) + compatibilityInfo, err := lookupImageAndFeatures(plugin.Spec.Type, rm.clusterVersion, acmVersion) if err != nil { + logger.Info("JZ ERROR compatibilityInfo: \n", compatibilityInfo) return ctrl.Result{}, err } + logger.Info("JZ compatibilityInfo: \n", compatibilityInfo) + if plugin.Annotations == nil { plugin.Annotations = map[string]string{} plugin.Annotations["observability.openshift.io/api-support"] = string(compatibilityInfo.SupportLevel) diff --git a/pkg/controllers/uiplugin/monitoring.go b/pkg/controllers/uiplugin/monitoring.go index 1c59cdb12..d20af486a 100644 --- a/pkg/controllers/uiplugin/monitoring.go +++ b/pkg/controllers/uiplugin/monitoring.go @@ -14,8 +14,6 @@ import ( uiv1alpha1 "github.com/rhobs/observability-operator/pkg/apis/uiplugin/v1alpha1" ) -// JZ Notes = plugin is the user generated CR - func createMonitoringPluginInfo(plugin *uiv1alpha1.UIPlugin, namespace, name, image string, features []string) (*UIPluginInfo, error) { config := plugin.Spec.Monitoring persesDashboardsFeatureEnabled := slices.Contains(features, "perses-dashboards")