validateHardLimits checks if the provided overrides exceed any hard limits from the runtime config
(overrides map[string]any, userID string)
| 39 | |
| 40 | // validateHardLimits checks if the provided overrides exceed any hard limits from the runtime config |
| 41 | func (a *API) validateHardLimits(overrides map[string]any, userID string) error { |
| 42 | // Read the runtime config to get hard limits |
| 43 | reader, err := a.bucketClient.Get(context.Background(), a.runtimeConfigPath) |
| 44 | defer func() { |
| 45 | if reader != nil { |
| 46 | reader.Close() |
| 47 | } |
| 48 | }() |
| 49 | if err != nil { |
| 50 | level.Error(a.logger).Log("msg", "failed to read hard limits configuration", "userID", userID, "err", err) |
| 51 | return fmt.Errorf("failed to validate hard limits") |
| 52 | } |
| 53 | |
| 54 | var config runtimeconfig.RuntimeConfigValues |
| 55 | if err := yaml.NewDecoder(reader).Decode(&config); err != nil { |
| 56 | level.Error(a.logger).Log("msg", "failed to decode hard limits configuration", "userID", userID, "err", err) |
| 57 | return fmt.Errorf("failed to validate hard limits") |
| 58 | } |
| 59 | |
| 60 | // If no hard overrides are defined, allow the request |
| 61 | if config.HardTenantLimits == nil { |
| 62 | return nil |
| 63 | } |
| 64 | |
| 65 | // Get hard limits for this specific user |
| 66 | userHardLimits, exists := config.HardTenantLimits[userID] |
| 67 | if !exists { |
| 68 | return nil // No hard limits defined for this user |
| 69 | } |
| 70 | |
| 71 | yamlData, err := yaml.Marshal(userHardLimits) |
| 72 | if err != nil { |
| 73 | level.Error(a.logger).Log("msg", "failed to marshal hard limits", "userID", userID, "err", err) |
| 74 | return fmt.Errorf("failed to validate hard limits") |
| 75 | } |
| 76 | |
| 77 | var hardLimitsMap map[string]any |
| 78 | if err := yaml.Unmarshal(yamlData, &hardLimitsMap); err != nil { |
| 79 | level.Error(a.logger).Log("msg", "failed to unmarshal hard limits", "userID", userID, "err", err) |
| 80 | return fmt.Errorf("failed to validate hard limits") |
| 81 | } |
| 82 | |
| 83 | // Validate each override against the user's hard limits |
| 84 | for limitName, value := range overrides { |
| 85 | if hardLimit, exists := hardLimitsMap[limitName]; exists { |
| 86 | if err := a.validateSingleHardLimit(limitName, value, hardLimit); err != nil { |
| 87 | return err |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | return nil |
| 93 | } |
| 94 | |
| 95 | // validateSingleHardLimit validates a single limit against its hard limit |
| 96 | func (a *API) validateSingleHardLimit(limitName string, value, hardLimit any) error { |
no test coverage detected