diff --git a/cmd/all-in-one/main.go b/cmd/all-in-one/main.go index 1d8cd4a881e..721757a6079 100644 --- a/cmd/all-in-one/main.go +++ b/cmd/all-in-one/main.go @@ -36,6 +36,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/internal/docs" "github.com/jaegertracing/jaeger/cmd/internal/env" "github.com/jaegertracing/jaeger/cmd/internal/flags" + "github.com/jaegertracing/jaeger/cmd/internal/printconfig" "github.com/jaegertracing/jaeger/cmd/internal/status" queryApp "github.com/jaegertracing/jaeger/cmd/query/app" "github.com/jaegertracing/jaeger/cmd/query/app/querysvc" @@ -229,6 +230,7 @@ by default uses only in-memory database.`, command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) command.AddCommand(status.Command(v, ports.CollectorAdminHTTP)) + command.AddCommand(printconfig.Command(v)) config.AddFlags( v, diff --git a/cmd/collector/main.go b/cmd/collector/main.go index 8f86c0a2390..e8f1ca4db95 100644 --- a/cmd/collector/main.go +++ b/cmd/collector/main.go @@ -31,6 +31,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/internal/docs" "github.com/jaegertracing/jaeger/cmd/internal/env" cmdFlags "github.com/jaegertracing/jaeger/cmd/internal/flags" + "github.com/jaegertracing/jaeger/cmd/internal/printconfig" "github.com/jaegertracing/jaeger/cmd/internal/status" "github.com/jaegertracing/jaeger/internal/metrics/expvar" "github.com/jaegertracing/jaeger/internal/metrics/fork" @@ -142,6 +143,7 @@ func main() { command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) command.AddCommand(status.Command(v, ports.CollectorAdminHTTP)) + command.AddCommand(printconfig.Command(v)) config.AddFlags( v, diff --git a/cmd/ingester/main.go b/cmd/ingester/main.go index 21641ac71aa..c4680edda68 100644 --- a/cmd/ingester/main.go +++ b/cmd/ingester/main.go @@ -30,6 +30,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/internal/docs" "github.com/jaegertracing/jaeger/cmd/internal/env" "github.com/jaegertracing/jaeger/cmd/internal/flags" + "github.com/jaegertracing/jaeger/cmd/internal/printconfig" "github.com/jaegertracing/jaeger/cmd/internal/status" "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/metrics" @@ -102,6 +103,7 @@ func main() { command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) command.AddCommand(status.Command(v, ports.IngesterAdminHTTP)) + command.AddCommand(printconfig.Command(v)) config.AddFlags( v, diff --git a/cmd/internal/printconfig/command.go b/cmd/internal/printconfig/command.go new file mode 100644 index 00000000000..4cb83d5a7c0 --- /dev/null +++ b/cmd/internal/printconfig/command.go @@ -0,0 +1,76 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package printconfig + +import ( + "fmt" + "sort" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func printDivider(cmd *cobra.Command, n int) { + fmt.Fprint(cmd.OutOrStdout(), strings.Repeat("-", n), "\n") +} + +func printConfigurations(cmd *cobra.Command, v *viper.Viper, includeEmpty bool) { + keys := v.AllKeys() + sort.Strings(keys) + + maxKeyLength, maxValueLength := len("Configuration Option Name"), len("Value") + maxSourceLength := len("user-assigned") + for _, key := range keys { + value := v.GetString(key) + if len(key) > maxKeyLength { + maxKeyLength = len(key) + } + if len(value) > maxValueLength { + maxValueLength = len(value) + } + } + maxRowLength := maxKeyLength + maxValueLength + maxSourceLength + 6 + + printDivider(cmd, maxRowLength) + fmt.Fprintf(cmd.OutOrStdout(), + "| %-*s %-*s %-*s |\n", + maxKeyLength, "Configuration Option Name", + maxValueLength, "Value", + maxSourceLength, "Source") + printDivider(cmd, maxRowLength) + + for _, key := range keys { + value := v.GetString(key) + source := "default" + if v.IsSet(key) { + source = "user-assigned" + } + + if includeEmpty || value != "" { + fmt.Fprintf(cmd.OutOrStdout(), + "| %-*s %-*s %-*s |\n", + maxKeyLength, key, + maxValueLength, value, + maxSourceLength, source) + } + } + printDivider(cmd, maxRowLength) +} + +func Command(v *viper.Viper) *cobra.Command { + allFlag := true + cmd := &cobra.Command{ + Use: "print-config", + Short: "Print names and values of configuration options", + Long: "Print names and values of configuration options, distinguishing between default and user-assigned values", + RunE: func(cmd *cobra.Command, args []string) error { + printConfigurations(cmd, v, allFlag) + return nil + }, + } + cmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Print all configuration options including those with empty values") + + return cmd +} diff --git a/cmd/internal/printconfig/command_test.go b/cmd/internal/printconfig/command_test.go new file mode 100644 index 00000000000..155730581d4 --- /dev/null +++ b/cmd/internal/printconfig/command_test.go @@ -0,0 +1,128 @@ +// Copyright (c) 2024 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package printconfig + +import ( + "bytes" + "flag" + "testing" + "time" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/jaegertracing/jaeger/pkg/config" + "github.com/jaegertracing/jaeger/pkg/config/tlscfg" + "github.com/jaegertracing/jaeger/pkg/tenancy" +) + +const ( + testPluginBinary = "test-plugin.binary" + testPluginConfigurationFile = "test-plugin.configuration-file" + testPluginLogLevel = "test-plugin.log-level" + testRemotePrefix = "test-remote" + testRemoteServer = testRemotePrefix + ".server" + testRemoteConnectionTimeout = testRemotePrefix + ".connection-timeout" + defaultTestPluginLogLevel = "warn" + defaultTestConnectionTimeout = time.Duration(5 * time.Second) +) + +func addFlags(flagSet *flag.FlagSet) { + tlscfg.ClientFlagsConfig{ + Prefix: "test", + }.AddFlags(flagSet) + + flagSet.String(testPluginBinary, "", "") + flagSet.String(testPluginConfigurationFile, "", "") + flagSet.String(testPluginLogLevel, defaultTestPluginLogLevel, "") + flagSet.String(testRemoteServer, "", "") + flagSet.Duration(testRemoteConnectionTimeout, defaultTestConnectionTimeout, "") +} + +func setConfig(t *testing.T) *viper.Viper { + v, command := config.Viperize(addFlags, tenancy.AddFlags) + err := command.ParseFlags([]string{ + "--test-plugin.binary=noop-test-plugin", + "--test-plugin.configuration-file=config.json", + "--test-plugin.log-level=debug", + "--multi-tenancy.header=x-scope-orgid", + }) + + require.NoError(t, err) + + return v +} + +func runPrintConfigCommand(v *viper.Viper, t *testing.T, allFlag bool) string { + buf := new(bytes.Buffer) + printCmd := Command(v) + printCmd.SetOut(buf) + + if allFlag { + err := printCmd.Flags().Set("all", "true") + require.NoError(t, err, "printCmd.Flags() returned the error %v", err) + } + + _, err := printCmd.ExecuteC() + require.NoError(t, err, "printCmd.ExecuteC() returned the error %v", err) + + return buf.String() +} + +func TestAllFlag(t *testing.T) { + expected := `----------------------------------------------------------------- +| Configuration Option Name Value Source | +----------------------------------------------------------------- +| multi-tenancy.enabled false default | +| multi-tenancy.header x-scope-orgid user-assigned | +| multi-tenancy.tenants default | +| test-plugin.binary noop-test-plugin user-assigned | +| test-plugin.configuration-file config.json user-assigned | +| test-plugin.log-level debug user-assigned | +| test-remote.connection-timeout 5s default | +| test-remote.server default | +| test.tls.ca default | +| test.tls.cert default | +| test.tls.enabled false default | +| test.tls.key default | +| test.tls.server-name default | +| test.tls.skip-host-verify false default | +----------------------------------------------------------------- +` + + v := setConfig(t) + actual := runPrintConfigCommand(v, t, true) + assert.Equal(t, expected, actual) +} + +func TestPrintConfigCommand(t *testing.T) { + expected := `----------------------------------------------------------------- +| Configuration Option Name Value Source | +----------------------------------------------------------------- +| multi-tenancy.enabled false default | +| multi-tenancy.header x-scope-orgid user-assigned | +| test-plugin.binary noop-test-plugin user-assigned | +| test-plugin.configuration-file config.json user-assigned | +| test-plugin.log-level debug user-assigned | +| test-remote.connection-timeout 5s default | +| test.tls.enabled false default | +| test.tls.skip-host-verify false default | +----------------------------------------------------------------- +` + v := setConfig(t) + actual := runPrintConfigCommand(v, t, false) + assert.Equal(t, expected, actual) +} diff --git a/cmd/jaeger/main.go b/cmd/jaeger/main.go index 04f01d79439..d63268845e7 100644 --- a/cmd/jaeger/main.go +++ b/cmd/jaeger/main.go @@ -19,7 +19,6 @@ func main() { command := internal.Command() command.AddCommand(version.Command()) command.AddCommand(docs.Command(v)) - config.AddFlags( v, command, diff --git a/cmd/query/main.go b/cmd/query/main.go index 24331d94c37..ccc9ab81933 100644 --- a/cmd/query/main.go +++ b/cmd/query/main.go @@ -29,6 +29,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/internal/docs" "github.com/jaegertracing/jaeger/cmd/internal/env" "github.com/jaegertracing/jaeger/cmd/internal/flags" + "github.com/jaegertracing/jaeger/cmd/internal/printconfig" "github.com/jaegertracing/jaeger/cmd/internal/status" "github.com/jaegertracing/jaeger/cmd/query/app" "github.com/jaegertracing/jaeger/cmd/query/app/querysvc" @@ -144,6 +145,7 @@ func main() { command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) command.AddCommand(status.Command(v, ports.QueryAdminHTTP)) + command.AddCommand(printconfig.Command(v)) config.AddFlags( v, diff --git a/cmd/remote-storage/main.go b/cmd/remote-storage/main.go index 8fd37d037a8..a4f7759a3aa 100644 --- a/cmd/remote-storage/main.go +++ b/cmd/remote-storage/main.go @@ -27,6 +27,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/internal/docs" "github.com/jaegertracing/jaeger/cmd/internal/env" "github.com/jaegertracing/jaeger/cmd/internal/flags" + "github.com/jaegertracing/jaeger/cmd/internal/printconfig" "github.com/jaegertracing/jaeger/cmd/internal/status" "github.com/jaegertracing/jaeger/cmd/remote-storage/app" "github.com/jaegertracing/jaeger/pkg/config" @@ -105,6 +106,7 @@ func main() { command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) command.AddCommand(status.Command(v, ports.QueryAdminHTTP)) + command.AddCommand(printconfig.Command(v)) config.AddFlags( v,