Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions api/operator/v1beta1/vmextra_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,19 +1021,17 @@ func (m *StringOrArray) UnmarshalJSON(data []byte) error {
}
}

// MarshalJSON implements json.Marshaller interface
func (m *StringOrArray) MarshalJSON() ([]byte, error) {
if m == nil {
return nil, nil
}
ms := *m
// MarshalJSON implements json.Marshaller interface.
// Use a value receiver so nested struct fields of type StringOrArray
// are serialized as strings when they contain a single element.
func (m StringOrArray) MarshalJSON() ([]byte, error) {
switch {
case len(ms) == 0:
case len(m) == 0:
return json.Marshal("")
case len(ms) == 1:
return json.Marshal(ms[0])
case len(m) == 1:
return json.Marshal(m[0])
default:
return json.Marshal([]string(ms))
return json.Marshal([]string(m))
}
}

Expand Down
7 changes: 7 additions & 0 deletions api/operator/v1beta1/vmextra_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ func TestStringOrArrayMarshal(t *testing.T) {
`)
f(&StringOrArray{}, yaml.Marshal, `""
`)
got, err := json.Marshal(struct {
Match StringOrArray `json:"match"`
}{
Match: StringOrArray{"1"},
})
assert.NoError(t, err)
assert.Equal(t, `{"match":"1"}`, string(got))

}

Expand Down
28 changes: 28 additions & 0 deletions internal/controller/operator/factory/converter/apis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package converter

import (
"context"
"encoding/json"
"testing"

promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
Expand Down Expand Up @@ -224,6 +225,33 @@ func TestServiceMonitor(t *testing.T) {
})
}

func TestServiceMonitorSingleRegexMarshalsAsJSONScalar(t *testing.T) {
ctx := context.TODO()
got := ServiceMonitor(ctx, &promv1.ServiceMonitor{
Spec: promv1.ServiceMonitorSpec{
Endpoints: []promv1.Endpoint{{
MetricRelabelConfigs: []promv1.RelabelConfig{{
Action: "drop",
Regex: "^karpenter_cloudprovider_instance.*",
SourceLabels: []promv1.LabelName{"__name__"},
}},
RelabelConfigs: []promv1.RelabelConfig{{
Action: "replace",
Regex: "^(.*)$",
SourceLabels: []promv1.LabelName{"__meta_kubernetes_pod_node_name"},
TargetLabel: "nodename",
}},
}},
},
}, &config.BaseOperatorConf{})

data, err := json.Marshal(got)
assert.NoError(t, err)
assert.Contains(t, string(data), `"regex":"^karpenter_cloudprovider_instance.*"`)
assert.Contains(t, string(data), `"regex":"^(.*)$"`)
assert.NotContains(t, string(data), `"regex":["`)
}

func TestConvertPodEndpoints(t *testing.T) {
type opts struct {
pe []promv1.PodMetricsEndpoint
Expand Down