diff --git a/pkg/mimirtool/config/convert_test.go b/pkg/mimirtool/config/convert_test.go index a06ee39c7b0..0177c9502da 100644 --- a/pkg/mimirtool/config/convert_test.go +++ b/pkg/mimirtool/config/convert_test.go @@ -14,24 +14,71 @@ import ( ) type conversionInput struct { - useNewDefaults bool - outputDefaults bool - inYAML []byte - inFlags []string + useNewDefaults bool + outputDefaults bool + yaml []byte + flags []string + dontLoadCommonOpts bool } -func testCortexAndGEM(t *testing.T, tc conversionInput, assert func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error)) { - t.Parallel() - t.Run("cortex->mimir", func(t *testing.T) { +func (in *conversionInput) loadCommonOpts(t *testing.T, yamlFile, flagsFile string) (commonYAML []byte, commonFlags []string) { + if in.dontLoadCommonOpts { + return nil, nil + } + if in.yaml == nil { + in.yaml = loadFile(t, yamlFile) + commonYAML = in.yaml + } + if in.flags == nil { + in.flags = loadFlags(t, flagsFile) + commonFlags = in.flags + } + + return +} + +func testConvertCortexAndGEM(t *testing.T, tc conversionInput, test func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error)) { + testConvertCortex(t, tc, test) + testConvertGEM(t, tc, test) +} + +func testConvertGEM(t *testing.T, tc conversionInput, test func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error)) { + t.Run("gem170->gem200", func(t *testing.T) { t.Parallel() - mimirYAML, mimirFlags, mimirNotices, mimirErr := Convert(tc.inYAML, tc.inFlags, CortexToMimirMapper(), DefaultCortexConfig, DefaultMimirConfig, tc.useNewDefaults, tc.outputDefaults) - assert(t, mimirYAML, mimirFlags, mimirNotices, mimirErr) + + expectedCommonYAML, expectedCommonFlags := tc.loadCommonOpts(t, "testdata/gem/common-options-old.yaml", "testdata/gem/common-flags-old.txt") + outYAML, outFlags, notices, err := Convert(tc.yaml, tc.flags, GEM170ToGEM200Mapper(), DefaultGEM170Config, DefaultGEM200COnfig, tc.useNewDefaults, tc.outputDefaults) + + if expectedCommonYAML != nil { + assert.YAMLEq(t, string(expectedCommonYAML), string(outYAML), "common config options did not map correctly") + outYAML = nil + } + if expectedCommonFlags != nil { + assert.ElementsMatch(t, expectedCommonFlags, outFlags, "common config options did not map correctly") + outFlags = []string{} + } + + test(t, outYAML, outFlags, notices, err) }) +} - t.Run("gem170->gem200", func(t *testing.T) { +func testConvertCortex(t *testing.T, tc conversionInput, test func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error)) { + t.Run("cortex->mimir", func(t *testing.T) { t.Parallel() - gemYAML, gemFlags, gemNotices, gemErr := Convert(tc.inYAML, tc.inFlags, GEM170ToGEM200Mapper(), DefaultGEM170Config, DefaultGEM200COnfig, tc.useNewDefaults, tc.outputDefaults) - assert(t, gemYAML, gemFlags, gemNotices, gemErr) + + expectedCommonYAML, expectedCommonFlags := tc.loadCommonOpts(t, "testdata/common-options.yaml", "testdata/common-flags.txt") + outYAML, outFlags, notices, err := Convert(tc.yaml, tc.flags, CortexToMimirMapper(), DefaultCortexConfig, DefaultMimirConfig, tc.useNewDefaults, tc.outputDefaults) + + if expectedCommonYAML != nil { + assert.YAMLEq(t, string(expectedCommonYAML), string(outYAML), "common config options did not map correctly") + outYAML = nil + } + if expectedCommonFlags != nil { + assert.ElementsMatch(t, expectedCommonFlags, outFlags, "common config options did not map correctly") + outFlags = []string{} + } + + test(t, outYAML, outFlags, notices, err) }) } @@ -41,6 +88,8 @@ func TestConvert_Cortex(t *testing.T) { useNewDefaults bool inFile, outFile string inFlagsFile, outFlagsFile string + skipGEMTest bool + dontAddCommonOpts bool }{ { name: "shouldn't need any conversion", @@ -83,6 +132,7 @@ func TestConvert_Cortex(t *testing.T) { inFlagsFile: "testdata/flags-precedence-old.flags.txt", outFlagsFile: "testdata/flags-precedence-new.flags.txt", outFile: "testdata/common-options.yaml", + skipGEMTest: true, // no need to test this in GEM too; plus, output for GEM also includes GEM common opts }, { name: "ruler.storage maps to ruler_storage", @@ -208,29 +258,33 @@ func TestConvert_Cortex(t *testing.T) { outFile: "testdata/instance-interface-names-explicit-new.yaml", }, { - name: "server.http-listen-port old default is printed even when implicitly using the old default", - inFlagsFile: "testdata/empty.txt", // prevent the test from using common-flags.txt - inFile: "testdata/empty.yaml", - outFile: "testdata/server-listen-http-port-new.yaml", + name: "server.http-listen-port old default is printed even when implicitly using the old default", + skipGEMTest: true, + dontAddCommonOpts: true, // The common opts are in the outFile. That's the same reason why this test case doesn't work for GEM + inFile: "testdata/empty.yaml", + outFile: "testdata/server-listen-http-port-new.yaml", }, { - name: "server.http-listen-port old default is retained with useNewDefaults=true", - inFlagsFile: "testdata/empty.txt", // prevent the test from using common-flags.txt - useNewDefaults: true, - inFile: "testdata/server-listen-http-port-old.yaml", - outFile: "testdata/server-listen-http-port-new.yaml", + name: "server.http-listen-port old default is retained with useNewDefaults=true", + skipGEMTest: true, + dontAddCommonOpts: true, // The common opts are in the outFile. That's the same reason why this test case doesn't work for GEM + useNewDefaults: true, + inFile: "testdata/server-listen-http-port-old.yaml", + outFile: "testdata/server-listen-http-port-new.yaml", }, { - name: "server.http-listen-port old default is retained with useNewDefaults=false", - inFlagsFile: "testdata/empty.txt", // prevent the test from using common-flags.txt - inFile: "testdata/server-listen-http-port-old.yaml", - outFile: "testdata/server-listen-http-port-new.yaml", + name: "server.http-listen-port old default is retained with useNewDefaults=false", + skipGEMTest: true, + dontAddCommonOpts: true, // The common opts are in the outFile. That's the same reason why this test case doesn't work for GEM + inFile: "testdata/server-listen-http-port-old.yaml", + outFile: "testdata/server-listen-http-port-new.yaml", }, { - name: "server.http-listen-port random value is retained with useNewDefaults=false", - inFlagsFile: "testdata/empty.txt", // prevent the test from using common-flags.txt - inFile: "testdata/server-listen-http-port-random-old.yaml", - outFile: "testdata/server-listen-http-port-random-new.yaml", + name: "server.http-listen-port random value is retained with useNewDefaults=false", + skipGEMTest: true, + dontAddCommonOpts: true, // The common opts are in the outFile. That's the same reason why this test case doesn't work for GEM + inFile: "testdata/server-listen-http-port-random-old.yaml", + outFile: "testdata/server-listen-http-port-random-new.yaml", }, { name: "flags with quotes and JSON don't get interpreted escaped", @@ -247,6 +301,11 @@ func TestConvert_Cortex(t *testing.T) { inFile: "testdata/duration-list-old.yaml", outFile: "testdata/duration-list-new.yaml", }, + { + name: "instance_id is preserved", + inFlagsFile: "testdata/ring-instance-id-old.flags.txt", + outFlagsFile: "testdata/ring-instance-id-new.flags.txt", + }, { name: "new frontend.results_cache.backend == memcached when old query_range.cache_results == true", inFile: "testdata/query-frontend-results-cache-old.yaml", @@ -257,33 +316,26 @@ func TestConvert_Cortex(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - inBytes, expectedOut := loadFile(t, tc.inFile), loadFile(t, tc.outFile) - inFlags, expectedOutFlags := loadFlags(t, tc.inFlagsFile), loadFlags(t, tc.outFlagsFile) - if inFlags == nil { - inFlags = loadFlags(t, "testdata/common-flags.txt") - expectedOutFlags = inFlags - } - if inBytes == nil { - inBytes = loadFile(t, "testdata/common-options.yaml") - expectedOut = inBytes - } + t.Parallel() + expectedOut := loadFile(t, tc.outFile) + expectedOutFlags := loadFlags(t, tc.outFlagsFile) in := conversionInput{ - useNewDefaults: tc.useNewDefaults, - outputDefaults: false, - inYAML: inBytes, - inFlags: inFlags, + useNewDefaults: tc.useNewDefaults, + dontLoadCommonOpts: tc.dontAddCommonOpts, + yaml: loadFile(t, tc.inFile), + flags: loadFlags(t, tc.inFlagsFile), } - testCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + assertion := func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { assert.NoError(t, err) - assert.ElementsMatch(t, expectedOutFlags, outFlags) - if expectedOut == nil { - expectedOut = []byte("{}") - } assert.YAMLEq(t, string(expectedOut), string(outYAML)) - }) + } + testConvertCortex(t, in, assertion) + if !tc.skipGEMTest { + testConvertGEM(t, in, assertion) + } }) } } @@ -294,11 +346,42 @@ func TestConvert_GEM(t *testing.T) { useNewDefaults bool inFile, outFile string inFlagsFile, outFlagsFile string + dontAddCommonOpts bool }{ { name: "proxy_targets get translated", - inFile: "testdata/proxy-targets.yaml", - outFile: "testdata/proxy-targets.yaml", + inFile: "testdata/gem/proxy-targets.yaml", + outFile: "testdata/gem/proxy-targets.yaml", + }, + { + name: "server.http-listen-port old default is printed even when implicitly using the old default", + dontAddCommonOpts: true, // The common opts are in the outFile + inFile: "testdata/empty.yaml", + outFile: "testdata/gem/server-listen-http-port-new.yaml", + }, + { + name: "server.http-listen-port old default is retained with useNewDefaults=true", + dontAddCommonOpts: true, // The common opts are in the outFile + useNewDefaults: true, + inFile: "testdata/gem/server-listen-http-port-old.yaml", + outFile: "testdata/gem/server-listen-http-port-new.yaml", + }, + { + name: "server.http-listen-port old default is retained with useNewDefaults=false", + dontAddCommonOpts: true, // The common opts are in the outFile + inFile: "testdata/gem/server-listen-http-port-old.yaml", + outFile: "testdata/gem/server-listen-http-port-new.yaml", + }, + { + name: "server.http-listen-port random value is retained with useNewDefaults=false", + dontAddCommonOpts: true, // The common opts are in the outFile + inFile: "testdata/gem/server-listen-http-port-random-old.yaml", + outFile: "testdata/gem/server-listen-http-port-random-new.yaml", + }, + { + name: "instance_id is preserved", + inFlagsFile: "testdata/gem/ring-instance-id-old.flags.txt", + outFlagsFile: "testdata/gem/ring-instance-id-new.flags.txt", }, } @@ -306,26 +389,21 @@ func TestConvert_GEM(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() - inBytes, expectedOut := loadFile(t, tc.inFile), loadFile(t, tc.outFile) - inFlags, expectedOutFlags := loadFlags(t, tc.inFlagsFile), loadFlags(t, tc.outFlagsFile) - if inFlags == nil { - inFlags = loadFlags(t, "testdata/common-flags.txt") - expectedOutFlags = inFlags - } - if inBytes == nil { - inBytes = loadFile(t, "testdata/common-options.yaml") - expectedOut = inBytes - } + expectedOut := loadFile(t, tc.outFile) + expectedOutFlags := loadFlags(t, tc.outFlagsFile) - outYAML, outFlags, _, err := Convert(inBytes, inFlags, GEM170ToGEM200Mapper(), DefaultGEM170Config, DefaultGEM200COnfig, tc.useNewDefaults, false) - assert.NoError(t, err) - - assert.ElementsMatch(t, expectedOutFlags, outFlags) - if expectedOut == nil { - expectedOut = []byte("{}") + in := conversionInput{ + useNewDefaults: tc.useNewDefaults, + dontLoadCommonOpts: tc.dontAddCommonOpts, + yaml: loadFile(t, tc.inFile), + flags: loadFlags(t, tc.inFlagsFile), } - assert.YAMLEq(t, string(expectedOut), string(outYAML)) + testConvertGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + assert.NoError(t, err) + assert.ElementsMatch(t, expectedOutFlags, outFlags) + assert.YAMLEq(t, string(expectedOut), string(outYAML)) + }) }) } } @@ -353,14 +431,13 @@ func TestConvert_InvalidConfigs(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - inBytes := loadFile(t, tc.inFile) - inFlags := loadFlags(t, tc.inFlagsFile) - + t.Parallel() in := conversionInput{ - inFlags: inFlags, - inYAML: inBytes, + flags: loadFlags(t, tc.inFlagsFile), + yaml: loadFile(t, tc.inFile), + dontLoadCommonOpts: true, } - testCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + testConvertCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { assert.EqualError(t, err, tc.expectedErr) }) }) @@ -508,7 +585,7 @@ var changedCortexDefaults = []ChangedDefault{ } func TestChangedCortexDefaults(t *testing.T) { - // Create cortex config where all params have explicitly set default values + // Create cortex config where all params have explicitly set default values so that all of them can be changed and reported as changed params := DefaultCortexConfig() err := params.Walk(func(path string, _ Value) error { return params.SetValue(path, params.MustGetDefaultValue(path)) @@ -517,10 +594,15 @@ func TestChangedCortexDefaults(t *testing.T) { config, err := yaml.Marshal(params) require.NoError(t, err) - // Create cortex config where all params have explicitly set default values so that all of them can be changed and reported as changed - _, _, notices, err := Convert(config, nil, CortexToMimirMapper(), DefaultCortexConfig, DefaultMimirConfig, true, false) - require.NoError(t, err) - assert.ElementsMatch(t, changedCortexDefaults, notices.ChangedDefaults) + in := conversionInput{ + useNewDefaults: true, + yaml: config, + } + + testConvertCortex(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + require.NoError(t, err) + assert.ElementsMatch(t, changedCortexDefaults, notices.ChangedDefaults) + }) } func TestChangedGEMDefaults(t *testing.T) { @@ -528,8 +610,21 @@ func TestChangedGEMDefaults(t *testing.T) { {Path: "admin_api.leader_election.client_config.max_send_msg_size", OldDefault: "16777216", NewDefault: "104857600"}, {Path: "admin_api.leader_election.enabled", OldDefault: "false", NewDefault: "true"}, {Path: "admin_api.leader_election.ring.instance_interface_names", OldDefault: "eth0,en0", NewDefault: ""}, - {Path: "auth.type", OldDefault: "trust", NewDefault: "enterprise"}, {Path: "graphite.enabled", OldDefault: "false", NewDefault: "true"}, + {Path: "graphite.querier.aggregation_cache.memcached.addresses", OldDefault: "dnssrvnoa+_memcached._tcp.", NewDefault: ""}, + {Path: "graphite.querier.aggregation_cache.memcached.max_async_buffer_size", OldDefault: "10000", NewDefault: "25000"}, + {Path: "graphite.querier.aggregation_cache.memcached.max_async_concurrency", OldDefault: "10", NewDefault: "50"}, + {Path: "graphite.querier.aggregation_cache.memcached.max_get_multi_batch_size", OldDefault: "1024", NewDefault: "100"}, + {Path: "graphite.querier.aggregation_cache.memcached.max_idle_connections", OldDefault: "16", NewDefault: "100"}, + {Path: "graphite.querier.aggregation_cache.memcached.max_item_size", OldDefault: "0", NewDefault: "1048576"}, + {Path: "graphite.querier.aggregation_cache.memcached.timeout", OldDefault: "100ms", NewDefault: "200ms"}, + {Path: "graphite.querier.metric_name_cache.memcached.addresses", OldDefault: "dnssrvnoa+_memcached._tcp.", NewDefault: ""}, + {Path: "graphite.querier.metric_name_cache.memcached.max_async_buffer_size", OldDefault: "10000", NewDefault: "25000"}, + {Path: "graphite.querier.metric_name_cache.memcached.max_async_concurrency", OldDefault: "10", NewDefault: "50"}, + {Path: "graphite.querier.metric_name_cache.memcached.max_get_multi_batch_size", OldDefault: "1024", NewDefault: "100"}, + {Path: "graphite.querier.metric_name_cache.memcached.max_idle_connections", OldDefault: "16", NewDefault: "100"}, + {Path: "graphite.querier.metric_name_cache.memcached.max_item_size", OldDefault: "0", NewDefault: "1048576"}, + {Path: "graphite.querier.metric_name_cache.memcached.timeout", OldDefault: "100ms", NewDefault: "200ms"}, {Path: "graphite.querier.schemas.backend", OldDefault: "s3", NewDefault: "filesystem"}, {Path: "instrumentation.enabled", OldDefault: "false", NewDefault: "true"}, {Path: "limits.compactor_split_groups", OldDefault: "4", NewDefault: "1"}, @@ -560,10 +655,15 @@ func TestChangedGEMDefaults(t *testing.T) { config, err := yaml.Marshal(params) require.NoError(t, err) - // Convert while also converting explicitly set defaults to new defaults - _, _, notices, err := Convert(config, nil, GEM170ToGEM200Mapper(), DefaultGEM170Config, DefaultGEM200COnfig, true, false) - require.NoError(t, err) - assert.ElementsMatch(t, expectedChangedDefaults, notices.ChangedDefaults) + in := conversionInput{ + useNewDefaults: true, + yaml: config, + } + + testConvertGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + require.NoError(t, err) + assert.ElementsMatch(t, expectedChangedDefaults, notices.ChangedDefaults) + }) } func TestConvert_UseNewDefaults(t *testing.T) { @@ -610,18 +710,13 @@ func TestConvert_UseNewDefaults(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - // We pass the common flags in, but ignore the output. - // This is so that the always-present options in common-flags.txt get output in the flags instead of - // in the out YAML. This helps to keep the test cases and expected YAML clean of - // unrelated config options (e.g. server.http_listen_port) - inFlags := loadFlags(t, "testdata/common-flags.txt") + t.Parallel() in := conversionInput{ - inYAML: tc.inYAML, - inFlags: inFlags, + yaml: tc.inYAML, useNewDefaults: tc.useNewDefaults, } - testCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + testConvertCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { require.NoError(t, err) assert.YAMLEq(t, string(tc.expectedYAML), string(outYAML)) @@ -642,13 +737,13 @@ func TestConvert_NotInYAMLIsNotPrinted(t *testing.T) { for _, showDefaults := range []bool{true, false} { showDefaults, useNewDefaults := showDefaults, useNewDefaults t.Run(fmt.Sprintf("useNewDefault=%t_showDefaults=%t", useNewDefaults, showDefaults), func(t *testing.T) { + t.Parallel() in := conversionInput{ - useNewDefaults: useNewDefaults, - outputDefaults: showDefaults, - inYAML: nil, - inFlags: nil, + useNewDefaults: useNewDefaults, + outputDefaults: showDefaults, + dontLoadCommonOpts: true, } - testCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + testConvertCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { assert.NoError(t, err) assert.NotContains(t, string(outYAML), notInYaml) }) @@ -659,13 +754,13 @@ func TestConvert_NotInYAMLIsNotPrinted(t *testing.T) { func TestConvert_PassingOnlyYAMLReturnsOnlyYAML(t *testing.T) { inYAML := []byte("distributor: { remote_timeout: 11s }") - expectedOutYAML := []byte(`{distributor: { remote_timeout: 11s }, server: { http_listen_port: 80 }}`) + expectedOutYAML := inYAML in := conversionInput{ - inYAML: inYAML, + yaml: inYAML, } - testCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + testConvertCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { assert.NoError(t, err) assert.YAMLEq(t, string(expectedOutYAML), string(outYAML)) assert.Empty(t, outFlags) @@ -674,15 +769,15 @@ func TestConvert_PassingOnlyYAMLReturnsOnlyYAML(t *testing.T) { func TestConvert_PassingOnlyFlagsReturnsOnlyFlags(t *testing.T) { inFlags := []string{"-distributor.remote-timeout=11s"} - expectedOutFlags := append([]string{"-server.http-listen-port=80"}, inFlags...) + expectedOutFlags := inFlags in := conversionInput{ - inFlags: inFlags, + flags: inFlags, } - testCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { + testConvertCortexAndGEM(t, in, func(t *testing.T, outYAML []byte, outFlags []string, notices ConversionNotices, err error) { assert.NoError(t, err) - assert.YAMLEq(t, "{}", string(outYAML)) + assert.Empty(t, outYAML) assert.ElementsMatch(t, expectedOutFlags, outFlags) }) } diff --git a/pkg/mimirtool/config/cortex.go b/pkg/mimirtool/config/cortex.go index b00e2f23819..916daee31bc 100644 --- a/pkg/mimirtool/config/cortex.go +++ b/pkg/mimirtool/config/cortex.go @@ -16,7 +16,7 @@ import ( func CortexToMimirMapper() Mapper { return MultiMapper{ mapCortexInstanceInterfaceNames(), - // first try to naively map keys from old config to same keys from new config + // Try to naively map keys from old config to same keys from new config BestEffortDirectMapper{}, // next map alertmanager URL in the ruler config MapperFunc(alertmanagerURLMapperFunc), @@ -31,13 +31,15 @@ func CortexToMimirMapper() Mapper { // Remap sharding configs MapperFunc(updateKVStoreValue), // Convert provided memcached service and host to the DNS service discovery format - MapperFunc(mapMemcachedAddresses), + mapMemcachedAddresses("query_range.results_cache.cache.memcached_client", "frontend.results_cache.memcached"), // Map `-*.s3.url` to `-*.s3.(endpoint|access_key_id|secret_access_key)` mapRulerAlertmanagerS3URL("alertmanager.storage", "alertmanager_storage"), mapRulerAlertmanagerS3URL("ruler.storage", "ruler_storage"), // Map `-*.s3.bucketnames` and (maybe part of `-*s3.s3.url`) to `-*.s3.bucket-name` mapRulerAlertmanagerS3Buckets("alertmanager.storage", "alertmanager_storage"), mapRulerAlertmanagerS3Buckets("ruler.storage", "ruler_storage"), // Prevent server.http_listen_port from being updated with a new default and always output it. - MapperFunc(mapServerHTTPListenPort), + setOldDefaultExplicitly("server.http_listen_port"), + // Manually override the dynamic fields' default values. + MapperFunc(mapCortexRingInstanceIDDefaults), // Set frontend.results_cache.backend when results cache was enabled in cortex MapperFunc(mapQueryFrontendBackend), } @@ -130,6 +132,7 @@ var cortexRenameMappings = map[string]Mapping{ "ingester.lifecycler.ring.zone_awareness_enabled": RenameMapping("ingester.ring.zone_awareness_enabled"), "ingester.lifecycler.tokens_file_path": RenameMapping("ingester.ring.tokens_file_path"), "ingester.lifecycler.unregister_on_shutdown": RenameMapping("ingester.ring.unregister_on_shutdown"), + notInYaml + ".ingester-lifecycler-id": RenameMapping("ingester.ring.instance_id"), "auth_enabled": RenameMapping("multitenancy_enabled"), } @@ -453,26 +456,25 @@ func mapRulerAlertmanagerS3Buckets(dotStoragePath, storagePath string) Mapper { // mapMemcachedAddresses maps query_range...memcached_client.host and .service to a DNS Service Discovery format // address. This should preserve the behaviour in cortex v1.11.0: // https://github.com/cortexproject/cortex/blob/43c646ba3ff906e80a6a1812f2322a0c276e9deb/pkg/chunk/cache/memcached_client.go#L242-L258 -func mapMemcachedAddresses(source, target Parameters) error { - const ( - oldPrefix = "query_range.results_cache.cache.memcached_client" - newPrefix = "frontend.results_cache.memcached" - ) - presetAddressesVal, err := source.GetValue(oldPrefix + ".addresses") - if err != nil { - return err - } - if presetAddressesVal.AsString() != "" { - return nil // respect already set values of addresses - } +// Also applies to GEM and graphite querier caches +func mapMemcachedAddresses(oldPrefix, newPrefix string) MapperFunc { + return func(source, target Parameters) error { + presetAddressesVal, err := source.GetValue(oldPrefix + ".addresses") + if err != nil { + return err + } + if presetAddressesVal.AsString() != "" { + return nil // respect already set values of addresses + } - service, hostname := source.MustGetValue(oldPrefix+".service"), source.MustGetValue(oldPrefix+".host") - if service.IsUnset() || hostname.IsUnset() { - return nil - } - newAddress := fmt.Sprintf("dnssrvnoa+_%s._tcp.%s", service.AsString(), hostname.AsString()) + service, hostname := source.MustGetValue(oldPrefix+".service"), source.MustGetValue(oldPrefix+".host") + if service.IsUnset() || hostname.IsUnset() { + return nil + } + newAddress := fmt.Sprintf("dnssrvnoa+_%s._tcp.%s", service.AsString(), hostname.AsString()) - return target.SetValue(newPrefix+".addresses", StringValue(newAddress)) + return target.SetValue(newPrefix+".addresses", StringValue(newAddress)) + } } func mapCortexInstanceInterfaceNames() Mapper { @@ -503,7 +505,8 @@ func mapInstanceInterfaceNames(ifaceNames map[string]string) Mapper { } instanceNamesVal, _ := source.GetValue(sourcePath) if !instanceNamesVal.IsUnset() { - // The user has set the value to something, we want to keep that + // The user has set the value to something, we want to keep that. + // But also when mapping defaults this restores the old default when mapping defaults after we've set it to Nil above. errs.Add(target.SetValue(targetPath, instanceNamesVal)) continue } @@ -513,21 +516,24 @@ func mapInstanceInterfaceNames(ifaceNames map[string]string) Mapper { }) } -func mapServerHTTPListenPort(source, target Parameters) error { - portVal, err := source.GetValue("server.http_listen_port") - if err != nil { - return err - } - // If the port wasn't set, or it was set to the default - if portVal.IsUnset() || !differentFromDefault(source, "server.http_listen_port") { - err = target.SetValue("server.http_listen_port", IntValue(80)) - // We set the default after the value itself because when mapping defaults - // calling `SetValue` actually modifies the default value. So we want to retain the target default as it is. - err2 := target.SetDefaultValue("server.http_listen_port", IntValue(8080)) - return multierror.New(err, err2).Err() - } +func setOldDefaultExplicitly(path string) Mapper { + return MapperFunc(func(source, target Parameters) error { + v, err := source.GetValue(path) + if err != nil { + return err + } - return nil + if v.IsUnset() || !differentFromDefault(source, path) { + err = target.SetValue(path, source.MustGetDefaultValue(path)) + // We set the default again after the value itself because when prepareSourceDefaults is mapping defaults + // `SetValue` actually sets the default value. + // Also set the source default to Nil, so that when updating defaults this parameter isn't affected + err2 := target.SetDefaultValue(path, Nil) + return multierror.New(err, err2).Err() + } + + return nil + }) } func mapQueryFrontendBackend(source, target Parameters) error { @@ -538,8 +544,19 @@ func mapQueryFrontendBackend(source, target Parameters) error { return nil } +func mapCortexRingInstanceIDDefaults(source, target Parameters) error { + return multierror.New( + target.SetDefaultValue("alertmanager.sharding_ring.instance_id", Nil), + target.SetDefaultValue("compactor.sharding_ring.instance_id", Nil), + target.SetDefaultValue("distributor.ring.instance_id", Nil), + target.SetDefaultValue("ingester.ring.instance_id", Nil), + target.SetDefaultValue("ruler.ring.instance_id", Nil), + target.SetDefaultValue("store_gateway.sharding_ring.instance_id", Nil), + ).Err() +} + // YAML Paths for config options removed since Cortex 1.11.0. -var removedConfigPaths = []string{ +var removedConfigPaths = append(gemRemovedConfigPath, []string{ "flusher.concurrent_flushes", // -flusher.concurrent-flushes "flusher.flush_op_timeout", // -flusher.flush-op-timeout "flusher.wal_dir", // -flusher.wal-dir @@ -1007,6 +1024,7 @@ var removedConfigPaths = []string{ "alertmanager.auto_webhook_root", // -alertmanager.configs.auto-webhook-root "api.response_compression_enabled", // -api.response-compression-enabled "compactor.sharding_enabled", // -compactor.sharding-enabled + "compactor.sharding_strategy", // -compactor.sharding-strategy "distributor.extra_queue_delay", // -distributor.extra-query-delay "distributor.shard_by_all_labels", // -distributor.shard-by-all-labels "distributor.sharding_strategy", // -distributor.sharding-strategy @@ -1027,7 +1045,7 @@ var removedConfigPaths = []string{ "ruler.sharding_strategy", // -ruler.sharding-strategy "store_gateway.sharding_enabled", // -store-gateway.sharding-enabled "store_gateway.sharding_strategy", // -store-gateway.sharding-strategy -} +}...) // CLI options removed since Cortex 1.10.0. These flags only existed as CLI Flags, and were not included in YAML Config. var removedCLIOptions = []string{ diff --git a/pkg/mimirtool/config/descriptors/cortex-v1.11.0-flags-only.json b/pkg/mimirtool/config/descriptors/cortex-v1.11.0-flags-only.json index bd57328da74..91b927c6dcf 100644 --- a/pkg/mimirtool/config/descriptors/cortex-v1.11.0-flags-only.json +++ b/pkg/mimirtool/config/descriptors/cortex-v1.11.0-flags-only.json @@ -66,6 +66,15 @@ "fieldDefaultValue": 0, "fieldFlag": "event.sample-rate", "fieldType": "int" + }, + { + "kind": "field", + "name": "ingester-lifecycler-id", + "required": false, + "desc": "ID to register in the ring.", + "fieldDefaultValue": null, + "fieldFlag": "ingester.lifecycler.id", + "fieldType": "string" } ] } diff --git a/pkg/mimirtool/config/descriptors/cortex-v1.11.0.json b/pkg/mimirtool/config/descriptors/cortex-v1.11.0.json index 597ba587735..5d02ce0e540 100644 --- a/pkg/mimirtool/config/descriptors/cortex-v1.11.0.json +++ b/pkg/mimirtool/config/descriptors/cortex-v1.11.0.json @@ -103,7 +103,7 @@ "kind": "field", "name": "http_listen_conn_limit", "required": false, - "desc": "Maximum number of simultaneous http connections, <=0 to disable", + "desc": "Maximum number of simultaneous http connections, \u003c=0 to disable", "fieldDefaultValue": 0, "fieldFlag": "server.http-conn-limit", "fieldType": "int" @@ -139,7 +139,7 @@ "kind": "field", "name": "grpc_listen_conn_limit", "required": false, - "desc": "Maximum number of simultaneous grpc connections, <=0 to disable", + "desc": "Maximum number of simultaneous grpc connections, \u003c=0 to disable", "fieldDefaultValue": 0, "fieldFlag": "server.grpc-conn-limit", "fieldType": "int" @@ -1055,6 +1055,15 @@ "fieldFlag": "distributor.ring.heartbeat-timeout", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldDefaultValue": null, + "fieldFlag": "distributor.ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -1066,6 +1075,24 @@ ], "fieldFlag": "distributor.ring.instance-interface-names", "fieldType": "list of string" + }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldDefaultValue": 0, + "fieldFlag": "distributor.ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldDefaultValue": "", + "fieldFlag": "distributor.ring.instance-addr", + "fieldType": "string" } ] }, @@ -1322,7 +1349,7 @@ "kind": "field", "name": "shuffle_sharding_ingesters_lookback_period", "required": false, - "desc": "When distributor's sharding strategy is shuffle-sharding and this setting is > 0, queriers fetch in-memory series from the minimum set of required ingesters, selecting only ingesters which may have received series since 'now - lookback period'. The lookback period should be greater or equal than the configured 'query store after' and 'query ingesters within'. If this setting is 0, queriers always query all ingesters (ingesters shuffle sharding on read path is disabled).", + "desc": "When distributor's sharding strategy is shuffle-sharding and this setting is \u003e 0, queriers fetch in-memory series from the minimum set of required ingesters, selecting only ingesters which may have received series since 'now - lookback period'. The lookback period should be greater or equal than the configured 'query store after' and 'query ingesters within'. If this setting is 0, queriers always query all ingesters (ingesters shuffle sharding on read path is disabled).", "fieldDefaultValue": 0, "fieldFlag": "querier.shuffle-sharding-ingesters-lookback-period", "fieldType": "duration" @@ -1928,6 +1955,15 @@ "fieldDefaultValue": true, "fieldFlag": "ingester.unregister-on-shutdown", "fieldType": "boolean" + }, + { + "kind": "field", + "name": "address", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldDefaultValue": "", + "fieldFlag": "ingester.lifecycler.addr", + "fieldType": "string" } ] }, @@ -2196,7 +2232,7 @@ "kind": "field", "name": "dynamodb_url", "required": false, - "desc": "DynamoDB endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:/// to use a mock in-memory implementation.", + "desc": "DynamoDB endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:///\u003ctable-name\u003e to use a mock in-memory implementation.", "fieldDefaultValue": {}, "fieldFlag": "dynamodb.url", "fieldType": "url" @@ -2275,7 +2311,7 @@ "name": "write_throttle_query", "required": false, "desc": "query to fetch throttle rates per table", - "fieldDefaultValue": "sum(rate(cortex_dynamo_throttled_total{operation=\"DynamoDB.BatchWriteItem\"}[1m])) by (table) > 0", + "fieldDefaultValue": "sum(rate(cortex_dynamo_throttled_total{operation=\"DynamoDB.BatchWriteItem\"}[1m])) by (table) \u003e 0", "fieldFlag": "metrics.write-throttle-query", "fieldType": "string" }, @@ -2284,7 +2320,7 @@ "name": "write_usage_query", "required": false, "desc": "query to fetch write capacity usage per table", - "fieldDefaultValue": "sum(rate(cortex_dynamo_consumed_capacity_total{operation=\"DynamoDB.BatchWriteItem\"}[15m])) by (table) > 0", + "fieldDefaultValue": "sum(rate(cortex_dynamo_consumed_capacity_total{operation=\"DynamoDB.BatchWriteItem\"}[15m])) by (table) \u003e 0", "fieldFlag": "metrics.usage-query", "fieldType": "string" }, @@ -2293,7 +2329,7 @@ "name": "read_usage_query", "required": false, "desc": "query to fetch read capacity usage per table", - "fieldDefaultValue": "sum(rate(cortex_dynamo_consumed_capacity_total{operation=\"DynamoDB.QueryPages\"}[1h])) by (table) > 0", + "fieldDefaultValue": "sum(rate(cortex_dynamo_consumed_capacity_total{operation=\"DynamoDB.QueryPages\"}[1h])) by (table) \u003e 0", "fieldFlag": "metrics.read-usage-query", "fieldType": "string" }, @@ -2302,7 +2338,7 @@ "name": "read_error_query", "required": false, "desc": "query to fetch read errors per table", - "fieldDefaultValue": "sum(increase(cortex_dynamo_failures_total{operation=\"DynamoDB.QueryPages\",error=\"ProvisionedThroughputExceededException\"}[1m])) by (table) > 0", + "fieldDefaultValue": "sum(increase(cortex_dynamo_failures_total{operation=\"DynamoDB.QueryPages\",error=\"ProvisionedThroughputExceededException\"}[1m])) by (table) \u003e 0", "fieldFlag": "metrics.read-error-query", "fieldType": "string" } @@ -2367,7 +2403,7 @@ "kind": "field", "name": "s3", "required": false, - "desc": "S3 endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:/// to use a mock in-memory implementation.", + "desc": "S3 endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:///\u003cbucket-name\u003e to use a mock in-memory implementation.", "fieldDefaultValue": {}, "fieldFlag": "s3.url", "fieldType": "url" @@ -3115,7 +3151,7 @@ "kind": "field", "name": "table_options", "required": false, - "desc": "Table options used to create index or chunk tables. This value is used as plain text in the table `WITH` like this, \"CREATE TABLE (...) WITH \". For details, see https://cortexmetrics.io/docs/production/cassandra. By default it will use the default table options of your Cassandra cluster.", + "desc": "Table options used to create index or chunk tables. This value is used as plain text in the table `WITH` like this, \"CREATE TABLE \u003cgenerated_by_cortex\u003e (...) WITH \u003ccassandra.table-options\u003e\". For details, see https://cortexmetrics.io/docs/production/cassandra. By default it will use the default table options of your Cassandra cluster.", "fieldDefaultValue": "", "fieldFlag": "cassandra.table-options", "fieldType": "string" @@ -3677,6 +3713,14 @@ "fieldType": "int" } ] + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldDefaultValue": "", + "fieldType": "string" } ] }, @@ -4259,6 +4303,14 @@ "fieldType": "int" } ] + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldDefaultValue": "", + "fieldType": "string" } ] }, @@ -4604,6 +4656,14 @@ "fieldType": "int" } ] + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldDefaultValue": "", + "fieldType": "string" } ] }, @@ -4933,7 +4993,7 @@ "kind": "field", "name": "max_query_lookback", "required": false, - "desc": "Limit how long back data (series and metadata) can be queried, up until duration ago. This limit is enforced in the query-frontend, querier and ruler. If the requested time range is outside the allowed range, the request will not fail but will be manipulated to only query data within the allowed time range. 0 to disable.", + "desc": "Limit how long back data (series and metadata) can be queried, up until \u003clookback\u003e duration ago. This limit is enforced in the query-frontend, querier and ruler. If the requested time range is outside the allowed range, the request will not fail but will be manipulated to only query data within the allowed time range. 0 to disable.", "fieldDefaultValue": 0, "fieldFlag": "querier.max-query-lookback", "fieldType": "duration" @@ -5376,7 +5436,7 @@ "kind": "field", "name": "log_queries_longer_than", "required": false, - "desc": "Log queries that are slower than the specified duration. Set to 0 to disable. Set to < 0 to enable on all queries.", + "desc": "Log queries that are slower than the specified duration. Set to 0 to disable. Set to \u003c 0 to enable on all queries.", "fieldDefaultValue": 0, "fieldFlag": "frontend.log-queries-longer-than", "fieldType": "duration" @@ -5607,6 +5667,15 @@ "fieldFlag": "frontend.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "address", + "required": false, + "desc": "IP address to advertise to querier (via scheduler) (resolved via interfaces by default).", + "fieldDefaultValue": "", + "fieldFlag": "frontend.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "downstream_url", @@ -5990,6 +6059,14 @@ "fieldType": "int" } ] + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldDefaultValue": "", + "fieldType": "string" } ] }, @@ -7392,7 +7469,7 @@ "kind": "field", "name": "addresses", "required": false, - "desc": "Comma separated list of memcached addresses. Supported prefixes are: dns+ (looked up as an A/AAAA query), dnssrv+ (looked up as a SRV query), dnssrvnoa+ (looked up as a SRV query, with no A/AAAA lookup made after that).", + "desc": "Comma separated list of memcached addresses. Supported prefixes are: dns+ (looked up as an A/AAAA query), dnssrv+ (looked up as a SRV query, dnssrvnoa+ (looked up as a SRV query, with no A/AAAA lookup made after that).", "fieldDefaultValue": "", "fieldFlag": "blocks-storage.bucket-store.index-cache.memcached.addresses", "fieldType": "string" @@ -7498,7 +7575,7 @@ "kind": "field", "name": "addresses", "required": false, - "desc": "Comma separated list of memcached addresses. Supported prefixes are: dns+ (looked up as an A/AAAA query), dnssrv+ (looked up as a SRV query), dnssrvnoa+ (looked up as a SRV query, with no A/AAAA lookup made after that).", + "desc": "Comma separated list of memcached addresses. Supported prefixes are: dns+ (looked up as an A/AAAA query), dnssrv+ (looked up as a SRV query, dnssrvnoa+ (looked up as a SRV query, with no A/AAAA lookup made after that).", "fieldDefaultValue": "", "fieldFlag": "blocks-storage.bucket-store.chunks-cache.memcached.addresses", "fieldType": "string" @@ -7640,7 +7717,7 @@ "kind": "field", "name": "addresses", "required": false, - "desc": "Comma separated list of memcached addresses. Supported prefixes are: dns+ (looked up as an A/AAAA query), dnssrv+ (looked up as a SRV query), dnssrvnoa+ (looked up as a SRV query, with no A/AAAA lookup made after that).", + "desc": "Comma separated list of memcached addresses. Supported prefixes are: dns+ (looked up as an A/AAAA query), dnssrv+ (looked up as a SRV query, dnssrvnoa+ (looked up as a SRV query, with no A/AAAA lookup made after that).", "fieldDefaultValue": "", "fieldFlag": "blocks-storage.bucket-store.metadata-cache.memcached.addresses", "fieldType": "string" @@ -7882,6 +7959,24 @@ "fieldFlag": "blocks-storage.bucket-store.max-chunk-pool-bytes", "fieldType": "int" }, + { + "kind": "field", + "name": "chunk_pool_min_bucket_size_bytes", + "required": false, + "desc": "Size - in bytes - of the smallest chunks pool bucket.", + "fieldDefaultValue": 16000, + "fieldFlag": "blocks-storage.bucket-store.chunk-pool-min-bucket-size-bytes", + "fieldType": "int" + }, + { + "kind": "field", + "name": "chunk_pool_max_bucket_size_bytes", + "required": false, + "desc": "Size - in bytes - of the largest chunks pool bucket.", + "fieldDefaultValue": 50000000, + "fieldFlag": "blocks-storage.bucket-store.chunk-pool-max-bucket-size-bytes", + "fieldType": "int" + }, { "kind": "field", "name": "index_header_lazy_loading_enabled", @@ -7895,10 +7990,28 @@ "kind": "field", "name": "index_header_lazy_loading_idle_timeout", "required": false, - "desc": "If index-header lazy loading is enabled and this setting is > 0, the store-gateway will offload unused index-headers after 'idle timeout' inactivity.", + "desc": "If index-header lazy loading is enabled and this setting is \u003e 0, the store-gateway will offload unused index-headers after 'idle timeout' inactivity.", "fieldDefaultValue": 1200000000000, "fieldFlag": "blocks-storage.bucket-store.index-header-lazy-loading-idle-timeout", "fieldType": "duration" + }, + { + "kind": "field", + "name": "partitioner_max_gap_bytes", + "required": false, + "desc": "Max size - in bytes - of a gap for which the partitioner aggregates together two bucket GET object requests.", + "fieldDefaultValue": 524288, + "fieldFlag": "blocks-storage.bucket-store.partitioner-max-gap-bytes", + "fieldType": "int" + }, + { + "kind": "field", + "name": "postings_offsets_in_mem_sampling", + "required": false, + "desc": "Controls what is the ratio of postings offsets that the store will hold in memory.", + "fieldDefaultValue": 32, + "fieldFlag": "blocks-storage.bucket-store.posting-offsets-in-mem-sampling", + "fieldType": "int" } ] }, @@ -8487,6 +8600,15 @@ "fieldFlag": "compactor.ring.wait-stability-max-duration", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldDefaultValue": null, + "fieldFlag": "compactor.ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -8499,6 +8621,24 @@ "fieldFlag": "compactor.ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldDefaultValue": 0, + "fieldFlag": "compactor.ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldDefaultValue": "", + "fieldFlag": "compactor.ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "wait_active_instance_timeout", @@ -8835,6 +8975,15 @@ "fieldFlag": "store-gateway.sharding-ring.wait-stability-max-duration", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldDefaultValue": null, + "fieldFlag": "store-gateway.sharding-ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -8847,6 +8996,24 @@ "fieldFlag": "store-gateway.sharding-ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldDefaultValue": 0, + "fieldFlag": "store-gateway.sharding-ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldDefaultValue": "", + "fieldFlag": "store-gateway.sharding-ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "instance_availability_zone", @@ -9361,7 +9528,7 @@ "kind": "field", "name": "s3", "required": false, - "desc": "S3 endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:/// to use a mock in-memory implementation.", + "desc": "S3 endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:///\u003cbucket-name\u003e to use a mock in-memory implementation.", "fieldDefaultValue": {}, "fieldFlag": "ruler.storage.s3.url", "fieldType": "url" @@ -10159,6 +10326,15 @@ "fieldFlag": "ruler.ring.heartbeat-timeout", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldDefaultValue": null, + "fieldFlag": "ruler.ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -10171,6 +10347,24 @@ "fieldFlag": "ruler.ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldDefaultValue": 0, + "fieldFlag": "ruler.ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldDefaultValue": "", + "fieldFlag": "ruler.ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "num_tokens", @@ -11204,6 +11398,15 @@ "fieldFlag": "alertmanager.sharding-ring.zone-awareness-enabled", "fieldType": "boolean" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldDefaultValue": null, + "fieldFlag": "alertmanager.sharding-ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -11216,6 +11419,24 @@ "fieldFlag": "alertmanager.sharding-ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldDefaultValue": 0, + "fieldFlag": "alertmanager.sharding-ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldDefaultValue": "", + "fieldFlag": "alertmanager.sharding-ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "instance_availability_zone", @@ -11492,7 +11713,7 @@ "kind": "field", "name": "s3", "required": false, - "desc": "S3 endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:/// to use a mock in-memory implementation.", + "desc": "S3 endpoint URL with escaped Key and Secret encoded. If only region is specified as a host, proper endpoint will be deduced. Use inmemory:///\u003cbucket-name\u003e to use a mock in-memory implementation.", "fieldDefaultValue": {}, "fieldFlag": "alertmanager.storage.s3.url", "fieldType": "url" diff --git a/pkg/mimirtool/config/descriptors/gem-v1.7.0-flags-only.json b/pkg/mimirtool/config/descriptors/gem-v1.7.0-flags-only.json index c5fcfb79012..7ce72027be2 100644 --- a/pkg/mimirtool/config/descriptors/gem-v1.7.0-flags-only.json +++ b/pkg/mimirtool/config/descriptors/gem-v1.7.0-flags-only.json @@ -75,6 +75,15 @@ "fieldDefaultValue": 0, "fieldFlag": "debug.block-profile-rate", "fieldType": "int" + }, + { + "kind": "field", + "name": "ingester-lifecycler-id", + "required": false, + "desc": "ID to register in the ring.", + "fieldDefaultValue": null, + "fieldFlag": "ingester.lifecycler.id", + "fieldType": "string" } ] } diff --git a/pkg/mimirtool/config/descriptors/gem-v1.7.0.json b/pkg/mimirtool/config/descriptors/gem-v1.7.0.json index 13a29958402..b556bcdcc57 100644 --- a/pkg/mimirtool/config/descriptors/gem-v1.7.0.json +++ b/pkg/mimirtool/config/descriptors/gem-v1.7.0.json @@ -1196,6 +1196,16 @@ "fieldFlag": "distributor.ring.heartbeat-timeout", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldValue": null, + "fieldDefaultValue": null, + "fieldFlag": "distributor.ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -1208,6 +1218,26 @@ ], "fieldFlag": "distributor.ring.instance-interface-names", "fieldType": "list of string" + }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldValue": null, + "fieldDefaultValue": 0, + "fieldFlag": "distributor.ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "distributor.ring.instance-addr", + "fieldType": "string" } ], "fieldValue": null, @@ -2201,6 +2231,16 @@ "fieldDefaultValue": true, "fieldFlag": "ingester.readiness-check-ring-health", "fieldType": "boolean" + }, + { + "kind": "field", + "name": "address", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "ingester.lifecycler.addr", + "fieldType": "string" } ], "fieldValue": null, @@ -4191,6 +4231,15 @@ ], "fieldValue": null, "fieldDefaultValue": null + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldType": "string" } ], "fieldValue": null, @@ -4851,6 +4900,15 @@ ], "fieldValue": null, "fieldDefaultValue": null + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldType": "string" } ], "fieldValue": null, @@ -5241,6 +5299,15 @@ ], "fieldValue": null, "fieldDefaultValue": null + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldType": "string" } ], "fieldValue": null, @@ -6445,6 +6512,16 @@ "fieldFlag": "frontend.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "address", + "required": false, + "desc": "IP address to advertise to querier (via scheduler) (resolved via interfaces by default).", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "frontend.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "downstream_url", @@ -6876,6 +6953,15 @@ ], "fieldValue": null, "fieldDefaultValue": null + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldType": "string" } ], "fieldValue": null, @@ -6934,6 +7020,16 @@ "fieldDefaultValue": false, "fieldFlag": "query-frontend.cache-unaligned-requests", "fieldType": "boolean" + }, + { + "kind": "field", + "name": "max_sharded_queries_limit_enabled", + "required": false, + "desc": "If enabled the query-frontend uses a new implementation of split by interval and results cache", + "fieldValue": null, + "fieldDefaultValue": false, + "fieldFlag": "query-frontend.max-sharded-queries-limit-enabled", + "fieldType": "boolean" } ], "fieldValue": null, @@ -9001,6 +9097,26 @@ "fieldFlag": "blocks-storage.bucket-store.max-chunk-pool-bytes", "fieldType": "int" }, + { + "kind": "field", + "name": "chunk_pool_min_bucket_size_bytes", + "required": false, + "desc": "Size - in bytes - of the smallest chunks pool bucket.", + "fieldValue": null, + "fieldDefaultValue": 16000, + "fieldFlag": "blocks-storage.bucket-store.chunk-pool-min-bucket-size-bytes", + "fieldType": "int" + }, + { + "kind": "field", + "name": "chunk_pool_max_bucket_size_bytes", + "required": false, + "desc": "Size - in bytes - of the largest chunks pool bucket.", + "fieldValue": null, + "fieldDefaultValue": 50000000, + "fieldFlag": "blocks-storage.bucket-store.chunk-pool-max-bucket-size-bytes", + "fieldType": "int" + }, { "kind": "field", "name": "series_hash_cache_max_size_bytes", @@ -9030,6 +9146,26 @@ "fieldDefaultValue": 1200000000000, "fieldFlag": "blocks-storage.bucket-store.index-header-lazy-loading-idle-timeout", "fieldType": "duration" + }, + { + "kind": "field", + "name": "partitioner_max_gap_bytes", + "required": false, + "desc": "Max size - in bytes - of a gap for which the partitioner aggregates together two bucket GET object requests.", + "fieldValue": null, + "fieldDefaultValue": 524288, + "fieldFlag": "blocks-storage.bucket-store.partitioner-max-gap-bytes", + "fieldType": "int" + }, + { + "kind": "field", + "name": "postings_offsets_in_mem_sampling", + "required": false, + "desc": "Controls what is the ratio of postings offsets that the store will hold in memory.", + "fieldValue": null, + "fieldDefaultValue": 32, + "fieldFlag": "blocks-storage.bucket-store.posting-offsets-in-mem-sampling", + "fieldType": "int" } ], "fieldValue": null, @@ -9691,6 +9827,16 @@ "fieldFlag": "compactor.ring.wait-stability-max-duration", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldValue": null, + "fieldDefaultValue": null, + "fieldFlag": "compactor.ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -9704,6 +9850,26 @@ "fieldFlag": "compactor.ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldValue": null, + "fieldDefaultValue": 0, + "fieldFlag": "compactor.ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "compactor.ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "wait_active_instance_timeout", @@ -10104,6 +10270,16 @@ "fieldFlag": "store-gateway.sharding-ring.wait-stability-max-duration", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldValue": null, + "fieldDefaultValue": null, + "fieldFlag": "store-gateway.sharding-ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -10117,6 +10293,26 @@ "fieldFlag": "store-gateway.sharding-ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldValue": null, + "fieldDefaultValue": 0, + "fieldFlag": "store-gateway.sharding-ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "store-gateway.sharding-ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "instance_availability_zone", @@ -11517,6 +11713,16 @@ "fieldFlag": "ruler.ring.heartbeat-timeout", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldValue": null, + "fieldDefaultValue": null, + "fieldFlag": "ruler.ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -11530,6 +11736,26 @@ "fieldFlag": "ruler.ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldValue": null, + "fieldDefaultValue": 0, + "fieldFlag": "ruler.ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "ruler.ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "num_tokens", @@ -12530,6 +12756,16 @@ "fieldFlag": "alertmanager.sharding-ring.zone-awareness-enabled", "fieldType": "boolean" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldValue": null, + "fieldDefaultValue": null, + "fieldFlag": "alertmanager.sharding-ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -12543,6 +12779,26 @@ "fieldFlag": "alertmanager.sharding-ring.instance-interface-names", "fieldType": "list of string" }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldValue": null, + "fieldDefaultValue": 0, + "fieldFlag": "alertmanager.sharding-ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "alertmanager.sharding-ring.instance-addr", + "fieldType": "string" + }, { "kind": "field", "name": "instance_availability_zone", @@ -14589,6 +14845,16 @@ "fieldFlag": "admin-api.leader-election.ring.tokens-observe-period", "fieldType": "duration" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldValue": null, + "fieldDefaultValue": null, + "fieldFlag": "admin-api.leader-election.ring.instance-id", + "fieldType": "string" + }, { "kind": "field", "name": "instance_interface_names", @@ -14601,6 +14867,26 @@ ], "fieldFlag": "admin-api.leader-election.ring.instance-interface-names", "fieldType": "list of string" + }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldValue": null, + "fieldDefaultValue": 0, + "fieldFlag": "admin-api.leader-election.ring.instance-port", + "fieldType": "int" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "admin-api.leader-election.ring.instance-addr", + "fieldType": "string" } ], "fieldValue": null, @@ -17571,6 +17857,15 @@ ], "fieldValue": null, "fieldDefaultValue": null + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldType": "string" } ], "fieldValue": null, @@ -17961,6 +18256,15 @@ ], "fieldValue": null, "fieldDefaultValue": null + }, + { + "kind": "field", + "name": "prefix", + "required": false, + "desc": "", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldType": "string" } ], "fieldValue": null, @@ -18420,6 +18724,16 @@ "required": false, "desc": "", "blockEntries": [ + { + "kind": "field", + "name": "type", + "required": false, + "desc": "Type of license.", + "fieldValue": null, + "fieldDefaultValue": "jwt", + "fieldFlag": "license.type", + "fieldType": "string" + }, { "kind": "field", "name": "path", diff --git a/pkg/mimirtool/config/descriptors/gem-v2.0.0.json b/pkg/mimirtool/config/descriptors/gem-v2.0.0.json index f69f7237c41..5007b122b06 100644 --- a/pkg/mimirtool/config/descriptors/gem-v2.0.0.json +++ b/pkg/mimirtool/config/descriptors/gem-v2.0.0.json @@ -10028,6 +10028,17 @@ "fieldType": "duration", "fieldCategory": "advanced" }, + { + "kind": "field", + "name": "instance_id", + "required": false, + "desc": "Instance ID to register in the ring.", + "fieldValue": null, + "fieldDefaultValue": "\u003chostname\u003e", + "fieldFlag": "admin-api.leader-election.ring.instance-id", + "fieldType": "string", + "fieldCategory": "advanced" + }, { "kind": "field", "name": "instance_interface_names", @@ -10037,6 +10048,28 @@ "fieldDefaultValue": [], "fieldFlag": "admin-api.leader-election.ring.instance-interface-names", "fieldType": "list of string" + }, + { + "kind": "field", + "name": "instance_port", + "required": false, + "desc": "Port to advertise in the ring (defaults to server.grpc-listen-port).", + "fieldValue": null, + "fieldDefaultValue": 0, + "fieldFlag": "admin-api.leader-election.ring.instance-port", + "fieldType": "int", + "fieldCategory": "advanced" + }, + { + "kind": "field", + "name": "instance_addr", + "required": false, + "desc": "IP address to advertise in the ring.", + "fieldValue": null, + "fieldDefaultValue": "", + "fieldFlag": "admin-api.leader-election.ring.instance-addr", + "fieldType": "string", + "fieldCategory": "advanced" } ], "fieldValue": null, @@ -12366,7 +12399,8 @@ "fieldValue": null, "fieldDefaultValue": 10000000000, "fieldFlag": "graphite.querier.schemas.schema-ttl", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -12376,7 +12410,8 @@ "fieldValue": null, "fieldDefaultValue": "/etc/cortextank/storage-schemas.conf", "fieldFlag": "graphite.querier.schemas.default-storage-schemas-file", - "fieldType": "string" + "fieldType": "string", + "fieldCategory": "advanced" }, { "kind": "field", @@ -12386,7 +12421,8 @@ "fieldValue": null, "fieldDefaultValue": "/etc/cortextank/storage-aggregation.conf", "fieldFlag": "graphite.querier.schemas.default-storage-aggregations-file", - "fieldType": "string" + "fieldType": "string", + "fieldCategory": "advanced" }, { "kind": "field", @@ -12396,7 +12432,8 @@ "fieldValue": null, "fieldDefaultValue": false, "fieldFlag": "graphite.querier.schemas.enable-user-overrides", - "fieldType": "boolean" + "fieldType": "boolean", + "fieldCategory": "advanced" }, { "kind": "field", @@ -12962,7 +12999,8 @@ "fieldValue": null, "fieldDefaultValue": false, "fieldFlag": "graphite.querier.schemas.enable-deduplicator", - "fieldType": "boolean" + "fieldType": "boolean", + "fieldCategory": "advanced" }, { "kind": "block", @@ -12978,7 +13016,8 @@ "fieldValue": null, "fieldDefaultValue": 15000000000, "fieldFlag": "graphite.querier.schemas.deduplicator.timeout", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -12988,7 +13027,8 @@ "fieldValue": null, "fieldDefaultValue": 43200000000000, "fieldFlag": "graphite.querier.schemas.deduplicator.ttl", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -12998,7 +13038,8 @@ "fieldValue": null, "fieldDefaultValue": 100000000, "fieldFlag": "graphite.querier.schemas.deduplicator.retry-delay", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13008,7 +13049,8 @@ "fieldValue": null, "fieldDefaultValue": 10, "fieldFlag": "graphite.querier.schemas.deduplicator.max-retries", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "block", @@ -13034,17 +13076,19 @@ "fieldValue": null, "fieldDefaultValue": "memcached", "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.service", - "fieldType": "string" + "fieldType": "string", + "fieldCategory": "advanced" }, { "kind": "field", "name": "addresses", "required": false, - "desc": "EXPERIMENTAL: Comma separated addresses list in DNS Service Discovery format: https://cortexmetrics.io/docs/configuration/arguments/#dns-service-discovery", + "desc": "Comma separated addresses list in DNS Service Discovery format: https://cortexmetrics.io/docs/configuration/arguments/#dns-service-discovery", "fieldValue": null, "fieldDefaultValue": "", "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.addresses", - "fieldType": "string" + "fieldType": "string", + "fieldCategory": "experimental" }, { "kind": "field", @@ -13054,7 +13098,8 @@ "fieldValue": null, "fieldDefaultValue": 100000000, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.timeout", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13064,7 +13109,8 @@ "fieldValue": null, "fieldDefaultValue": 16, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.max-idle-conns", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13074,7 +13120,8 @@ "fieldValue": null, "fieldDefaultValue": 0, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.max-item-size", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13084,7 +13131,8 @@ "fieldValue": null, "fieldDefaultValue": 60000000000, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.update-interval", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13094,7 +13142,8 @@ "fieldValue": null, "fieldDefaultValue": true, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.consistent-hash", - "fieldType": "boolean" + "fieldType": "boolean", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13104,7 +13153,8 @@ "fieldValue": null, "fieldDefaultValue": 10, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.circuit-breaker-consecutive-failures", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13114,7 +13164,8 @@ "fieldValue": null, "fieldDefaultValue": 10000000000, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.circuit-breaker-timeout", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13124,7 +13175,8 @@ "fieldValue": null, "fieldDefaultValue": 10000000000, "fieldFlag": "graphite.querier.schemas.deduplicator.memcached.circuit-breaker-interval", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" } ], "fieldValue": null, @@ -13146,7 +13198,8 @@ "fieldValue": null, "fieldDefaultValue": 300000000000, "fieldFlag": "graphite.querier.cache-grace-period", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "block", @@ -13388,7 +13441,8 @@ "fieldValue": null, "fieldDefaultValue": 8, "fieldFlag": "graphite.querier.query-handling-concurrency", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13398,7 +13452,8 @@ "fieldValue": null, "fieldDefaultValue": 86400000000000, "fieldFlag": "graphite.querier.split-queries-by-interval", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13408,7 +13463,8 @@ "fieldValue": null, "fieldDefaultValue": true, "fieldFlag": "graphite.querier.proxy-bad-requests", - "fieldType": "boolean" + "fieldType": "boolean", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13428,7 +13484,8 @@ "fieldValue": null, "fieldDefaultValue": "32d", "fieldFlag": "graphite.querier.metrics-find-cutoff", - "fieldType": "string" + "fieldType": "string", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13438,7 +13495,8 @@ "fieldValue": null, "fieldDefaultValue": 1000000, "fieldFlag": "graphite.querier.max-points-per-req-soft", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13448,7 +13506,8 @@ "fieldValue": null, "fieldDefaultValue": 20000000, "fieldFlag": "graphite.querier.max-points-per-req-hard", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "block", @@ -13474,7 +13533,8 @@ "fieldValue": null, "fieldDefaultValue": 30000000000, "fieldFlag": "graphite.querier.query-timeout", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13484,7 +13544,8 @@ "fieldValue": null, "fieldDefaultValue": 30000000000, "fieldFlag": "graphite.querier.query-keep-alive", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13494,7 +13555,8 @@ "fieldValue": null, "fieldDefaultValue": 10, "fieldFlag": "graphite.querier.query-max-idle-conns", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13504,7 +13566,8 @@ "fieldValue": null, "fieldDefaultValue": 100, "fieldFlag": "graphite.querier.query-max-conns", - "fieldType": "int" + "fieldType": "int", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13514,7 +13577,8 @@ "fieldValue": null, "fieldDefaultValue": "graphite-querier", "fieldFlag": "graphite.querier.query-client-name", - "fieldType": "string" + "fieldType": "string", + "fieldCategory": "advanced" } ], "fieldValue": null, @@ -13548,7 +13612,8 @@ "fieldValue": null, "fieldDefaultValue": 30000000000, "fieldFlag": "graphite.querier.remote-subquery-timeout", - "fieldType": "duration" + "fieldType": "duration", + "fieldCategory": "advanced" }, { "kind": "field", @@ -13556,7 +13621,7 @@ "required": false, "desc": "If set, results from subqueries will be used. If false, queries that would be fanned out to subqueriers are answered locally. The remote subqueries are still issued but the results are dropped.", "fieldValue": null, - "fieldDefaultValue": false, + "fieldDefaultValue": true, "fieldFlag": "graphite.querier.use-remote-results", "fieldType": "boolean" }, @@ -13566,7 +13631,7 @@ "required": false, "desc": "Enables remote subquery server.", "fieldValue": null, - "fieldDefaultValue": false, + "fieldDefaultValue": true, "fieldFlag": "graphite.querier.enable-remote-subquerier", "fieldType": "boolean" } @@ -13703,7 +13768,7 @@ }, { "kind": "field", - "name": "keepalive", + "name": "keep_alive", "required": false, "desc": "KeepAlive for write to upstream Prometheus remote write API.", "fieldValue": null, @@ -13713,7 +13778,7 @@ }, { "kind": "field", - "name": "maxidleconns", + "name": "max_idle_conns", "required": false, "desc": "Max idle conns per host for writes to upstream Prometheus remote write API.", "fieldValue": null, @@ -13723,7 +13788,7 @@ }, { "kind": "field", - "name": "maxconns", + "name": "max_conns", "required": false, "desc": "Max open conns per host for writes to upstream Prometheus remote write API.", "fieldValue": null, @@ -13733,7 +13798,7 @@ }, { "kind": "field", - "name": "skiplabelvalidation", + "name": "skip_label_validation", "required": false, "desc": "If set to true sends requests with headers to skip label validation.", "fieldValue": null, diff --git a/pkg/mimirtool/config/gem.go b/pkg/mimirtool/config/gem.go index c811ef5a8ec..98864286d7d 100644 --- a/pkg/mimirtool/config/gem.go +++ b/pkg/mimirtool/config/gem.go @@ -8,7 +8,38 @@ func GEM170ToGEM200Mapper() Mapper { "blocks_storage.tsdb.max_exemplars": {}, "query_range.parallelise_shardable_queries": {}, } - gemRenames := make(map[string]Mapping, len(cortexRenameMappings)) + gemRenames := map[string]Mapping{ + "graphite.querier.metric_name_cache.background.writeback_buffer": RenameMapping("graphite.querier.metric_name_cache.memcached.max_async_buffer_size"), + "graphite.querier.metric_name_cache.background.writeback_goroutines": RenameMapping("graphite.querier.metric_name_cache.memcached.max_async_concurrency"), + "graphite.querier.metric_name_cache.memcached.batch_size": RenameMapping("graphite.querier.metric_name_cache.memcached.max_get_multi_batch_size"), + "graphite.querier.metric_name_cache.memcached.parallelism": RenameMapping("graphite.querier.metric_name_cache.memcached.max_get_multi_concurrency"), + "graphite.querier.metric_name_cache.memcached_client.addresses": RenameMapping("graphite.querier.metric_name_cache.memcached.addresses"), + "graphite.querier.metric_name_cache.memcached_client.max_idle_conns": RenameMapping("graphite.querier.metric_name_cache.memcached.max_idle_connections"), + "graphite.querier.metric_name_cache.memcached_client.max_item_size": RenameMapping("graphite.querier.metric_name_cache.memcached.max_item_size"), + "graphite.querier.metric_name_cache.memcached_client.timeout": RenameMapping("graphite.querier.metric_name_cache.memcached.timeout"), + + "graphite.querier.aggregation_cache.background.writeback_buffer": RenameMapping("graphite.querier.aggregation_cache.memcached.max_async_buffer_size"), + "graphite.querier.aggregation_cache.background.writeback_goroutines": RenameMapping("graphite.querier.aggregation_cache.memcached.max_async_concurrency"), + "graphite.querier.aggregation_cache.memcached.batch_size": RenameMapping("graphite.querier.aggregation_cache.memcached.max_get_multi_batch_size"), + "graphite.querier.aggregation_cache.memcached.parallelism": RenameMapping("graphite.querier.aggregation_cache.memcached.max_get_multi_concurrency"), + "graphite.querier.aggregation_cache.memcached_client.addresses": RenameMapping("graphite.querier.aggregation_cache.memcached.addresses"), + "graphite.querier.aggregation_cache.memcached_client.max_idle_conns": RenameMapping("graphite.querier.aggregation_cache.memcached.max_idle_connections"), + "graphite.querier.aggregation_cache.memcached_client.max_item_size": RenameMapping("graphite.querier.aggregation_cache.memcached.max_item_size"), + "graphite.querier.aggregation_cache.memcached_client.timeout": RenameMapping("graphite.querier.aggregation_cache.memcached.timeout"), + + "query_range.cache_unaligned_requests": RenameMapping("frontend.cache_unaligned_requests"), + + "gateway.proxy.graphite.enable_keepalive": RenameMapping("gateway.proxy.graphite_querier.enable_keepalive"), + "gateway.proxy.graphite.read_timeout": RenameMapping("gateway.proxy.graphite_querier.read_timeout"), + "gateway.proxy.graphite.tls_ca_path": RenameMapping("gateway.proxy.graphite_querier.tls_ca_path"), + "gateway.proxy.graphite.tls_cert_path": RenameMapping("gateway.proxy.graphite_querier.tls_cert_path"), + "gateway.proxy.graphite.tls_enabled": RenameMapping("gateway.proxy.graphite_querier.tls_enabled"), + "gateway.proxy.graphite.tls_insecure_skip_verify": RenameMapping("gateway.proxy.graphite_querier.tls_insecure_skip_verify"), + "gateway.proxy.graphite.tls_key_path": RenameMapping("gateway.proxy.graphite_querier.tls_key_path"), + "gateway.proxy.graphite.tls_server_name": RenameMapping("gateway.proxy.graphite_querier.tls_server_name"), + "gateway.proxy.graphite.url": RenameMapping("gateway.proxy.graphite_querier.url"), + "gateway.proxy.graphite.write_timeout": RenameMapping("gateway.proxy.graphite_querier.write_timeout"), + } for path, mapping := range cortexRenameMappings { if _, notInGEM := nonExistentGEMPaths[path]; notInGEM { continue @@ -18,7 +49,7 @@ func GEM170ToGEM200Mapper() Mapper { return MultiMapper{ mapGEMInstanceInterfaceNames(), - // first try to naively map keys from old config to same keys from new config + // Try to naively map keys from old config to same keys from new config BestEffortDirectMapper{}, // next map alertmanager URL in the ruler config MapperFunc(alertmanagerURLMapperFunc), @@ -33,15 +64,23 @@ func GEM170ToGEM200Mapper() Mapper { // Remap sharding configs MapperFunc(updateKVStoreValue), // Convert provided memcached service and host to the DNS service discovery format - MapperFunc(mapMemcachedAddresses), + mapMemcachedAddresses("query_range.results_cache.cache.memcached_client", "frontend.results_cache.memcached"), + mapMemcachedAddresses("graphite.querier.metric_name_cache.memcached_client", "graphite.querier.metric_name_cache.memcached"), + mapMemcachedAddresses("graphite.querier.aggregation_cache.memcached_client", "graphite.querier.aggregation_cache.memcached"), + // Map `-*.s3.url` to `-*.s3.(endpoint|access_key_id|secret_access_key)` mapRulerAlertmanagerS3URL("alertmanager.storage", "alertmanager_storage"), mapRulerAlertmanagerS3URL("ruler.storage", "ruler_storage"), // Map `-*.s3.bucketnames` and (maybe part of `-*s3.s3.url`) to `-*.s3.bucket-name` mapRulerAlertmanagerS3Buckets("alertmanager.storage", "alertmanager_storage"), mapRulerAlertmanagerS3Buckets("ruler.storage", "ruler_storage"), // Prevent server.http_listen_port from being updated with a new default and always output it. - MapperFunc(mapServerHTTPListenPort), + setOldDefaultExplicitly("server.http_listen_port"), + // Prevent auth.type from being updated with a new default and always output it. + setOldDefaultExplicitly("auth.type"), // Set frontend.results_cache.backend when results cache was enabled in cortex MapperFunc(mapQueryFrontendBackend), + // Manually override the dynamic fields' default values. + MapperFunc(mapCortexRingInstanceIDDefaults), + MapperFunc(mapAdminAPIRingInstanceIDDefaults), } } @@ -58,3 +97,64 @@ func mapGEMInstanceInterfaceNames() Mapper { } return mapInstanceInterfaceNames(ifaceNames) } + +func mapAdminAPIRingInstanceIDDefaults(source, target Parameters) error { + return target.SetDefaultValue("admin_api.leader_election.ring.instance_id", Nil) +} + +var gemRemovedConfigPath = []string{ + "graphite.querier_remote_read_enabled", // -graphite.querier.remote-read-enabled + + // changed memcached config and dropped support for redis and fifocache + "graphite.querier.metric_name_cache.cache.default_validity", // -graphite.querier.metric-name-cache.default-validity + "graphite.querier.metric_name_cache.cache.enable_fifocache", // -graphite.querier.metric-name-cache.cache.enable-fifocache + "graphite.querier.metric_name_cache.cache.fifocache.max_size_bytes", // -graphite.querier.metric-name-cache.fifocache.max-size-bytes + "graphite.querier.metric_name_cache.cache.fifocache.max_size_items", // -graphite.querier.metric-name-cache.fifocache.max-size-items + "graphite.querier.metric_name_cache.cache.fifocache.size", // -graphite.querier.metric-name-cache.fifocache.size + "graphite.querier.metric_name_cache.cache.fifocache.validity", // -graphite.querier.metric-name-cache.fifocache.duration + "graphite.querier.metric_name_cache.cache.memcached.expiration", // -graphite.querier.metric-name-cache.memcached.expiration + "graphite.querier.metric_name_cache.cache.memcached_client.circuit_breaker_consecutive_failures", // -graphite.querier.metric-name-cache.memcached.circuit-breaker-consecutive-failures + "graphite.querier.metric_name_cache.cache.memcached_client.circuit_breaker_interval", // -graphite.querier.metric-name-cache.memcached.circuit-breaker-interval + "graphite.querier.metric_name_cache.cache.memcached_client.circuit_breaker_timeout", // -graphite.querier.metric-name-cache.memcached.circuit-breaker-timeout + "graphite.querier.metric_name_cache.cache.memcached_client.consistent_hash", // -graphite.querier.metric-name-cache.memcached.consistent-hash + "graphite.querier.metric_name_cache.cache.memcached_client.update_interval", // -graphite.querier.metric-name-cache.memcached.update-interval + "graphite.querier.metric_name_cache.cache.redis.db", // -graphite.querier.metric-name-cache.redis.db + "graphite.querier.metric_name_cache.cache.redis.endpoint", // -graphite.querier.metric-name-cache.redis.endpoint + "graphite.querier.metric_name_cache.cache.redis.expiration", // -graphite.querier.metric-name-cache.redis.expiration + "graphite.querier.metric_name_cache.cache.redis.idle_timeout", // -graphite.querier.metric-name-cache.redis.idle-timeout + "graphite.querier.metric_name_cache.cache.redis.master_name", // -graphite.querier.metric-name-cache.redis.master-name + "graphite.querier.metric_name_cache.cache.redis.max_connection_age", // -graphite.querier.metric-name-cache.redis.max-connection-age + "graphite.querier.metric_name_cache.cache.redis.password", // -graphite.querier.metric-name-cache.redis.password + "graphite.querier.metric_name_cache.cache.redis.pool_size", // -graphite.querier.metric-name-cache.redis.pool-size + "graphite.querier.metric_name_cache.cache.redis.timeout", // -graphite.querier.metric-name-cache.redis.timeout + "graphite.querier.metric_name_cache.cache.redis.tls_enabled", // -graphite.querier.metric-name-cache.redis.tls-enabled + "graphite.querier.metric_name_cache.cache.redis.tls_insecure_skip_verify", // -graphite.querier.metric-name-cache.redis.tls-insecure-skip-verify + + "graphite.querier.aggregation_cache.cache.default_validity", // -graphite.querier.aggregation-cache.default-validity + "graphite.querier.aggregation_cache.cache.enable_fifocache", // -graphite.querier.aggregation-cache.cache.enable-fifocache + "graphite.querier.aggregation_cache.cache.fifocache.max_size_bytes", // -graphite.querier.aggregation-cache.fifocache.max-size-bytes + "graphite.querier.aggregation_cache.cache.fifocache.max_size_items", // -graphite.querier.aggregation-cache.fifocache.max-size-items + "graphite.querier.aggregation_cache.cache.fifocache.size", // -graphite.querier.aggregation-cache.fifocache.size + "graphite.querier.aggregation_cache.cache.fifocache.validity", // -graphite.querier.aggregation-cache.fifocache.duration + "graphite.querier.aggregation_cache.cache.memcached.expiration", // -graphite.querier.aggregation-cache.memcached.expiration + "graphite.querier.aggregation_cache.cache.memcached_client.circuit_breaker_consecutive_failures", // -graphite.querier.aggregation-cache.memcached.circuit-breaker-consecutive-failures + "graphite.querier.aggregation_cache.cache.memcached_client.circuit_breaker_interval", // -graphite.querier.aggregation-cache.memcached.circuit-breaker-interval + "graphite.querier.aggregation_cache.cache.memcached_client.circuit_breaker_timeout", // -graphite.querier.aggregation-cache.memcached.circuit-breaker-timeout + "graphite.querier.aggregation_cache.cache.memcached_client.consistent_hash", // -graphite.querier.aggregation-cache.memcached.consistent-hash + "graphite.querier.aggregation_cache.cache.memcached_client.update_interval", // -graphite.querier.aggregation-cache.memcached.update-interval + "graphite.querier.aggregation_cache.cache.redis.db", // -graphite.querier.aggregation-cache.redis.db + "graphite.querier.aggregation_cache.cache.redis.endpoint", // -graphite.querier.aggregation-cache.redis.endpoint + "graphite.querier.aggregation_cache.cache.redis.expiration", // -graphite.querier.aggregation-cache.redis.expiration + "graphite.querier.aggregation_cache.cache.redis.idle_timeout", // -graphite.querier.aggregation-cache.redis.idle-timeout + "graphite.querier.aggregation_cache.cache.redis.master_name", // -graphite.querier.aggregation-cache.redis.master-name + "graphite.querier.aggregation_cache.cache.redis.max_connection_age", // -graphite.querier.aggregation-cache.redis.max-connection-age + "graphite.querier.aggregation_cache.cache.redis.password", // -graphite.querier.aggregation-cache.redis.password + "graphite.querier.aggregation_cache.cache.redis.pool_size", // -graphite.querier.aggregation-cache.redis.pool-size + "graphite.querier.aggregation_cache.cache.redis.timeout", // -graphite.querier.aggregation-cache.redis.timeout + "graphite.querier.aggregation_cache.cache.redis.tls_enabled", // -graphite.querier.aggregation-cache.redis.tls-enabled + "graphite.querier.aggregation_cache.cache.redis.tls_insecure_skip_verify", // -graphite.querier.aggregation-cache.redis.tls-insecure-skip-verify + + "compactor.compaction_strategy", // -compactor.compaction-strategy + + "querier.query_label_names_with_matchers_enabled", // -querier.query-label-names-with-matchers-enabled +} diff --git a/pkg/mimirtool/config/testdata/gem/common-flags-new.txt b/pkg/mimirtool/config/testdata/gem/common-flags-new.txt new file mode 100644 index 00000000000..cc6881677f5 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/common-flags-new.txt @@ -0,0 +1,2 @@ +-server.http-listen-port=80 +-auth.type=trust \ No newline at end of file diff --git a/pkg/mimirtool/config/testdata/gem/common-flags-old.txt b/pkg/mimirtool/config/testdata/gem/common-flags-old.txt new file mode 100644 index 00000000000..cc6881677f5 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/common-flags-old.txt @@ -0,0 +1,2 @@ +-server.http-listen-port=80 +-auth.type=trust \ No newline at end of file diff --git a/pkg/mimirtool/config/testdata/gem/common-options-new.yaml b/pkg/mimirtool/config/testdata/gem/common-options-new.yaml new file mode 100644 index 00000000000..82cd88b5703 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/common-options-new.yaml @@ -0,0 +1,5 @@ +server: + http_listen_port: 80 + +auth: + type: trust diff --git a/pkg/mimirtool/config/testdata/gem/common-options-old.yaml b/pkg/mimirtool/config/testdata/gem/common-options-old.yaml new file mode 100644 index 00000000000..82cd88b5703 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/common-options-old.yaml @@ -0,0 +1,5 @@ +server: + http_listen_port: 80 + +auth: + type: trust diff --git a/pkg/mimirtool/config/testdata/proxy-targets.yaml b/pkg/mimirtool/config/testdata/gem/proxy-targets.yaml similarity index 100% rename from pkg/mimirtool/config/testdata/proxy-targets.yaml rename to pkg/mimirtool/config/testdata/gem/proxy-targets.yaml diff --git a/pkg/mimirtool/config/testdata/gem/ring-instance-id-new.flags.txt b/pkg/mimirtool/config/testdata/gem/ring-instance-id-new.flags.txt new file mode 100644 index 00000000000..c4fdc031a12 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/ring-instance-id-new.flags.txt @@ -0,0 +1,7 @@ +-admin-api.leader-election.ring.instance-id=123abc-7 +-alertmanager.sharding-ring.instance-id=123abc-2 +-compactor.ring.instance-id=123abc-4 +-distributor.ring.instance-id=123abc-1 +-ingester.ring.instance-id=123abc-6 +-ruler.ring.instance-id=123abc-3 +-store-gateway.sharding-ring.instance-id=123abc-5 \ No newline at end of file diff --git a/pkg/mimirtool/config/testdata/gem/ring-instance-id-old.flags.txt b/pkg/mimirtool/config/testdata/gem/ring-instance-id-old.flags.txt new file mode 100644 index 00000000000..c3a12740747 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/ring-instance-id-old.flags.txt @@ -0,0 +1,7 @@ +-admin-api.leader-election.ring.instance-id=123abc-7 +-alertmanager.sharding-ring.instance-id=123abc-2 +-compactor.ring.instance-id=123abc-4 +-distributor.ring.instance-id=123abc-1 +-ingester.lifecycler.id=123abc-6 +-ruler.ring.instance-id=123abc-3 +-store-gateway.sharding-ring.instance-id=123abc-5 \ No newline at end of file diff --git a/pkg/mimirtool/config/testdata/gem/server-listen-http-port-new.yaml b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-new.yaml new file mode 100644 index 00000000000..82cd88b5703 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-new.yaml @@ -0,0 +1,5 @@ +server: + http_listen_port: 80 + +auth: + type: trust diff --git a/pkg/mimirtool/config/testdata/gem/server-listen-http-port-old.yaml b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-old.yaml new file mode 100644 index 00000000000..46ca5ee38af --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-old.yaml @@ -0,0 +1,2 @@ +server: + http_listen_port: 80 diff --git a/pkg/mimirtool/config/testdata/gem/server-listen-http-port-random-new.yaml b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-random-new.yaml new file mode 100644 index 00000000000..c74b6e44afa --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-random-new.yaml @@ -0,0 +1,5 @@ +server: + http_listen_port: 1234 + +auth: + type: trust diff --git a/pkg/mimirtool/config/testdata/gem/server-listen-http-port-random-old.yaml b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-random-old.yaml new file mode 100644 index 00000000000..61fe3f97643 --- /dev/null +++ b/pkg/mimirtool/config/testdata/gem/server-listen-http-port-random-old.yaml @@ -0,0 +1,2 @@ +server: + http_listen_port: 1234 diff --git a/pkg/mimirtool/config/testdata/ring-instance-id-new.flags.txt b/pkg/mimirtool/config/testdata/ring-instance-id-new.flags.txt new file mode 100644 index 00000000000..b39097ad1ca --- /dev/null +++ b/pkg/mimirtool/config/testdata/ring-instance-id-new.flags.txt @@ -0,0 +1,6 @@ +-alertmanager.sharding-ring.instance-id=123abc-2 +-compactor.ring.instance-id=123abc-4 +-distributor.ring.instance-id=123abc-1 +-ingester.ring.instance-id=123abc-6 +-ruler.ring.instance-id=123abc-3 +-store-gateway.sharding-ring.instance-id=123abc-5 \ No newline at end of file diff --git a/pkg/mimirtool/config/testdata/ring-instance-id-old.flags.txt b/pkg/mimirtool/config/testdata/ring-instance-id-old.flags.txt new file mode 100644 index 00000000000..6d79dabe864 --- /dev/null +++ b/pkg/mimirtool/config/testdata/ring-instance-id-old.flags.txt @@ -0,0 +1,6 @@ +-alertmanager.sharding-ring.instance-id=123abc-2 +-compactor.ring.instance-id=123abc-4 +-distributor.ring.instance-id=123abc-1 +-ingester.lifecycler.id=123abc-6 +-ruler.ring.instance-id=123abc-3 +-store-gateway.sharding-ring.instance-id=123abc-5 \ No newline at end of file