Skip to content

Commit

Permalink
Add Korrel8r plugin to UITroubleshootPanel
Browse files Browse the repository at this point in the history
Signed-off-by: Shweta Padubidri <spadubid@redhat.com>
  • Loading branch information
shwetaap committed May 31, 2024
1 parent f5ebcf9 commit 50af384
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 3 deletions.
3 changes: 2 additions & 1 deletion cmd/operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var defaultImages = map[string]string{
"ui-dashboards": "quay.io/openshift-observability-ui/console-dashboards-plugin:v0.1.0",
"ui-troubleshooting-panel": "quay.io/openshift-observability-ui/troubleshooting-panel-console-plugin:v0.1.0",
"ui-distributed-tracing": "quay.io/openshift-observability-ui/distributed-tracing-console-plugin:v0.1.0",
"korrel8r": "quay.io/shwetaap/korrel8r:0.6.3",
}

func imagesUsed() []string {
Expand Down Expand Up @@ -88,7 +89,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,
Expand Down
180 changes: 179 additions & 1 deletion pkg/controllers/uiplugin/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package uiplugin

import (
"fmt"
"embed"
"bytes"
"io"
"text/template"

osv1alpha1 "github.com/openshift/api/console/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
Expand All @@ -19,16 +23,28 @@ const (
port = 9443
serviceAccountSuffix = "-sa"
servingCertVolumeName = "serving-cert"
Korrel8rConfigFileName = "korrel8r.yaml"
Korrel8rConfigMountDir = "/etc/korrel8r/"
)

var (
//go:embed config/korrel8r.yaml
korrel8rConfigYAMLTmplFile embed.FS
)


func pluginComponentReconcilers(plugin *uiv1alpha1.UIPlugin, pluginInfo UIPluginInfo) []reconciler.Reconciler {
namespace := pluginInfo.ResourceNamespace
kname := "korrel8r"

components := []reconciler.Reconciler{
reconciler.NewUpdater(newServiceAccount(pluginInfo, namespace), plugin),
reconciler.NewUpdater(newDeployment(pluginInfo, namespace), plugin),
reconciler.NewUpdater(newService(pluginInfo, namespace), plugin),
reconciler.NewUpdater(newConsolePlugin(pluginInfo, namespace), plugin),
reconciler.NewUpdater(newKorrel8rService(kname, namespace), plugin),
reconciler.NewUpdater(newKorrel8rConfigMap(kname, namespace), plugin),
reconciler.NewUpdater(newKorrel8rDeployment(kname, namespace, pluginInfo), plugin),
}

if pluginInfo.Role != nil {
Expand Down Expand Up @@ -252,10 +268,172 @@ func newService(info UIPluginInfo, namespace string) *corev1.Service {
}
}

func newKorrel8rDeployment(name string, namespace string, info UIPluginInfo) *appsv1.Deployment {
volumes := []corev1.Volume{
{
Name: servingCertVolumeName,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: name,
DefaultMode: ptr.To(int32(420)),
},
},
},
}
volumeMounts := []corev1.VolumeMount{
{
Name: servingCertVolumeName,
ReadOnly: true,
MountPath: "/var/serving-cert",
},
}

volumes = append(volumes, corev1.Volume{
Name: "korrel8r-config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: name,
},
},
},
})
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "korrel8r-config",
ReadOnly: true,
MountPath: Korrel8rConfigMountDir,
})


deploy := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
APIVersion: appsv1.SchemeGroupVersion.String(),
Kind: "Deployment",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: componentLabels(name),
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: componentLabels(name),
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: componentLabels(name),
},
Spec: corev1.PodSpec{
ServiceAccountName: info.Name + serviceAccountSuffix,
Containers: []corev1.Container{
{
Name: name,
Image: info.Korrel8rImage,
Command: []string{"korrel8r", "web", "--config", "/etc/korrel8r/korrel8r.yaml"},
Ports: []corev1.ContainerPort{
{
ContainerPort: 8443,
Protocol: corev1.ProtocolTCP,
},
},
SecurityContext: &corev1.SecurityContext{
RunAsNonRoot: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{
"ALL",
},
},
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
},
VolumeMounts: volumeMounts,
},
},
Volumes: volumes,
},
},
},
}
return deploy
}

func newKorrel8rService(name string, namespace string) *corev1.Service {
annotations := map[string]string{
"service.alpha.openshift.io/serving-cert-secret-name": name,
}

return &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: corev1.SchemeGroupVersion.String(),
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: componentLabels(name),
Annotations: annotations,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Port: port,
Name: "web",
Protocol: corev1.ProtocolTCP,
TargetPort: intstr.FromInt32(port),
},
},
Selector: componentLabels(name),
Type: corev1.ServiceTypeClusterIP,
},
}
}

func newKorrel8rConfigMap(name string, namespace string) *corev1.ConfigMap {

korrel8rData := struct {
Metric string
MetricAlert string
Log string
Netflow string
}{
Metric: "thanos-querier",
MetricAlert: "alertmanager-main",
Log: "logging-loki-gateway-http",
Netflow: "loki-gateway-http",
}

// TODO Check the loki service exists and update name if needed

var korrel8rConfigYAMLTmpl = template.Must(template.ParseFS(korrel8rConfigYAMLTmplFile, "config/korrel8r.yaml"))
w := bytes.NewBuffer(nil)
korrel8rConfigYAMLTmpl.Execute(w, korrel8rData)

cfg, _ := io.ReadAll(w)

return &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: corev1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: componentLabels(name),
},
Data: map[string]string{
Korrel8rConfigFileName: string(cfg),
},
}
}

func componentLabels(pluginName string) map[string]string {
return map[string]string{
"app.kubernetes.io/instance": pluginName,
"app.kubernetes.io/part-of": "UIPlugin",
"app.kubernetes.io/managed-by": "observability-operator",
}
}
}
20 changes: 20 additions & 0 deletions pkg/controllers/uiplugin/config/korrel8r.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Default configuration for deploying Korrel8r as a service in an OpenShift cluster.
# Store service URLs assume that stores are installed in their default locations.
stores:
- domain: k8s
- domain: alert
metrics: https://{{ .Thanos }}.openshift-monitoring.svc:9091
alertmanager: https://{{ .Alert }}.openshift-monitoring.svc:9094
certificateAuthority: ./run/secrets/kubernetes.io/serviceaccount/service-ca.crt
- domain: log
lokiStack: https://{{ .Logloki }}.openshift-logging.svc:8080
certificateAuthority: ./run/secrets/kubernetes.io/serviceaccount/service-ca.crt
- domain: metric
metric: https://{{ .Thanos }}.openshift-monitoring.svc:9091
certificateAuthority: ./run/secrets/kubernetes.io/serviceaccount/service-ca.crt
- domain: netflow
lokiStack: https://{{ .Netflowloki }}.netobserv.svc:8080
certificateAuthority: ./run/secrets/kubernetes.io/serviceaccount/service-ca.crt

include:
- rules/all.yaml
5 changes: 4 additions & 1 deletion pkg/controllers/uiplugin/plugin_info_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

type UIPluginInfo struct {
Image string
Korrel8rImage string
Name string
ConsoleName string
DisplayName string
Expand Down Expand Up @@ -109,7 +110,9 @@ func PluginInfoBuilder(plugin *uiv1alpha1.UIPlugin, pluginConf UIPluginsConfigur
}
case uiv1alpha1.TypeTroubleshootingPanel:
{
return createTroubleshootingPanelPluginInfo(plugin, namespace, plugin.Name, image, []string{})
pluginInfo, _ := createTroubleshootingPanelPluginInfo(plugin, namespace, plugin.Name, image, []string{})
pluginInfo.Korrel8rImage = pluginConf.Images["korrel8r"]
return pluginInfo, nil
}
case uiv1alpha1.TypeDistributedTracing:
{
Expand Down

0 comments on commit 50af384

Please sign in to comment.