loadPerTenantOverrides is of type runtimeconfig.Loader
(validator Validator, typ ConfigType, expandEnv bool, enableLegacy bool)
| 83 | |
| 84 | // loadPerTenantOverrides is of type runtimeconfig.Loader |
| 85 | func loadPerTenantOverrides(validator Validator, typ ConfigType, expandEnv bool, enableLegacy bool) func(r io.Reader) (interface{}, error) { |
| 86 | // var is outside closure to ensure it's not recreated on each call |
| 87 | var lastLegacyWarn time.Time |
| 88 | return func(r io.Reader) (interface{}, error) { |
| 89 | overrides := &perTenantOverrides{} |
| 90 | |
| 91 | if expandEnv { |
| 92 | rr := r.(*bytes.Reader) |
| 93 | b, err := io.ReadAll(rr) |
| 94 | if err != nil { |
| 95 | return nil, err |
| 96 | } |
| 97 | |
| 98 | s, err := envsubst.EvalEnv(string(b)) |
| 99 | if err != nil { |
| 100 | return nil, fmt.Errorf("failed to expand env vars: %w", err) |
| 101 | } |
| 102 | r = bytes.NewReader([]byte(s)) |
| 103 | } |
| 104 | |
| 105 | decoder := yaml.NewDecoder(r) |
| 106 | decoder.SetStrict(true) |
| 107 | if err := decoder.Decode(&overrides); err != nil { |
| 108 | return nil, err |
| 109 | } |
| 110 | |
| 111 | if overrides.ConfigType == ConfigTypeLegacy { |
| 112 | // Log periodically (every 10 mins) and not every reload, so the warning stays visible in recent logs |
| 113 | // without spamming logs on every reload cycle. |
| 114 | if time.Since(lastLegacyWarn) >= 10*time.Minute { |
| 115 | level.Warn(log.Logger).Log( |
| 116 | "msg", "DEPRECATED: legacy overrides config format is in use. per-tenant overrides file uses the legacy format. Legacy overrides are deprecated and will be removed in a future release. "+ |
| 117 | "Please migrate your per-tenant overrides to the new scoped format.", |
| 118 | ) |
| 119 | lastLegacyWarn = time.Now() |
| 120 | } |
| 121 | |
| 122 | if !enableLegacy { |
| 123 | return nil, fmt.Errorf( |
| 124 | "DEPRECATED: legacy overrides config format is in use. per-tenant overrides file uses the legacy format but legacy overrides are disabled by default. " + |
| 125 | "Migrate your per-tenant overrides to the new scoped format, or set -config.enable-legacy-overrides=true (or enable_legacy_overrides: true in YAML) to continue using legacy overrides temporarily") |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | if overrides.ConfigType != typ { |
| 130 | // TODO: Return error? |
| 131 | level.Warn(log.Logger).Log( |
| 132 | "msg", "Overrides config type mismatch", |
| 133 | "err", "per-tenant overrides config type does not match static overrides config type", |
| 134 | "config_type", overrides.ConfigType, |
| 135 | "static_config_type", typ, |
| 136 | ) |
| 137 | } |
| 138 | |
| 139 | if validator != nil { |
| 140 | for tenant, tenantOverrides := range overrides.TenantLimits { |
| 141 | warnings, err := validator.Validate(tenantOverrides) |
| 142 | if err != nil { |