Skip to content

K8s transformer plugins

Advanced usage

K8s transformer plugins are for specific Kubernetes setups. Most users should use the default Prometheus Operator output.

Version

K8s transformer plugins are available on Sloth >=v0.16.0.

Kubernetes controller only

This feature only works with kubernetes specs mode.

Introduction

K8s transformer plugins transform generated Prometheus rules into custom Kubernetes objects. By default, Sloth generates Prometheus Operator PrometheusRule CRs. With transformer plugins, you can output to:

  • ConfigMaps
  • VictoriaMetrics VMRule CRs
  • Google Managed Prometheus Rules
  • ... in the end, any custom K8s resource.

These plugins use Kubernetes' Unstructured API to dynamically create any resource type.

Built-in Plugins

Sloth includes built-in transformer plugins. Check these

Configuration and usage

Loading external custom plugins

Use the common --plugins-path (-p) flag (same as SLI/SLO plugins) to load custom plugins not buil-in in Sloth. Sloth autodiscovers all plugins in the provided paths.

sloth generate -p ./plugins/ --k8s-transform-plugin-id="mycompany.com/custom-plugin/v1"

Developing Custom Plugins

Requirements

  • Define PluginVersion = "prometheus/k8stransform/v1"
  • Define unique PluginID
  • Implement NewPlugin() factory function
  • Single file named plugin.go
  • Only Go standard library + approved packages

Plugin Interface

type Plugin interface {
    TransformK8sObjects(
        ctx context.Context,
        kmeta model.K8sMeta,
        sloResult model.PromSLOGroupResult,
    ) (*K8sObjects, error)
}

Parameters:

  • kmeta: Kubernetes metadata (namespace, name, labels, annotations)
  • sloResult: Generated Prometheus rules for all SLOs
  • Returns: List of unstructured.Unstructured K8s objects

Can return multiple objects to split large outputs.

Available Packages

  • Go standard library (no reflect, unsafe)
  • k8s.io/apimachinery/pkg/apis/meta/v1/unstructured
  • github.com/slok/sloth/pkg/common/model
  • github.com/slok/sloth/pkg/common/utils/k8s
  • github.com/slok/sloth/pkg/prometheus/plugin/k8stransform/v1

Example Plugin

Simplified ConfigMap transformer:

package plugin

import (
    "context"
    "github.com/slok/sloth/pkg/common/model"
    k8sutils "github.com/slok/sloth/pkg/common/utils/k8s"
    plugink8stransformv1 "github.com/slok/sloth/pkg/prometheus/plugin/k8stransform/v1"
    "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

const (
    PluginVersion = "prometheus/k8stransform/v1"
    PluginID      = "mycompany.com/prometheus-configmap/v1"
)

func NewPlugin() (plugink8stransformv1.Plugin, error) {
    return plugin{}, nil
}

type plugin struct{}

func (p plugin) TransformK8sObjects(
    ctx context.Context,
    kmeta model.K8sMeta,
    sloResult model.PromSLOGroupResult,
) (*plugink8stransformv1.K8sObjects, error) {
    u := &unstructured.Unstructured{}
    u.SetAPIVersion("v1")
    u.SetKind("ConfigMap")
    u.SetNamespace(kmeta.Namespace)
    u.SetName(kmeta.Name)
    u.SetLabels(kmeta.Labels)

    // Collect all rules
    groups := []model.PromRuleGroup{}
    for _, slo := range sloResult.SLOResults {
        groups = append(groups,
            slo.PrometheusRules.SLIErrorRecRules,
            slo.PrometheusRules.MetadataRecRules,
            slo.PrometheusRules.AlertRules,
        )
    }

    // Convert to YAML
    rulesYAML, err := k8sutils.UnstructuredToYAMLString(
        map[string]any{"groups": groups},
    )
    if err != nil {
        return nil, err
    }

    u.Object["data"] = map[string]any{
        "prometheus-rules.yaml": rulesYAML,
    }

    return &plugink8stransformv1.K8sObjects{
        Items: []*unstructured.Unstructured{u},
    }, nil
}

Testing

Use Sloth's testing utilities:

import "github.com/slok/sloth/pkg/prometheus/plugin/k8stransform/v1/testing"

Simulates real plugin execution environment and catches errors early.

Examples

Built-in plugins source code: github.com/slok/sloth/tree/main/internal/plugin/k8stransform