diff --git a/tracing/config/tracing.go b/tracing/config/tracing.go index eaa2bb6d88..a0893079ef 100644 --- a/tracing/config/tracing.go +++ b/tracing/config/tracing.go @@ -17,6 +17,7 @@ limitations under the License. package config import ( + "encoding/json" "errors" "fmt" "reflect" @@ -139,3 +140,43 @@ func NewTracingConfigFromMap(cfgMap map[string]string) (*Config, error) { func NewTracingConfigFromConfigMap(config *corev1.ConfigMap) (*Config, error) { return NewTracingConfigFromMap(config.Data) } + +// JsonToTracingConfig converts a json string of a Config. +// Returns a non-nil Config always and an eventual error. +func JsonToTracingConfig(jsonCfg string) (*Config, error) { + if jsonCfg == "" { + return defaultConfig(), errors.New("empty json tracing config") + } + + var configMap map[string]string + if err := json.Unmarshal([]byte(jsonCfg), &configMap); err != nil { + return defaultConfig(), err + } + + cfg, err := NewTracingConfigFromMap(configMap) + if err != nil { + return defaultConfig(), nil + } + return cfg, nil +} + +// TracingConfigToJson converts a Config to a json string. +func TracingConfigToJson(cfg *Config) (string, error) { + if cfg == nil { + return "", nil + } + + out := make(map[string]string, 5) + out[backendKey] = string(cfg.Backend) + if cfg.ZipkinEndpoint != "" { + out[zipkinEndpointKey] = cfg.ZipkinEndpoint + } + if cfg.StackdriverProjectID != "" { + out[stackdriverProjectIDKey] = cfg.StackdriverProjectID + } + out[debugKey] = fmt.Sprint(cfg.Debug) + out[sampleRateKey] = fmt.Sprint(cfg.SampleRate) + + jsonCfg, err := json.Marshal(out) + return string(jsonCfg), err +} diff --git a/tracing/config/tracing_test.go b/tracing/config/tracing_test.go index 923a24cd8c..309d5225cd 100644 --- a/tracing/config/tracing_test.go +++ b/tracing/config/tracing_test.go @@ -137,6 +137,102 @@ func TestNewConfigSuccess(t *testing.T) { } } +func TestNewConfigJson(t *testing.T) { + tt := []struct { + name string + input map[string]string + output *Config + }{{ + name: "Empty map", + input: map[string]string{}, + output: defaultConfig(), + }, { + name: "Everything enabled (legacy)", + input: map[string]string{ + enableKey: "true", + zipkinEndpointKey: "some-endpoint", + debugKey: "true", + sampleRateKey: "0.5", + }, + output: &Config{ + Backend: Zipkin, + Debug: true, + ZipkinEndpoint: "some-endpoint", + SampleRate: 0.5, + }, + }, { + name: "Everything enabled (zipkin)", + input: map[string]string{ + backendKey: "zipkin", + zipkinEndpointKey: "some-endpoint", + debugKey: "true", + sampleRateKey: "0.5", + }, + output: &Config{ + Backend: Zipkin, + Debug: true, + ZipkinEndpoint: "some-endpoint", + SampleRate: 0.5, + }, + }, { + name: "Everything enabled (stackdriver)", + input: map[string]string{ + backendKey: "stackdriver", + zipkinEndpointKey: "some-endpoint", + stackdriverProjectIDKey: "my-project", + debugKey: "true", + sampleRateKey: "0.5", + }, + output: &Config{ + Backend: Stackdriver, + Debug: true, + ZipkinEndpoint: "some-endpoint", + StackdriverProjectID: "my-project", + SampleRate: 0.5, + }, + }, { + name: "Everything enabled (stackdriver, with enabled)", + input: map[string]string{ + enableKey: "true", + backendKey: "stackdriver", + zipkinEndpointKey: "some-endpoint", + stackdriverProjectIDKey: "my-project", + debugKey: "true", + sampleRateKey: "0.5", + }, + output: &Config{ + Backend: Stackdriver, + Debug: true, + ZipkinEndpoint: "some-endpoint", + StackdriverProjectID: "my-project", + SampleRate: 0.5, + }, + }} + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + config, err := NewTracingConfigFromMap(tc.input) + if err != nil { + t.Fatal("Failed to create tracing config:", err) + } + + json, err := TracingConfigToJson(config) + if err != nil { + t.Fatal("Failed to create tracing config:", err) + } + + haveConfig, err := JsonToTracingConfig(json) + if err != nil { + t.Fatal("Failed to create tracing config:", err) + } + + if !cmp.Equal(tc.output, haveConfig) { + t.Error("Got config from map (-want, +got) =", cmp.Diff(tc.output, haveConfig)) + } + }) + } +} + func TestNewConfigFailures(t *testing.T) { tests := []struct { name string