Remove usage of create_auth and reset_password API#1697
Remove usage of create_auth and reset_password API#1697tangledbytes merged 1 commit intonoobaa:masterfrom
Conversation
WalkthroughRemoved NB client CreateAuth and ResetPassword APIs/types and their CLI test/commands; replaced remote NB auth calls with local JWT signing via new util.MakeAuthToken using the server secret. Also made jwt a direct go.mod dependency, bumped default image tag, and increased select polling timeouts/intervals. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Reconciler as Reconciler
participant SecretServer as Server Secret (jwt)
participant Util as util.MakeAuthToken
participant K8sSecret as Kubernetes Secret
Note over Reconciler,SecretServer: Local JWT signing replaces NBClient CreateAuthAPI
Reconciler->>SecretServer: read signing key (secretServer.StringData["jwt"])
SecretServer-->>Reconciler: jwt signing key
Reconciler->>Util: MakeAuthToken({system, role, email}, jwt)
Util-->>Reconciler: signed JWT token
Reconciler->>K8sSecret: write token to secret (auth_token / metrics key)
Note over Reconciler,K8sSecret: NBClient.CreateAuthAPI call removed from this flow
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Pre-merge checks (1 passed, 2 warnings)❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. 📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (10)
💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (7)
🧰 Additional context used🧬 Code graph analysis (2)pkg/noobaaaccount/reconciler.go (3)
pkg/system/phase4_configuring.go (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
2302de6 to
599a86b
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (2)
pkg/system/phase4_configuring.go (2)
218-227: READY path: same signing-key guard as above; prefer r.NooBaa.Name; add TTL
- Hydrate/validate server JWT before signing (same as metrics).
- Minor: use r.NooBaa.Name consistently for the "system" claim (less surprise than r.Request.Name).
- Add exp/iat to avoid never-expiring operator tokens.
@@ - token, err := util.MakeAuthToken(map[string]any{ - "system": r.Request.Name, - "role": "operator", - "email": options.OperatorAccountEmail, - }, []byte(r.SecretServer.StringData["jwt"])) + util.SecretResetStringDataFromData(r.SecretServer) + serverJWT := r.SecretServer.StringData["jwt"] + if serverJWT == "" { + return fmt.Errorf("server JWT secret is missing/empty") + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.NooBaa.Name, + "role": "operator", + "email": options.OperatorAccountEmail, + /* requires util.MakeAuthToken to allow std claims: + "iat": time.Now().Unix(), + "exp": time.Now().Add(24*time.Hour).Unix(), + */ + }, []byte(serverJWT))Confirm core PR 9211 accepts the "role", "system", and "email" claims exactly as used here for operator auth.
266-276: Endpoints admin token: add signing-key guard + TTL
- Same signing-key hydration/empty check.
- Add exp/iat for admin token as well.
@@ - token, err := util.MakeAuthToken(map[string]any{ - "system": r.Request.Name, - "role": "admin", - "email": options.AdminAccountEmail, - }, []byte(r.SecretServer.StringData["jwt"])) + util.SecretResetStringDataFromData(r.SecretServer) + serverJWT := r.SecretServer.StringData["jwt"] + if serverJWT == "" { + return fmt.Errorf("server JWT secret is missing/empty") + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.NooBaa.Name, + "role": "admin", + "email": options.AdminAccountEmail, + /* requires util.MakeAuthToken to allow std claims: + "iat": time.Now().Unix(), + "exp": time.Now().Add(24*time.Hour).Unix(), + */ + }, []byte(serverJWT))
🧹 Nitpick comments (2)
pkg/noobaaaccount/reconciler.go (2)
48-50:SecretServerfield is unusedEither wire this into the reconcile flow or remove to avoid confusion.
372-377: JWT best-practices: set issuer and TTL via MakeAuthToken (follow-up to util change)Once MakeAuthToken adds standard claims, pass issuer/TTL as needed (or rely on defaults). No change required here if defaults are acceptable.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
go.mod(1 hunks)pkg/nb/api.go(0 hunks)pkg/nb/types.go(2 hunks)pkg/noobaaaccount/noobaaaccount.go(0 hunks)pkg/noobaaaccount/reconciler.go(2 hunks)pkg/options/options.go(1 hunks)pkg/system/phase4_configuring.go(3 hunks)pkg/util/util.go(2 hunks)test/cli/test_cli_functions.sh(0 hunks)
💤 Files with no reviewable changes (3)
- test/cli/test_cli_functions.sh
- pkg/nb/api.go
- pkg/noobaaaccount/noobaaaccount.go
🧰 Additional context used
🧬 Code graph analysis (2)
pkg/noobaaaccount/reconciler.go (3)
pkg/util/util.go (3)
KubeObject(283-293)KubeCheck(569-590)MakeAuthToken(2394-2406)pkg/bundle/deploy.go (1)
File_deploy_internal_secret_empty_yaml(4902-4909)pkg/options/options.go (3)
Namespace(57-57)SystemName(50-50)OperatorAccountEmail(47-47)
pkg/system/phase4_configuring.go (2)
pkg/util/util.go (1)
MakeAuthToken(2394-2406)pkg/options/options.go (2)
OperatorAccountEmail(47-47)AdminAccountEmail(44-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: run-core-config-map-tests
- GitHub Check: run-admission-test
- GitHub Check: run-kms-tls-token-test
- GitHub Check: run-kms-tls-sa-test
- GitHub Check: cnpg-deployment-test
- GitHub Check: run-hac-test
- GitHub Check: run-kms-kmip-test
- GitHub Check: golangci-lint
- GitHub Check: run-kms-key-rotate-test
- GitHub Check: run-cli-tests
- GitHub Check: run-operator-tests
- GitHub Check: run-kms-dev-test
- GitHub Check: run-azure-vault-test
🔇 Additional comments (3)
pkg/options/options.go (1)
33-33: Verify image compatibility and update docs
Thenoobaa-core:master-20250908tag is present (HTTP 200), but the image’s version label couldn’t be parsed automatically. Manually confirm the image’s version falls within the supported semver range (>= 5.0.0 and < 6.0.0), and if this tag is meant to track a dated master build, update any release documentation to reflect that.pkg/util/util.go (1)
31-31: LGTM: direct jwt/v4 import is correctMatches the new direct dependency in go.mod.
go.mod (1)
141-141: Code only imports jwt/v4; go.mod is tidy
Verified no jwt/v5 import paths in code (only at pkg/util/util.go:31).
599a86b to
b8bcc85
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/system/phase4_configuring.go (1)
259-276: Replace the early‐return in SetDesiredSecretEndpoints to guard on the token field and load the server JWTIn pkg/system/phase4_configuring.go within SetDesiredSecretEndpoints(), the check
if r.SecretEndpoints.UID != "" { return nil }skips minting auth_token for existing Secrets that lack it. Change to:
- Load string data for SecretEndpoints before checking
- Return early only if StringData["auth_token"] is non‐empty
- Load string data for SecretServer and error if its “jwt” key is missing/empty
This ensures clusters upgraded from before this PR correctly receive a new auth token.
♻️ Duplicate comments (4)
pkg/nb/types.go (1)
568-577: API break:UpdateAccountParams.Nametag must remainname(notusername)
This will break consumers of account_api.update_account() expectingname.-type UpdateAccountParams struct { - Name *string `json:"username,omitempty"` +type UpdateAccountParams struct { + Name *string `json:"name,omitempty"` Email string `json:"email"` NewEmail *string `json:"new_email,omitempty"` AllowedIPs *[]struct { Start string `json:"start"` End string `json:"end"` } `json:"ips,omitempty"` RoleConfig interface{} `json:"role_config,omitempty"` RemoveRoleConfig bool `json:"remove_role_config,omitempty"` }Also update the struct comment above to reference account_api.update_account() instead of update_account_s3_access().
pkg/noobaaaccount/reconciler.go (2)
365-371: Guard missing/empty JWT key and prefer Secret.Data over StringData
Currently, if the secret lacks "jwt", token gets signed with an empty key. Use Data and validate presence.- if !util.KubeCheck(secretServer) { - return fmt.Errorf("cannot create an auth token for remote operator - server secret not found") - } + if !util.KubeCheck(secretServer) { + return fmt.Errorf("cannot create an auth token for remote operator - server secret not found") + } + jwtBytes := secretServer.Data["jwt"] + if len(jwtBytes) == 0 { + return fmt.Errorf("cannot create an auth token for remote operator - missing \"jwt\" key in server secret %q", secretServer.Name) + }
380-384: Prevent panics: checkAccessKeyslength and initStringDatabefore writes
Indexing[0]can panic;StringDatamay be nil.- accessKeys := accountInfo.AccessKeys[0] - r.Secret.StringData["auth_token"] = token - r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) - r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey) + var accessKeys nb.S3AccessKeys + if len(accountInfo.AccessKeys) == 0 { + log.Info("CreateAccountAPI did not return access keys. calling ReadAccountAPI to get keys..") + readAccountReply, err := r.NBClient.ReadAccountAPI(nb.ReadAccountParams{Email: r.NooBaaAccount.Name}) + if err != nil { + return err + } + accessKeys = readAccountReply.AccessKeys[0] + } else { + accessKeys = accountInfo.AccessKeys[0] + } + if r.Secret.StringData == nil { + r.Secret.StringData = map[string]string{} + } + r.Secret.StringData["auth_token"] = token + r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) + r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey)pkg/system/phase4_configuring.go (1)
156-166: Hydrate server JWT secret and add exp/iat (TTL) to metrics token.Load r.SecretServer.StringData from Data, ensure the signing key is non-empty, and set standard JWT timing claims to avoid never-expiring tokens.
Apply:
- token, err := util.MakeAuthToken(map[string]any{ - "system": r.NooBaa.Name, - "role": "metrics", - "email": options.OperatorAccountEmail, - }, []byte(r.SecretServer.StringData["jwt"])) + // Ensure signing key is loaded and non-empty + util.SecretResetStringDataFromData(r.SecretServer) + serverJWT := r.SecretServer.StringData["jwt"] + if serverJWT == "" { + return fmt.Errorf("server JWT secret is missing/empty") + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.NooBaa.Name, + "role": "metrics", + "email": options.OperatorAccountEmail, + // token hardening + "iat": time.Now().Unix(), + "exp": time.Now().Add(1 * time.Hour).Unix(), + }, []byte(serverJWT))Supporting change outside this file (to let util keep these std claims):
--- a/pkg/util/util.go +++ b/pkg/util/util.go @@ - allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system"} + // include standard timing claims + allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system", "iat", "exp", "nbf"}Note: plan rotation for metrics_token on JWT key change/expiry (re-mint token and update SecretMetricsAuth to trigger reloads).
🧹 Nitpick comments (3)
pkg/backingstore/backingstore.go (1)
947-949: Nit: simplify interval expressionUse a duration literal to avoid multiplying by time.Second at the call site.
- interval := time.Duration(30) - err := wait.PollUntilContextCancel(ctx, interval*time.Second, true, func(ctx context.Context) (bool, error) { + interval := 30 * time.Second + err := wait.PollUntilContextCancel(ctx, interval, true, func(ctx context.Context) (bool, error) {pkg/noobaaaccount/reconciler.go (1)
48-50:SecretServerfield is unusedEither wire it into the token generation path or drop it to avoid confusion.
pkg/system/phase4_configuring.go (1)
415-426: Minor typos in comments/logs.Low-impact polish for operator logs and comments.
@@ - // Ignore mailformed addresses + // Ignore malformed addresses @@ - // Ignore mailformed addresses + // Ignore malformed addresses@@ - if _, err := url.Parse(endpoint); err != nil { - r.Logger.Errorf("Invalid formate URL %q", endpoint) - return fmt.Errorf("Invalid formate URL %q", endpoint) + if _, err := url.Parse(endpoint); err != nil { + r.Logger.Errorf("Invalid URL format %q", endpoint) + return fmt.Errorf("invalid URL format %q", endpoint)@@ - // make sure the name is ended with a valid charecter + // make sure the name ends with a valid characterAlso applies to: 1329-1332, 1499-1501
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
go.mod(1 hunks)pkg/backingstore/backingstore.go(1 hunks)pkg/nb/api.go(0 hunks)pkg/nb/types.go(2 hunks)pkg/noobaaaccount/noobaaaccount.go(0 hunks)pkg/noobaaaccount/reconciler.go(2 hunks)pkg/options/options.go(1 hunks)pkg/system/phase4_configuring.go(3 hunks)pkg/util/util.go(2 hunks)test/cli/test_cli_functions.sh(0 hunks)
💤 Files with no reviewable changes (3)
- pkg/nb/api.go
- pkg/noobaaaccount/noobaaaccount.go
- test/cli/test_cli_functions.sh
🚧 Files skipped from review as they are similar to previous changes (1)
- pkg/util/util.go
🧰 Additional context used
🧬 Code graph analysis (2)
pkg/system/phase4_configuring.go (2)
pkg/util/util.go (1)
MakeAuthToken(2394-2410)pkg/options/options.go (2)
OperatorAccountEmail(47-47)AdminAccountEmail(44-44)
pkg/noobaaaccount/reconciler.go (3)
pkg/util/util.go (3)
KubeObject(283-293)KubeCheck(569-590)MakeAuthToken(2394-2410)pkg/bundle/deploy.go (1)
File_deploy_internal_secret_empty_yaml(4902-4909)pkg/options/options.go (3)
Namespace(57-57)SystemName(50-50)OperatorAccountEmail(47-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: run-azure-vault-test
- GitHub Check: run-kms-dev-test
- GitHub Check: run-kms-kmip-test
- GitHub Check: run-kms-key-rotate-test
- GitHub Check: golangci-lint
- GitHub Check: cnpg-deployment-test
- GitHub Check: run-kms-tls-token-test
- GitHub Check: run-hac-test
- GitHub Check: run-admission-test
- GitHub Check: run-cli-tests
- GitHub Check: run-operator-tests
- GitHub Check: run-kms-tls-sa-test
- GitHub Check: run-core-config-map-tests
🔇 Additional comments (4)
go.mod (1)
141-141: Only jwt/v4 is imported; no v5 usage foundpkg/options/options.go (1)
33-33: LGTM: default image tag bumpLooks good; keep release notes/docs in sync with the new default tag.
pkg/nb/types.go (1)
289-290: Formatting-only changeNo behavioral impact. OK.
pkg/system/phase4_configuring.go (1)
218-227: Hydrate and validate server JWT before token creation (pkg/system/phase4_configuring.go:218-227)Call
util.SecretResetStringDataFromDatato populateStringData["jwt"], return an error if it’s empty, then invokeutil.MakeAuthToken; e.g.:- token, err := util.MakeAuthToken(map[string]any{ - "system": r.Request.Name, - "role": "operator", - "email": options.OperatorAccountEmail, - }, []byte(r.SecretServer.StringData["jwt"])) + // Ensure signing key is loaded and non-empty + util.SecretResetStringDataFromData(r.SecretServer) + serverJWT := r.SecretServer.StringData["jwt"] + if serverJWT == "" { + return fmt.Errorf("server JWT secret is missing/empty") + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.Request.Name, + "role": "operator", + "email": options.OperatorAccountEmail, + }, []byte(serverJWT))Consider adding TTL with automatic refresh to prevent operator token expiry at runtime.
b8bcc85 to
605c725
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
pkg/noobaaaccount/reconciler.go (2)
364-369: Guard: verify server secret contains “jwt” and use Secret.Data bytes.Avoid signing with a missing/empty key and prefer Data over StringData.
Apply:
secretServer := util.KubeObject(bundle.File_deploy_internal_secret_empty_yaml).(*corev1.Secret) secretServer.Namespace = r.Request.Namespace secretServer.Name = options.SystemName if !util.KubeCheck(secretServer) { return fmt.Errorf("cannot create an auth token for remote operator - server secret not found") } - + jwtBytes, ok := secretServer.Data["jwt"] + if !ok || len(jwtBytes) == 0 { + return fmt.Errorf("cannot create an auth token for remote operator - missing %q key in server secret %q", "jwt", secretServer.Name) + }
379-383: Fix potential panic and ensure StringData is initialized.AccessKeys[0] can be empty on older cores; also StringData may be nil.
Apply:
- accessKeys := accountInfo.AccessKeys[0] - r.Secret.StringData["auth_token"] = token - r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) - r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey) + var accessKeys nb.S3AccessKeys + if len(accountInfo.AccessKeys) == 0 { + log.Info("CreateAccountAPI did not return access keys. calling ReadAccountAPI to get keys..") + readAccountReply, err := r.NBClient.ReadAccountAPI(nb.ReadAccountParams{Email: r.NooBaaAccount.Name}) + if err != nil { + return err + } + if len(readAccountReply.AccessKeys) == 0 { + return fmt.Errorf("no access keys found for account %q", r.NooBaaAccount.Name) + } + accessKeys = readAccountReply.AccessKeys[0] + } else { + accessKeys = accountInfo.AccessKeys[0] + } + if r.Secret.StringData == nil { + r.Secret.StringData = map[string]string{} + } + r.Secret.StringData["auth_token"] = token + r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) + r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey)
🧹 Nitpick comments (1)
test/cli/test_cli_flow.sh (1)
34-34: Don’t silently drop a destructive test; gate it behind a flag.Keep coverage while avoiding accidental data wipes in CI.
Apply:
- # check_default_backingstore #It deletes all the buckets and non-default accounts, creates new backingstore and attach it to default admin account and then deletes default backingstore + # It deletes all the buckets and non-default accounts, creates new backingstore and attach it to default admin account and then deletes default backingstore + if [[ "${RUN_DESTRUCTIVE_TESTS:-false}" == "true" ]]; then + check_default_backingstore + fi
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
go.mod(1 hunks)pkg/backingstore/backingstore.go(1 hunks)pkg/nb/api.go(0 hunks)pkg/nb/types.go(2 hunks)pkg/noobaaaccount/noobaaaccount.go(0 hunks)pkg/noobaaaccount/reconciler.go(1 hunks)pkg/options/options.go(1 hunks)pkg/system/phase4_configuring.go(3 hunks)pkg/util/util.go(2 hunks)test/cli/test_cli_flow.sh(1 hunks)test/cli/test_cli_functions.sh(0 hunks)
💤 Files with no reviewable changes (3)
- test/cli/test_cli_functions.sh
- pkg/noobaaaccount/noobaaaccount.go
- pkg/nb/api.go
🚧 Files skipped from review as they are similar to previous changes (6)
- pkg/backingstore/backingstore.go
- pkg/util/util.go
- go.mod
- pkg/options/options.go
- pkg/system/phase4_configuring.go
- pkg/nb/types.go
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/noobaaaccount/reconciler.go (3)
pkg/util/util.go (3)
KubeObject(283-293)KubeCheck(569-590)MakeAuthToken(2394-2410)pkg/bundle/deploy.go (1)
File_deploy_internal_secret_empty_yaml(4902-4909)pkg/options/options.go (2)
SystemName(50-50)OperatorAccountEmail(47-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: run-azure-vault-test
- GitHub Check: run-hac-test
- GitHub Check: cnpg-deployment-test
- GitHub Check: run-kms-tls-token-test
- GitHub Check: run-operator-tests
- GitHub Check: run-kms-tls-sa-test
- GitHub Check: run-kms-kmip-test
- GitHub Check: run-cli-tests
- GitHub Check: run-admission-test
- GitHub Check: run-kms-key-rotate-test
- GitHub Check: run-kms-dev-test
- GitHub Check: golangci-lint
- GitHub Check: run-core-config-map-tests
| token, err := util.MakeAuthToken(map[string]any{ | ||
| "system": r.NooBaa.Name, | ||
| "role": "operator", | ||
| "email": options.OperatorAccountEmail, | ||
| }, []byte(secretServer.StringData["jwt"])) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use validated jwtBytes and add a short-lived token expiry.
Sign with the validated bytes and include exp to avoid indefinite tokens.
Apply:
- token, err := util.MakeAuthToken(map[string]any{
- "system": r.NooBaa.Name,
- "role": "operator",
- "email": options.OperatorAccountEmail,
- }, []byte(secretServer.StringData["jwt"]))
+ token, err := util.MakeAuthToken(map[string]any{
+ "system": r.NooBaa.Name,
+ "role": "operator",
+ "email": options.OperatorAccountEmail,
+ "exp": time.Now().Add(24 * time.Hour).Unix(),
+ }, jwtBytes)Additionally, allow exp in util.MakeAuthToken:
- allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system"}
+ allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system", "exp", "iat"}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| token, err := util.MakeAuthToken(map[string]any{ | |
| "system": r.NooBaa.Name, | |
| "role": "operator", | |
| "email": options.OperatorAccountEmail, | |
| }, []byte(secretServer.StringData["jwt"])) | |
| // In pkg/noobaaaccount/reconciler.go (around lines 371–375) | |
| token, err := util.MakeAuthToken(map[string]any{ | |
| "system": r.NooBaa.Name, | |
| "role": "operator", | |
| "email": options.OperatorAccountEmail, | |
| "exp": time.Now().Add(24 * time.Hour).Unix(), | |
| }, jwtBytes) |
| token, err := util.MakeAuthToken(map[string]any{ | |
| "system": r.NooBaa.Name, | |
| "role": "operator", | |
| "email": options.OperatorAccountEmail, | |
| }, []byte(secretServer.StringData["jwt"])) | |
| // In util.MakeAuthToken (allowedFields definition) | |
| allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system", "exp", "iat"} |
🤖 Prompt for AI Agents
In pkg/noobaaaccount/reconciler.go around lines 371 to 375, the MakeAuthToken
call is signing with the raw secretServer.StringData["jwt"] and produces a token
without expiry; replace the raw access with the validated jwtBytes variable (the
parsed/validated []byte) when calling util.MakeAuthToken and add an "exp" claim
set to a short TTL (e.g. now + few minutes) to the claims map so tokens are
short-lived; also update util.MakeAuthToken to accept and embed the exp claim
(or accept a claims map) and sign using the provided jwtBytes rather than the
secret string.
605c725 to
a88fa70
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
test/cli/test_cli_functions.sh (2)
262-271: Bug: waiting on the wrong resource (polls NooBaa CR instead of BackingStore)Inside wait_for_backingstore_ready the loop polls the NooBaa CR phase, not the BackingStore’s phase, and the initial status is redundantly assigned. This can mask failures or loop indefinitely.
Apply:
function wait_for_backingstore_ready { - local status=$(kuberun silence get backingstore noobaa-default-backing-store -o 'jsonpath={.status.phase}') - local status=$(kuberun silence get backingstore ${1} -o 'jsonpath={.status.phase}') + local status + status=$(kuberun silence get backingstore ${1} -o 'jsonpath={.status.phase}') while [ "${status}" != "Ready" ] do echo_time "💬 Waiting for status Ready, Status is ${status}" sleep 10 - status=$(kuberun silence get noobaa noobaa -o 'jsonpath={.status.phase}') + status=$(kuberun silence get backingstore ${1} -o 'jsonpath={.status.phase}') done }
1189-1191: Shell error: stray string executes as a commandThis line runs a quoted string as a command and will fail with “command not found”.
Apply:
- "💬 Deleting non-default accounts" + echo_time "💬 Deleting non-default accounts"
♻️ Duplicate comments (7)
pkg/util/util.go (1)
2393-2410: JWTs lack exp/iat and accept weak/empty keysTokens never expire and HS256 signs even with very short secrets. Enforce a minimum key length and add standard time claims by default. Also allow callers to override/augment with exp/iat if needed.
Apply:
-func MakeAuthToken(payload map[string]any, secret []byte) (string, error) { - if len(secret) == 0 { - return "", fmt.Errorf("jwt signing secret missing") - } - - filtered := jwt.MapClaims{} - - allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system"} - for _, field := range allowedFields { - val, ok := payload[field] - if ok { - filtered[field] = val - } - } - - return jwt.NewWithClaims(jwt.SigningMethodHS256, filtered).SignedString(secret) -} +func MakeAuthToken(payload map[string]any, secret []byte) (string, error) { + if len(secret) < 32 { + return "", fmt.Errorf("jwt signing secret missing or too short") + } + filtered := jwt.MapClaims{} + // allow selected custom and standard claims + allowedFields := []string{ + "account_id", "system_id", "role", "extra", "authorized_by", "email", "system", + "iss", "sub", "iat", "exp", "nbf", + } + for _, field := range allowedFields { + if val, ok := payload[field]; ok { + filtered[field] = val + } + } + // set defaults if not provided + now := time.Now().UTC() + if _, ok := filtered["iat"]; !ok { + filtered["iat"] = now.Unix() + } + if _, ok := filtered["exp"]; !ok { + filtered["exp"] = now.Add(15 * time.Minute).Unix() + } + if _, ok := filtered["iss"]; !ok { + filtered["iss"] = "noobaa-operator" + } + if _, ok := filtered["sub"]; !ok { + if v, ok := filtered["account_id"]; ok { + filtered["sub"] = v + } else if v, ok := filtered["email"]; ok { + filtered["sub"] = v + } + } + token := jwt.NewWithClaims(jwt.SigningMethodHS256, filtered) + return token.SignedString(secret) +}pkg/noobaaaccount/reconciler.go (2)
364-375: Guard jwt key and add token TTL; sign with validated bytesEnsure the server secret contains a non-empty "jwt" key before signing. Also make tokens short-lived.
Apply:
- if !util.KubeCheck(secretServer) { + if !util.KubeCheck(secretServer) { return fmt.Errorf("cannot create an auth token for remote operator - server secret not found") } - - token, err := util.MakeAuthToken(map[string]any{ - "system": r.NooBaa.Name, - "role": "operator", - "email": options.OperatorAccountEmail, - }, []byte(secretServer.StringData["jwt"])) + // hydrate and validate JWT key + util.SecretResetStringDataFromData(secretServer) + jwtKey := strings.TrimSpace(secretServer.StringData["jwt"]) + if jwtKey == "" { + return fmt.Errorf("cannot create an auth token for remote operator - missing \"jwt\" key in server secret %q", secretServer.Name) + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.NooBaa.Name, + "role": "operator", + "email": options.OperatorAccountEmail, + "iat": time.Now().UTC().Unix(), + "exp": time.Now().UTC().Add(24 * time.Hour).Unix(), + }, []byte(jwtKey))
379-383: Possible panic: AccessKeys[0] without length checkWhen AccessKeys is empty, indexing [0] panics. Mirror the fallback used in the non-remote path.
Apply:
- accessKeys := accountInfo.AccessKeys[0] - r.Secret.StringData["auth_token"] = token - r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) - r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey) + var accessKeys nb.S3AccessKeys + if len(accountInfo.AccessKeys) == 0 { + log.Info("CreateAccountAPI did not return access keys. calling ReadAccountAPI to get keys..") + readAccountReply, err := r.NBClient.ReadAccountAPI(nb.ReadAccountParams{Email: r.NooBaaAccount.Name}) + if err != nil || len(readAccountReply.AccessKeys) == 0 { + return fmt.Errorf("failed to obtain access keys for account %q", r.NooBaaAccount.Name) + } + accessKeys = readAccountReply.AccessKeys[0] + } else { + accessKeys = accountInfo.AccessKeys[0] + } + r.Secret.StringData["auth_token"] = token + r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) + r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey)pkg/system/phase4_configuring.go (3)
157-166: Metrics token: guard empty signing key and add exp/iatAvoid minting with an empty key; add short TTL for metrics.
Apply:
- token, err := util.MakeAuthToken(map[string]any{ - "system": r.NooBaa.Name, - "role": "metrics", - "email": options.OperatorAccountEmail, - }, []byte(r.SecretServer.StringData["jwt"])) + util.SecretResetStringDataFromData(r.SecretServer) + serverJWT := strings.TrimSpace(r.SecretServer.StringData["jwt"]) + if serverJWT == "" { + return fmt.Errorf("server JWT secret is missing/empty") + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.NooBaa.Name, + "role": "metrics", + "email": options.OperatorAccountEmail, + "iat": time.Now().UTC().Unix(), + "exp": time.Now().UTC().Add(1 * time.Hour).Unix(), + }, []byte(serverJWT))
218-227: Operator token: guard signing key and add exp/iatSame concern as metrics; make operator tokens time-bound.
Apply:
- token, err := util.MakeAuthToken(map[string]any{ - "system": r.Request.Name, - "role": "operator", - "email": options.OperatorAccountEmail, - }, []byte(r.SecretServer.StringData["jwt"])) + util.SecretResetStringDataFromData(r.SecretServer) + serverJWT := strings.TrimSpace(r.SecretServer.StringData["jwt"]) + if serverJWT == "" { + return fmt.Errorf("server JWT secret is missing/empty") + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.Request.Name, + "role": "operator", + "email": options.OperatorAccountEmail, + "iat": time.Now().UTC().Unix(), + "exp": time.Now().UTC().Add(24 * time.Hour).Unix(), + }, []byte(serverJWT))
266-276: Admin/endpoints token: guard signing key and add exp/iatPrevent empty-key signing; include expiry.
Apply:
- token, err := util.MakeAuthToken(map[string]any{ - "system": r.Request.Name, - "role": "admin", - "email": options.AdminAccountEmail, - }, []byte(r.SecretServer.StringData["jwt"])) + util.SecretResetStringDataFromData(r.SecretServer) + serverJWT := strings.TrimSpace(r.SecretServer.StringData["jwt"]) + if serverJWT == "" { + return fmt.Errorf("server JWT secret is missing/empty") + } + token, err := util.MakeAuthToken(map[string]any{ + "system": r.Request.Name, + "role": "admin", + "email": options.AdminAccountEmail, + "iat": time.Now().UTC().Unix(), + "exp": time.Now().UTC().Add(24 * time.Hour).Unix(), + }, []byte(serverJWT))pkg/nb/types.go (1)
568-577: JSON tag change breaks API: use name, not usernameaccount_api.update_account expects "name"; switching to "username" will break clients.
Apply:
- Name *string `json:"username,omitempty"` + Name *string `json:"name,omitempty"`Also consider updating the struct comment to reference account_api.update_account().
🧹 Nitpick comments (1)
pkg/util/util.go (1)
1851-1862: Optional: use duration/context for pollingHard-coding 5*60 seconds is fine; consider a time.Duration or context.WithTimeout to make this reusable/configurable.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
go.mod(1 hunks)pkg/backingstore/backingstore.go(1 hunks)pkg/nb/api.go(0 hunks)pkg/nb/types.go(2 hunks)pkg/noobaaaccount/noobaaaccount.go(0 hunks)pkg/noobaaaccount/reconciler.go(1 hunks)pkg/options/options.go(1 hunks)pkg/system/phase4_configuring.go(3 hunks)pkg/util/util.go(3 hunks)test/cli/test_cli_functions.sh(1 hunks)
💤 Files with no reviewable changes (2)
- pkg/nb/api.go
- pkg/noobaaaccount/noobaaaccount.go
🚧 Files skipped from review as they are similar to previous changes (3)
- go.mod
- pkg/backingstore/backingstore.go
- pkg/options/options.go
🧰 Additional context used
🧬 Code graph analysis (2)
pkg/noobaaaccount/reconciler.go (3)
pkg/util/util.go (3)
KubeObject(283-293)KubeCheck(569-590)MakeAuthToken(2394-2410)pkg/bundle/deploy.go (1)
File_deploy_internal_secret_empty_yaml(4902-4909)pkg/options/options.go (3)
Namespace(57-57)SystemName(50-50)OperatorAccountEmail(47-47)
pkg/system/phase4_configuring.go (2)
pkg/util/util.go (1)
MakeAuthToken(2394-2410)pkg/options/options.go (2)
OperatorAccountEmail(47-47)AdminAccountEmail(44-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: run-azure-vault-test
- GitHub Check: run-admission-test
- GitHub Check: run-cli-tests
🔇 Additional comments (2)
test/cli/test_cli_functions.sh (1)
816-816: LGTM: normalize default_resource for legacy valueThe fallback to noobaa-default-backing-store when default_resource is "backingstores" keeps tests compatible with older cores. No further changes needed.
pkg/nb/types.go (1)
289-290: LGTMFormatting-only change; no API impact.
a88fa70 to
2170f04
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
pkg/util/util.go (1)
2394-2410: JWTs lack exp/iat and accept trivially short secrets — add standard claims and enforce key lengthTokens are long-lived if leaked and can be signed with an empty/weak key. Add exp/iat (and optional iss/sub defaults) and require a minimum HS256 key length.
Apply:
func MakeAuthToken(payload map[string]any, secret []byte) (string, error) { - if len(secret) == 0 { - return "", fmt.Errorf("jwt signing secret missing") - } + if len(secret) < 32 { + return "", fmt.Errorf("jwt signing secret missing or too short") + } filtered := jwt.MapClaims{} allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system"} for _, field := range allowedFields { val, ok := payload[field] if ok { filtered[field] = val } } - return jwt.NewWithClaims(jwt.SigningMethodHS256, filtered).SignedString(secret) + now := time.Now().UTC() + filtered["iat"] = now.Unix() + filtered["exp"] = now.Add(15 * time.Minute).Unix() + if _, ok := filtered["iss"]; !ok { + filtered["iss"] = "noobaa-operator" + } + if _, ok := filtered["sub"]; !ok { + if v, ok := filtered["account_id"]; ok { + filtered["sub"] = v + } else if v, ok := filtered["email"]; ok { + filtered["sub"] = v + } + } + return jwt.NewWithClaims(jwt.SigningMethodHS256, filtered).SignedString(secret) }Follow-up:
- If noobaa-core expects specific iss/aud, set them accordingly; otherwise consider adding aud and verifying at the receiver.
- If different TTLs are needed (operator vs metrics), we can add a TTL parameter variant while keeping this default.
I can thread TTL/issuer across call sites if you want.
🧹 Nitpick comments (1)
pkg/noobaaaccount/noobaaaccount.go (1)
265-275: Differentiate NotFound from other RPC failuresReplace the simple
err == nilchecks with explicit handling of “not found” RPC codes and fail fast on other errors:-_, err = sysClient.NBClient.ReadPoolAPI(nb.ReadPoolParams{Name: newDefaultResource}) -isResourceBackingStore := err == nil +isResourceBackingStore := false +if _, err := sysClient.NBClient.ReadPoolAPI(nb.ReadPoolParams{Name: newDefaultResource}); err == nil { + isResourceBackingStore = true +} else if rpcErr, ok := err.(*nb.RPCError); ok && rpcErr.RPCCode == "NO_SUCH_POOL" { + // backing store does not exist +} else { + log.Fatalf("❌ ReadPoolAPI failed: %v", err) +} -_, err = sysClient.NBClient.ReadNamespaceResourceAPI(nb.ReadNamespaceResourceParams{Name: newDefaultResource}) -isResourceNamespaceStore := err == nil +isResourceNamespaceStore := false +if _, err := sysClient.NBClient.ReadNamespaceResourceAPI(nb.ReadNamespaceResourceParams{Name: newDefaultResource}); err == nil { + isResourceNamespaceStore = true +} else if rpcErr, ok := err.(*nb.RPCError); ok && rpcErr.RPCCode == "NO_SUCH_NAMESPACE_RESOURCE" { + // namespace store does not exist +} else { + log.Fatalf("❌ ReadNamespaceResourceAPI failed: %v", err) +}RPC codes “NO_SUCH_POOL” and “NO_SUCH_NAMESPACE_RESOURCE” are confirmed in the codebase. Also consider reusing the existing
sysClientinRunUpdaterather than reconnecting.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
go.mod(1 hunks)pkg/backingstore/backingstore.go(1 hunks)pkg/nb/api.go(0 hunks)pkg/nb/types.go(2 hunks)pkg/noobaaaccount/noobaaaccount.go(1 hunks)pkg/noobaaaccount/reconciler.go(1 hunks)pkg/options/options.go(1 hunks)pkg/system/phase4_configuring.go(3 hunks)pkg/util/util.go(3 hunks)test/cli/test_cli_functions.sh(1 hunks)
💤 Files with no reviewable changes (1)
- pkg/nb/api.go
🚧 Files skipped from review as they are similar to previous changes (6)
- go.mod
- pkg/noobaaaccount/reconciler.go
- pkg/backingstore/backingstore.go
- test/cli/test_cli_functions.sh
- pkg/nb/types.go
- pkg/system/phase4_configuring.go
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/noobaaaccount/noobaaaccount.go (2)
pkg/system/system.go (1)
Connect(1118-1203)pkg/nb/types.go (2)
ReadPoolParams(257-259)ReadNamespaceResourceParams(272-274)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: run-cli-tests
- GitHub Check: run-kms-tls-sa-test
- GitHub Check: run-kms-tls-token-test
- GitHub Check: run-admission-test
- GitHub Check: run-kms-kmip-test
- GitHub Check: run-operator-tests
- GitHub Check: golangci-lint
- GitHub Check: cnpg-deployment-test
- GitHub Check: run-core-config-map-tests
- GitHub Check: run-hac-test
- GitHub Check: run-kms-dev-test
- GitHub Check: run-kms-key-rotate-test
- GitHub Check: run-azure-vault-test
🔇 Additional comments (3)
pkg/options/options.go (1)
33-33: Confirm image tag availability and compatibilityPlease verify the new tag "master-20250908" exists in your registry, satisfies the supported semver bounds (>= 5.0.0, < 6.0.0), and aligns with dependent noobaa-core PR #9211.
pkg/util/util.go (2)
31-31: Direct import of jwt/v4 is appropriateUsing github.com/golang-jwt/jwt/v4 is the right choice here.
1851-1864: Confirm reduced wait timeout is intentionalChanging timeout to 5 minutes may be tight on slow or busy clusters. Ensure this aligns with other polling intervals introduced in this PR (e.g., backingstore readiness).
2170f04 to
2ecf175
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/cli/test_cli_functions.sh (1)
818-833: Add error handling for failed default resource updates.The function updates the default resource and verifies the change, but if the verification fails, it exits without attempting to restore the original state. Consider adding cleanup logic to restore the original default resource even on failure.
test_noobaa account update ${account_name} --new_default_resource=${new_default_resource} local curr_default_resource=$(test_noobaa api account list_accounts {} -o json | jq -r '.accounts[0].default_resource') if [ "${new_default_resource}" != "${curr_default_resource}" ] then echo_time "❌ Looks like account not updated, Exiting" + # Attempt to restore original default resource before exiting + test_noobaa account update ${account_name} --new_default_resource=${default_resource} 2>/dev/null || true exit 1 else echo_time "✅ Update account default_resource successful" test_noobaa account update ${account_name} --new_default_resource=${default_resource} curr_default_resource=$(test_noobaa api account list_accounts {} -o json | jq -r '.accounts[0].default_resource') if [ "${default_resource}" != "${curr_default_resource}" ] then echo_time "❌ Looks like account not updated to default state, Exiting" exit 1 fi fi
♻️ Duplicate comments (3)
pkg/system/phase4_configuring.go (3)
157-161: Critical: Validate JWT secret before token generation.The code directly uses
r.SecretServer.StringData["jwt"]without checking if it exists or is empty. If the JWT secret is missing or empty,util.MakeAuthTokenwill fail or create invalid tokens.+// Ensure the JWT secret is available and non-empty +util.SecretResetStringDataFromData(r.SecretServer) +jwtSecret := r.SecretServer.StringData["jwt"] +if jwtSecret == "" { + return fmt.Errorf("server JWT secret is missing or empty") +} token, err := util.MakeAuthToken(map[string]any{ "system": r.NooBaa.Name, "role": "metrics", "email": options.OperatorAccountEmail, -}, []byte(r.SecretServer.StringData["jwt"])) +}, []byte(jwtSecret))
218-222: Critical: Validate JWT secret before operator token generation.Similar to the metrics token generation, the JWT secret should be validated before use.
+// Ensure the JWT secret is available and non-empty +util.SecretResetStringDataFromData(r.SecretServer) +jwtSecret := r.SecretServer.StringData["jwt"] +if jwtSecret == "" { + return fmt.Errorf("server JWT secret is missing or empty") +} token, err := util.MakeAuthToken(map[string]any{ "system": r.Request.Name, "role": "operator", "email": options.OperatorAccountEmail, -}, []byte(r.SecretServer.StringData["jwt"])) +}, []byte(jwtSecret))
266-270: Critical: Validate JWT secret before admin token generation.The JWT secret validation is needed here as well for consistency and safety.
+// Ensure the JWT secret is available and non-empty +util.SecretResetStringDataFromData(r.SecretServer) +jwtSecret := r.SecretServer.StringData["jwt"] +if jwtSecret == "" { + return fmt.Errorf("server JWT secret is missing or empty") +} token, err := util.MakeAuthToken(map[string]any{ "system": r.Request.Name, "role": "admin", "email": options.AdminAccountEmail, -}, []byte(r.SecretServer.StringData["jwt"])) +}, []byte(jwtSecret))
🧹 Nitpick comments (1)
test/cli/test_cli_functions.sh (1)
816-816: Centralize & document default-resource normalization ('backingstores' → 'noobaa-default-backing-store').Normalization exists only in test/cli/test_cli_functions.sh (line 816); many tests/code reference the literal "noobaa-default-backing-store". Create a shared helper (or document the conversion) and update callers to use it.
Key locations: test/cli/test_cli_functions.sh:816 (normalization), test/cli/test_cli_functions.sh:703,1152,1166,1198–1206; pkg/cosi/cosi_cli_test.go; pkg/cosi/cosi_test.go; pkg/admission/test/integ/admission_integ_test.go.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
go.mod(1 hunks)pkg/backingstore/backingstore.go(1 hunks)pkg/nb/api.go(0 hunks)pkg/nb/types.go(2 hunks)pkg/noobaaaccount/noobaaaccount.go(1 hunks)pkg/noobaaaccount/reconciler.go(1 hunks)pkg/options/options.go(1 hunks)pkg/system/phase4_configuring.go(3 hunks)pkg/util/util.go(3 hunks)test/cli/test_cli_functions.sh(1 hunks)
💤 Files with no reviewable changes (1)
- pkg/nb/api.go
🚧 Files skipped from review as they are similar to previous changes (7)
- pkg/backingstore/backingstore.go
- pkg/noobaaaccount/noobaaaccount.go
- pkg/util/util.go
- pkg/noobaaaccount/reconciler.go
- go.mod
- pkg/nb/types.go
- pkg/options/options.go
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/system/phase4_configuring.go (2)
pkg/util/util.go (1)
MakeAuthToken(2394-2410)pkg/options/options.go (2)
OperatorAccountEmail(47-47)AdminAccountEmail(44-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: run-kms-dev-test
- GitHub Check: run-hac-test
- GitHub Check: run-admission-test
- GitHub Check: run-cli-tests
- GitHub Check: run-kms-kmip-test
- GitHub Check: run-core-config-map-tests
- GitHub Check: run-kms-key-rotate-test
- GitHub Check: cnpg-deployment-test
- GitHub Check: run-kms-tls-token-test
- GitHub Check: run-azure-vault-test
- GitHub Check: run-kms-tls-sa-test
- GitHub Check: run-operator-tests
- GitHub Check: golangci-lint
2ecf175 to
d7751c5
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
pkg/noobaaaccount/reconciler.go (2)
364-376: Guard missing/empty JWT key and use validated bytes; add token expiry
If "jwt" is absent/blank, you’ll sign with an empty key. Also add exp/iat to avoid indefinite tokens. Use trimmed, validated bytes for signing.Apply:
- secretServer := util.KubeObject(bundle.File_deploy_internal_secret_empty_yaml).(*corev1.Secret) + secretServer := util.KubeObject(bundle.File_deploy_internal_secret_empty_yaml).(*corev1.Secret) secretServer.Namespace = r.Request.Namespace secretServer.Name = options.SystemName if !util.KubeCheck(secretServer) { return fmt.Errorf("cannot create an auth token for remote operator - server secret not found") } - token, err := util.MakeAuthToken(map[string]any{ - "system": r.NooBaa.Name, - "role": "operator", - "email": options.OperatorAccountEmail, - }, []byte(secretServer.StringData["jwt"])) + jwtKey := strings.TrimSpace(secretServer.StringData["jwt"]) + if jwtKey == "" { + return fmt.Errorf("cannot create an auth token for remote operator - missing \"jwt\" key in server secret %q", secretServer.Name) + } + jwtBytes := []byte(jwtKey) + + token, err := util.MakeAuthToken(map[string]any{ + "system": r.NooBaa.Name, + "role": "operator", + "email": options.OperatorAccountEmail, + "iat": time.Now().Unix(), + "exp": time.Now().Add(24 * time.Hour).Unix(), + }, jwtBytes)Additionally update util.MakeAuthToken allowlist to include exp/iat:
- allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system"} + allowedFields := []string{"account_id", "system_id", "role", "extra", "authorized_by", "email", "system", "exp", "iat"}
379-383: Nil map write and potential panic on AccessKeys[0]
StringData may be nil; writing to it panics. Also AccessKeys can be empty on older cores.Apply:
- accessKeys := accountInfo.AccessKeys[0] - r.Secret.StringData["auth_token"] = token - r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) - r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey) + if r.Secret.StringData == nil { + r.Secret.StringData = map[string]string{} + } + var accessKeys nb.S3AccessKeys + if len(accountInfo.AccessKeys) == 0 { + log.Info("CreateAccountAPI did not return access keys. calling ReadAccountAPI to get keys..") + readAccountReply, err := r.NBClient.ReadAccountAPI(nb.ReadAccountParams{Email: r.NooBaaAccount.Name}) + if err != nil || len(readAccountReply.AccessKeys) == 0 { + return fmt.Errorf("failed retrieving access keys for %q: %v", r.NooBaaAccount.Name, err) + } + accessKeys = readAccountReply.AccessKeys[0] + } else { + accessKeys = accountInfo.AccessKeys[0] + } + r.Secret.StringData["auth_token"] = token + r.Secret.StringData["AWS_ACCESS_KEY_ID"] = string(accessKeys.AccessKey) + r.Secret.StringData["AWS_SECRET_ACCESS_KEY"] = string(accessKeys.SecretKey)
🧹 Nitpick comments (3)
pkg/backingstore/backingstore.go (1)
947-949: 30s poll hurts UX; prefer shorter or configurable interval30s between status checks makes CLI feel stalled and slows tests. Suggest 10s (or make it flag/env-configurable).
Apply:
- interval := time.Duration(30) + // Poll every ~10s for a snappier UX; keep overall controller-side backoff unchanged. + interval := time.Duration(10)test/cli/test_cli_functions.sh (2)
816-816: Avoid hardcoded alias “backingstores”; normalize via actual default resource
Literal “backingstores” is brittle across core versions/config. Prefer querying the system’s default and mapping once.Apply:
- if [ "${default_resource}" == "backingstores" ]; then default_resource="noobaa-default-backing-store"; fi + # Normalize default_resource from legacy alias to actual name + if [ "${default_resource}" == "backingstores" ] || [ -z "${default_resource}" ]; then + default_resource=$(test_noobaa silence api account list_accounts {} -o json | jq -r '.accounts[0].default_resource') + fi
1195-1195: Operator account may not exist — gate update or create first
If operator@noobaa.io isn’t present, this line fails the suite. Guard or ensure creation.Apply:
- test_noobaa account update operator@noobaa.io --new_default_resource=new-default-backing-store + if test_noobaa silence account list | awk '{print $1}' | grep -qx "operator@noobaa.io"; then + test_noobaa account update operator@noobaa.io --new_default_resource=new-default-backing-store + else + echo_time "ℹ️ Skipping operator account update (operator@noobaa.io not found)" + fi
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
go.mod(1 hunks)pkg/backingstore/backingstore.go(1 hunks)pkg/nb/api.go(0 hunks)pkg/nb/types.go(2 hunks)pkg/noobaaaccount/noobaaaccount.go(1 hunks)pkg/noobaaaccount/reconciler.go(1 hunks)pkg/options/options.go(1 hunks)pkg/system/phase4_configuring.go(3 hunks)pkg/util/util.go(3 hunks)test/cli/test_cli_functions.sh(2 hunks)
💤 Files with no reviewable changes (1)
- pkg/nb/api.go
🚧 Files skipped from review as they are similar to previous changes (6)
- pkg/util/util.go
- pkg/options/options.go
- pkg/noobaaaccount/noobaaaccount.go
- pkg/system/phase4_configuring.go
- go.mod
- pkg/nb/types.go
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/noobaaaccount/reconciler.go (3)
pkg/util/util.go (3)
KubeObject(283-293)KubeCheck(569-590)MakeAuthToken(2394-2410)pkg/bundle/deploy.go (1)
File_deploy_internal_secret_empty_yaml(4902-4909)pkg/options/options.go (3)
Namespace(57-57)SystemName(50-50)OperatorAccountEmail(47-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: run-core-config-map-tests
- GitHub Check: run-kms-tls-sa-test
- GitHub Check: cnpg-deployment-test
- GitHub Check: run-hac-test
- GitHub Check: run-azure-vault-test
- GitHub Check: run-kms-key-rotate-test
- GitHub Check: run-kms-tls-token-test
- GitHub Check: run-kms-kmip-test
- GitHub Check: run-admission-test
- GitHub Check: golangci-lint
- GitHub Check: run-kms-dev-test
- GitHub Check: run-operator-tests
- GitHub Check: run-cli-tests
Signed-off-by: Utkarsh Srivastava <srivastavautkarsh8097@gmail.com>
d7751c5 to
dd5e392
Compare
Explain the changes
This PR:
CreateAuthAPIand replaces it with generating tokens using a new utility functionMakeAuthToken.ResetPasswordAPIand associated tests.Issues: Fixed #xxx / Gap #xxx
Testing Instructions:
Summary by CodeRabbit
Refactor
Behavior Changes
Chores