diff --git a/cmd/fishymetrics/main.go b/cmd/fishymetrics/main.go index 743857fe..ac9e1189 100644 --- a/cmd/fishymetrics/main.go +++ b/cmd/fishymetrics/main.go @@ -73,6 +73,7 @@ var ( driveModExclude = a.Flag("collector.drives.modules-exclude", "regex of drive module(s) to exclude from the scrape").Default("").Envar("COLLECTOR_DRIVES_MODULE_EXCLUDE").String() firmwareModExclude = a.Flag("collector.firmware.modules-exclude", "regex of firmware module(s) to exclude from the scrape").Default("").Envar("COLLECTOR_FIRMWARE_MODULE_EXCLUDE").String() urlExtraParams = a.Flag("url.extra-params", `extra parameter(s) to parse from the URL. --url.extra-params="param1:alias1,param2:alias2"`).Default("").Envar("URL_EXTRA_PARAMS").String() + disable404Retry = a.Flag("disable-404-retry", "Skip retrying on HTTP 404 (no 404 retry loop).").Default("false").Envar("FISHYMETRICS_DISABLE_404_RETRY").Bool() _ = common.CredentialProf(a.Flag("credentials.profiles", `profile(s) with all necessary parameters to obtain BMC credential from secrets backend, i.e. --credentials.profiles=" @@ -155,11 +156,12 @@ func main() { } c := &config.Config{ - BMCScheme: *bmcScheme, - BMCTimeout: *bmcTimeout, - SSLVerify: *insecureSkipVerify, - User: *username, - Pass: *password, + BMCScheme: *bmcScheme, + BMCTimeout: *bmcTimeout, + SSLVerify: *insecureSkipVerify, + User: *username, + Pass: *password, + Disable404Retry: *disable404Retry, } config.NewConfig(c) diff --git a/common/util.go b/common/util.go index ef1f2245..1a835d50 100644 --- a/common/util.go +++ b/common/util.go @@ -52,8 +52,13 @@ func Fetch(uri, host, profile string, client *retryablehttp.Client) func() ([]by return nil, err } defer EmptyAndCloseBody(resp) - if !(resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices) { - if resp.StatusCode == http.StatusNotFound { + if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices { + switch resp.StatusCode { + case http.StatusNotFound: + // When --disable-404-retry or FISHYMETRICS_DISABLE_404_RETRY=1, skip retries. + if config.GetConfig().Disable404Retry { + return nil, fmt.Errorf("HTTP status %d", http.StatusNotFound) + } for retryCount < 3 && resp.StatusCode == http.StatusNotFound { time.Sleep(client.RetryWaitMin) resp, err = DoRequest(client, req) @@ -63,12 +68,10 @@ func Fetch(uri, host, profile string, client *retryablehttp.Client) func() ([]by defer EmptyAndCloseBody(resp) retryCount++ } - if err != nil { - return nil, err - } else if !(resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices) { + if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices { return nil, fmt.Errorf("HTTP status %d", resp.StatusCode) } - } else if resp.StatusCode == http.StatusUnauthorized { + case http.StatusUnauthorized: if ChassisCreds.Vault != nil { // Credentials may have rotated, clear cache, go to vault and get the latest ChassisCreds.mu.Lock() @@ -103,7 +106,7 @@ func Fetch(uri, host, profile string, client *retryablehttp.Client) func() ([]by if resp.StatusCode == http.StatusUnauthorized { return nil, ErrInvalidCredential } - } else { + default: return nil, fmt.Errorf("HTTP status %d", resp.StatusCode) } } diff --git a/config/config.go b/config/config.go index fa32f056..0c686471 100644 --- a/config/config.go +++ b/config/config.go @@ -22,11 +22,12 @@ import ( ) type Config struct { - BMCScheme string - BMCTimeout time.Duration - SSLVerify bool - User string - Pass string + BMCScheme string + BMCTimeout time.Duration + SSLVerify bool + User string + Pass string + Disable404Retry bool } var (