in pkg/operator/apis/monitoring/v1/pod_config.go [463:522]
func convertRelabelingRule(r RelabelingRule) (*relabel.Config, error) {
rcfg := &relabel.Config{
// Upstream applies ToLower when digesting the config, so we allow the same.
Action: relabel.Action(strings.ToLower(r.Action)),
TargetLabel: r.TargetLabel,
Separator: r.Separator,
Replacement: r.Replacement,
Modulus: r.Modulus,
}
for _, n := range r.SourceLabels {
rcfg.SourceLabels = append(rcfg.SourceLabels, prommodel.LabelName(n))
}
// Instantiate the default regex Prometheus uses so that the checks below can be run
// if no explicit value is provided.
re := relabel.MustNewRegexp(`(.*)`)
// We must only set the regex if its not empty. Like in other cases, the Prometheus code does
// not setup the structs correctly and this would default to the string "null" when marshalled,
// which is then interpreted as a regex again when read by Prometheus.
if r.Regex != "" {
var err error
re, err = relabel.NewRegexp(r.Regex)
if err != nil {
return nil, fmt.Errorf("invalid regex %q: %w", r.Regex, err)
}
rcfg.Regex = re
}
// Validate that the protected target labels are not mutated by the provided relabeling rules.
switch rcfg.Action {
// Default action is "replace" per https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config.
case relabel.Replace, relabel.HashMod, "":
// These actions write into the target label and it must not be a protected one.
if protectedLabel[r.TargetLabel] {
return nil, fmt.Errorf("cannot relabel with action %q onto protected label %q", r.Action, r.TargetLabel)
}
case relabel.LabelDrop:
if matchesAnyProtectedLabel(re) {
return nil, fmt.Errorf("regex %s would drop at least one of the protected labels %v", r.Regex, protectedLabels)
}
case relabel.LabelKeep:
// Keep drops all labels that don't match the regex. So all protected labels must
// match keep.
if !matchesAllProtectedLabels(re) {
return nil, fmt.Errorf("regex %s would drop at least one of the protected labels %s", r.Regex, protectedLabels)
}
case relabel.LabelMap:
// It is difficult to prove for certain that labelmap does not override a protected label.
// Thus we just prohibit its use for now.
// The most feasible way to support this would probably be store all protected labels
// in __tmp_protected_<name> via a replace rule, then apply labelmap, then replace the
// __tmp label back onto the protected label.
return nil, fmt.Errorf("relabeling with action %q not allowed", r.Action)
case relabel.Keep, relabel.Drop:
// These actions don't modify a series and are OK.
default:
return nil, fmt.Errorf("unknown relabeling action %q", r.Action)
}
return rcfg, nil
}