-
Notifications
You must be signed in to change notification settings - Fork 6
fix(adhoc-sweep-fixes): CU-86akdypw4 31 review findings across 26 files #358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
671a16f
6ec8d20
2fdf6b2
045a282
27fa0f9
b8b241f
b0bfd22
aa7a70e
6f9d61a
46fd89b
476b206
4ce88da
69530cc
318f5c1
6e6ec94
430dd09
65b87f5
d4bc1c1
9be5d26
7f1aaf8
460145c
cb7e7d6
c3f1bef
e68ca28
b3f625d
ca11d1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,10 @@ const fatalManifestMinChecks = 5 | |
| // fatalManifestTracker records, per application, how long a deterministic | ||
| // manifest error has persisted. Mirrors stallTracker's shape: reset on change, | ||
| // forget on disappearance. | ||
| // | ||
| // Not concurrency-safe: entries is a plain map and observe() must only ever be | ||
| // called from a single goroutine (the wait loop's polling ticker). If callers | ||
| // are ever parallelized, this tracker needs a mutex or per-goroutine instances. | ||
| type fatalManifestTracker struct { | ||
| entries map[string]fatalManifestEntry | ||
| } | ||
|
|
@@ -91,6 +95,9 @@ func newFatalManifestTracker() *fatalManifestTracker { | |
| // deterministic manifest error has persisted past both thresholds. An app that | ||
| // stops showing the error (or becomes ready) is forgotten, so its clock starts | ||
| // fresh if the error ever returns. | ||
| // | ||
| // Not concurrency-safe: must be called from a single goroutine only (see | ||
| // fatalManifestTracker doc comment). | ||
| func (t *fatalManifestTracker) observe(apps []Application, now time.Time) []Application { | ||
| var fatal []Application | ||
| seen := make(map[string]bool, len(apps)) | ||
|
|
@@ -134,7 +141,7 @@ func fatalManifestError(requestedRef string, apps []Application) error { | |
| for _, app := range apps { | ||
| cond := app.Condition | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π fatalManifestError truncates condition mid-string without checking for a byte-safety issue on non-ASCII content In fatalManifestError (line ~135), the truncation π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
| if len(cond) > maxConditionInError { | ||
| cond = cond[:maxConditionInError] + "..." | ||
| cond = strings.ToValidUTF8(cond[:maxConditionInError], "") + "..." | ||
| } | ||
| fmt.Fprintf(&b, " - %s: %s\n", app.Name, cond) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ package argocd | |
| import ( | ||
| "context" | ||
| "fmt" | ||
| "os" | ||
| "sort" | ||
| "strconv" | ||
| "strings" | ||
|
|
@@ -133,6 +134,14 @@ const trackingInstanceLabel = "app.kubernetes.io/instance" | |
| // e.g. "argocd-apps:argoproj.io/Application:argocd/openframe-api". | ||
| const trackingIDAnnotation = "argocd.argoproj.io/tracking-id" | ||
|
|
||
| // syncUnrelatedAppsEnvVar is the explicit opt-in required before | ||
| // syncChildApplications is allowed to fall back to syncing every Application in | ||
| // the namespace when neither tracking marker is present. Unset (or any value | ||
| // other than "true") means the fallback is refused rather than silently | ||
| // force-syncing Applications that may not belong to OpenFrame at all β see the | ||
| // fallback's warning for the risk this guards against. | ||
| const syncUnrelatedAppsEnvVar = "OPENFRAME_ALLOW_SYNC_UNRELATED_APPS" | ||
|
|
||
| // trackingOwner returns the owning Application name encoded in either tracking | ||
| // marker, or "" if neither is present. The label wins when set; otherwise the | ||
| // annotation's owner is the segment before the first ":". Splitting (rather | ||
|
|
@@ -155,10 +164,12 @@ func trackingOwner(labels, annotations map[string]string) string { | |
| // methods leave the label empty β the case the verification run hit, where the | ||
| // primary selector matched nothing and the fallback synced everything. | ||
| // | ||
| // Only when NEITHER marker is present on any Application does it fall back to | ||
| // every Application except the root, rather than silently syncing nothing β | ||
| // but that may touch Applications that are not OpenFrame-owned (a real risk on | ||
| // a shared cluster), which the fallback warning makes visible. | ||
| // Only when NEITHER marker is present on any Application does it consider | ||
| // falling back to every Application except the root β but on a shared ArgoCD | ||
| // instance that may touch Applications that are not OpenFrame-owned at all, so | ||
| // the fallback is refused unless explicitly opted into via | ||
| // OPENFRAME_ALLOW_SYNC_UNRELATED_APPS=true; otherwise it errors instead of | ||
| // silently force-syncing unrelated Applications. | ||
| // | ||
| // Children carrying the SyncGroupLabel are synced group-by-group (lowest | ||
| // first), each group gated on the previous one converging to Healthy+Synced | ||
|
|
@@ -188,14 +199,22 @@ func (m *Manager) syncChildApplications(ctx context.Context, prune bool) error { | |
| } | ||
| } | ||
| if children == nil { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π syncChildApplications fallback path can sync unrelated (non-OpenFrame) Applications on a shared cluster In π€ Prompt for AI agentsfix confidence: π‘ 75 medium β react π/π to teach the reviewer |
||
| var untracked []unstructured.Unstructured | ||
| for i := range list.Items { | ||
| if list.Items[i].GetName() != AppOfAppsName { | ||
| children = append(children, list.Items[i]) | ||
| untracked = append(untracked, list.Items[i]) | ||
| } | ||
| } | ||
| if len(children) > 0 { | ||
| pterm.Warning.Printf("No applications carry the %s=%s tracking label; syncing all %d applications in %q\n", | ||
| trackingInstanceLabel, AppOfAppsName, len(children), ArgoCDNamespace) | ||
| if len(untracked) > 0 { | ||
| if os.Getenv(syncUnrelatedAppsEnvVar) != "true" { | ||
| return fmt.Errorf("no applications carry the %s=%s tracking label or %s tracking-id in namespace %q; "+ | ||
| "refusing to sync %d application(s) that cannot be confirmed as OpenFrame-owned "+ | ||
| "(set %s=true to opt in)", | ||
| trackingInstanceLabel, AppOfAppsName, trackingIDAnnotation, ArgoCDNamespace, len(untracked), syncUnrelatedAppsEnvVar) | ||
| } | ||
| pterm.Warning.Printf("No applications carry the %s=%s tracking label; syncing all %d applications in %q (opted in via %s)\n", | ||
| trackingInstanceLabel, AppOfAppsName, len(untracked), ArgoCDNamespace, syncUnrelatedAppsEnvVar) | ||
| children = untracked | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,15 +39,30 @@ func extractGitAuth(rawURL string) gitAuth { | |
| // A single-field userinfo (e.g. https://<token>@host, a common GitHub PAT | ||
| // shorthand) carries the token as the username with no password. Treat it as | ||
| // the token so it is used for auth (and masked in output) rather than | ||
| // silently stripped from the URL and dropped. | ||
| // silently stripped from the URL and dropped. This is a heuristic: a | ||
| // legitimate plain username with no embedded secret (e.g. | ||
| // https://someuser@host with credentials supplied out-of-band) will also be | ||
| // reinterpreted as a token here. We only apply the heuristic when the | ||
| // userinfo looks like a plausible token (long enough / not a simple word), | ||
| // to reduce the chance of masking a real, non-secret username in output. | ||
| if !hasPassword { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π gitAuth.extractGitAuth silently treats bare username as token even when a real distinct username with no password is intended In π€ Prompt for AI agentsfix confidence: π΄ 40 low β review closely β react π/π to teach the reviewer |
||
| token = username | ||
| username = "" | ||
| if looksLikeToken(username) { | ||
| token = username | ||
| username = "" | ||
| } | ||
| } | ||
| u.User = nil | ||
| return gitAuth{cleanURL: u.String(), username: username, token: token} | ||
| } | ||
|
|
||
| // looksLikeToken is a heuristic guard used by extractGitAuth to decide whether | ||
| // a bare (password-less) userinfo value should be treated as a secret token | ||
| // rather than a plain, non-secret username. Short, simple values are left as | ||
| // usernames so they are not needlessly masked in log output. | ||
| func looksLikeToken(s string) bool { | ||
| return len(s) >= 20 | ||
| } | ||
|
|
||
| // buildAuth returns the in-memory HTTP auth method for a private repository, or | ||
| // nil for a public one. The token lives only in memory β never in the URL, | ||
| // argv, or a credentials file. GitHub PAT auth expects the token as the | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,7 +64,7 @@ func (h *HelmManager) waitForArgoCDDeployments(ctx context.Context, verbose bool | |
|
|
||
| // Check Deployments | ||
| for _, name := range expectedDeployments { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π waitForArgoCDDeployments hardcodes namespace string "argocd" instead of using argocd.ArgoCDNamespace constant In π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
| _, err := h.kubeClient.AppsV1().Deployments("argocd").Get(ctx, name, metav1.GetOptions{}) | ||
| _, err := h.kubeClient.AppsV1().Deployments(argocd.ArgoCDNamespace).Get(ctx, name, metav1.GetOptions{}) | ||
|
|
||
| if k8serrors.IsNotFound(err) { | ||
| missingWorkloads = append(missingWorkloads, "deployment/"+name) | ||
|
|
@@ -77,7 +77,7 @@ func (h *HelmManager) waitForArgoCDDeployments(ctx context.Context, verbose bool | |
|
|
||
| // Check StatefulSets (application-controller in ArgoCD v3.x) | ||
| for _, name := range expectedStatefulSets { | ||
| _, err := h.kubeClient.AppsV1().StatefulSets("argocd").Get(ctx, name, metav1.GetOptions{}) | ||
| _, err := h.kubeClient.AppsV1().StatefulSets(argocd.ArgoCDNamespace).Get(ctx, name, metav1.GetOptions{}) | ||
|
|
||
| if k8serrors.IsNotFound(err) { | ||
| missingWorkloads = append(missingWorkloads, "statefulset/"+name) | ||
|
|
@@ -345,3 +345,4 @@ func (h *HelmManager) verifyClusterConnectivity(ctx context.Context, config conf | |
| } | ||
| return fmt.Errorf("cluster not reachable after retries: %w", lastErr) | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
𦩠π fatalManifestTracker and stallTracker share no synchronization primitive documentation despite being read/written from a polling loop
Added explicit non-concurrency-safe doc comments to the
fatalManifestTrackerstruct and itsobservemethod stating that the map has no synchronization and must only be called from a single goroutine. No mutex was added since the finding only asks for documentation of the invariant (or a mutex "if there's any chance"); since there's no evidence in this file of concurrent callers, documentation-only was chosen as the minimal safe fix β if a future refactor does parallelize polling, an actual mutex would still need to be added.π€ Prompt for AI agents
fix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer