mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-07-28 17:52:13 +00:00
cli/mcp: throttle hub-token re-mint on failure; accurate proxy 401 message
Review follow-up. HubTokenRenewer.Token() re-minted on every request while the token was empty, so a cluster where minting can't succeed (no RBAC, SA missing) paid a blocking ~10s CreateToken round-trip per request (under the lock). Add a 30s retry throttle: on mint failure, back off and fall back to the prior token / License-Key. Also correct the proxy-mode 401 message — a token-bearing 401 means the minted token was rejected (allowlist/audience), not an RBAC-to-mint failure.
This commit is contained in:
@@ -321,7 +321,7 @@ func (s *mcpServer) hubAuthErrorMessage() string {
|
||||
"URL mode cannot auto-renew it — mint a fresh token (e.g. `kubectl create token kubeshark-cli --audience kubeshark-hub`) " +
|
||||
"and restart with --token (or KUBESHARK_HUB_TOKEN)."
|
||||
}
|
||||
return "Hub rejected the request (401 Unauthorized): authentication failed. Ensure you have RBAC to mint the kubeshark-cli token (or set a valid license)."
|
||||
return "Hub rejected the request (401 Unauthorized): the minted kubeshark-cli token was not accepted (check the Hub's AUTH_CLI_SERVICE_ACCOUNTS allowlist and the token audience), or no credential was available — if you lack RBAC to mint the token the CLI falls back to the License-Key, so set a valid license."
|
||||
}
|
||||
|
||||
func (s *mcpServer) fetchHubMCP() *hubMCPResponse {
|
||||
|
||||
@@ -22,6 +22,10 @@ const (
|
||||
// hubTokenRenewMargin re-mints this long before expiry so requests in
|
||||
// flight always carry a comfortably valid token.
|
||||
hubTokenRenewMargin = 5 * time.Minute
|
||||
// hubTokenMintRetryInterval throttles re-minting after a failure so a
|
||||
// cluster where minting can't succeed (no RBAC, SA missing) doesn't pay a
|
||||
// blocking CreateToken round-trip on every request.
|
||||
hubTokenMintRetryInterval = 30 * time.Second
|
||||
)
|
||||
|
||||
// MintHubToken requests a short-lived ServiceAccount token (audience
|
||||
@@ -67,9 +71,10 @@ type HubTokenRenewer struct {
|
||||
provider *Provider
|
||||
namespace string
|
||||
|
||||
mu sync.Mutex
|
||||
token string
|
||||
expireAt time.Time
|
||||
mu sync.Mutex
|
||||
token string
|
||||
expireAt time.Time
|
||||
nextAttempt time.Time // earliest time to retry minting after a failure
|
||||
}
|
||||
|
||||
// NewHubTokenRenewer builds a renewer that mints kubeshark-cli tokens in the
|
||||
@@ -84,14 +89,19 @@ func NewHubTokenRenewer(provider *Provider, namespace string) *HubTokenRenewer {
|
||||
func (r *HubTokenRenewer) Token() string {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if r.token == "" || time.Now().After(r.expireAt.Add(-hubTokenRenewMargin)) {
|
||||
needsMint := r.token == "" || time.Now().After(r.expireAt.Add(-hubTokenRenewMargin))
|
||||
if needsMint && time.Now().After(r.nextAttempt) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
tok, expireAt, err := r.provider.mintHubToken(ctx, r.namespace)
|
||||
cancel()
|
||||
if err != nil {
|
||||
// Throttle retries and fall back to the prior token (possibly "",
|
||||
// i.e. the License-Key) so a failing cluster doesn't block every
|
||||
// request on a doomed mint.
|
||||
r.nextAttempt = time.Now().Add(hubTokenMintRetryInterval)
|
||||
return r.token
|
||||
}
|
||||
r.token, r.expireAt = tok, expireAt
|
||||
r.token, r.expireAt, r.nextAttempt = tok, expireAt, time.Time{}
|
||||
}
|
||||
return r.token
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user