-
Notifications
You must be signed in to change notification settings - Fork 1
fix(FLEETMDM-001): CU-86akj32d7 48 review findings across 30 files #165
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
a4d523d
2f87a63
d58eb19
3faa94a
ae704c8
607c971
a80e99b
aa036de
4c4e813
ce0986a
9248509
0a3c67b
642e290
dc38220
458541e
dec0576
a90f4cb
41c9c18
06f9cf3
9cd18e3
a25a9c2
49f2448
7b7eb79
41ae2b7
25164e3
7332da7
8c6aef7
3cf7750
56ee709
911a46c
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 |
|---|---|---|
|
|
@@ -229,7 +229,10 @@ spec: | |
| {{- if .Values.database.tls.enabled }} | ||
|
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. 𦩠π΄ Openframe sentinel comment left unclosed/incomplete in job-migration.yaml volumes block Completed the truncated π€ Prompt for AI agentsfix confidence: π‘ 70 medium β react π/π to teach the reviewer |
||
| - name: mysql-tls | ||
| secret: | ||
| # >>> OPENFRAME(helm): the server CA rides in the same externally managed Secret as | ||
| # >>> OPENFRAME(helm): the server CA, client cert and client key all live in the | ||
| # same externally managed Secret referenced by database.existingSecret (or the | ||
| # chart-managed database.secretName fallback), so this volume mounts that single | ||
| # Secret and FLEET_MYSQL_TLS_CA/CERT/KEY above select the individual keys from it. | ||
| secretName: "{{ default .Values.database.secretName .Values.database.existingSecret }}" | ||
| # <<< OPENFRAME(helm) | ||
| {{- end }} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ rules: | |
| # >>> OPENFRAME(helm): mirror the mysql-tls volume source β openframe/docs/helm-chart.md | ||
| - {{ default .Values.database.secretName .Values.database.existingSecret }} | ||
| # <<< OPENFRAME(helm) | ||
| # NOTE: the following resourceNames (cache/fleet/osquery secrets, imagePullSecrets) are pre-existing upstream fleetdm/fleet lines, not fork-specific additions. | ||
| - {{ .Values.cache.secretName }} | ||
| - {{ .Values.fleet.secretName }} | ||
| - {{ .Values.osquery.secretName }} | ||
|
Comment on lines
17
to
23
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. 𦩠π΄ OPENFRAME sentinel wraps only part of the fork-specific resourceNames edit, leaving the surrounding RBAC verb/resource block unmarked Added an explanatory comment line immediately after the existing π€ Prompt for AI agentsfix confidence: π΄ 25 low β review closely β react π/π to teach the reviewer |
||
|
|
@@ -45,3 +46,4 @@ subjects: | |
| kind: ServiceAccount | ||
| name: fleet | ||
| namespace: {{ .Release.Namespace }} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -129,7 +129,7 @@ fleet: | |
| existingSecret: "" # Name of a K8s Secret. If set, secretKeyValue is ignored. | ||
| secretKeyKey: "FLEET_SETUP_ADMIN_PASSWORD" # Key name within the secret to read the value from. | ||
| secretKeyValue: "fleet" # Plain text password (for dev/test only). Ignored if secret is set. | ||
| # >>> OPENFRAME(mysql-multitenancy): OpenFrame feature block. | ||
|
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. 𦩠π OpenFrame multiTenancy block sentinel comment style inconsistent with rest of file (single '>>>' line, missing matching doc reference format) Updated the sentinel opening comment in π€ Prompt for AI agentsfix confidence: π’ 90 high β react π/π to teach the reviewer |
||
| # >>> OPENFRAME(mysql-multitenancy): OpenFrame feature block β openframe/docs/mysql-multitenancy.md | ||
| openframe: | ||
| multiTenancy: | ||
| enabled: false | ||
|
|
@@ -459,3 +459,4 @@ mysql: | |
|
|
||
| redis: | ||
| enabled: false | ||
|
|
||
|
Comment on lines
459
to
+462
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. 𦩠π Fleet chart ships a default plaintext MySQL password fallback value in values.yaml No functional change made to π€ Prompt for AI agentsfix confidence: π΄ 15 low β review closely β react π/π to teach the reviewer |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,6 +96,9 @@ func Setup( | |
| return nil, fmt.Errorf("failed to load secure hardware key: %w", err) | ||
| } | ||
|
|
||
| // >>> OPENFRAME(host-identity-renewal): Certificate renewal on approaching expiry and | ||
| // scheduled restart timer are fork-specific extensions to the upstream SCEP issuance flow. | ||
| // See openframe/docs/host-identity-renewal.md | ||
| clientCert, err := loadSCEPClientCert(metadataDir) | ||
|
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. 𦩠π΄ New ee/orbit host_identity.go file lacks OPENFRAME sentinel wrapping for fork-specific renewal logic Wrapped the fork-specific renewal logic in π€ Prompt for AI agentsfix confidence: π΄ 35 low β review closely β react π/π to teach the reviewer |
||
| switch { | ||
| case err == nil && certNeedsRenewal(clientCert, certificateRenewalThreshold): | ||
|
|
@@ -111,6 +114,7 @@ func Setup( | |
| clientCert = renewedCert | ||
| logger.Info().Msg("Certificate renewal completed successfully") | ||
| } | ||
| // <<< OPENFRAME(host-identity-renewal) | ||
| case errors.Is(err, os.ErrNotExist): | ||
| // We don't have a certificate, let's issue one using SCEP. | ||
| opts := []scep.Option{ | ||
|
|
@@ -164,6 +168,8 @@ func Setup( | |
| } | ||
| logger.Debug().Msg("secure HW key matches certificate public key") | ||
|
|
||
| // >>> OPENFRAME(host-identity-renewal): scheduled restart timer for certificate renewal. | ||
| // See openframe/docs/host-identity-renewal.md | ||
| // Start a goroutine with a timer to trigger restart for certificate renewal | ||
| if restartFunc != nil { | ||
| go func() { | ||
|
|
@@ -193,6 +199,7 @@ func Setup( | |
| restartFunc("host identity certificate renewal") | ||
| }() | ||
| } | ||
| // <<< OPENFRAME(host-identity-renewal) | ||
|
|
||
| return credentials, nil | ||
| } | ||
|
|
@@ -226,6 +233,10 @@ func saveSCEPClientCert(metadataDir string, cert *x509.Certificate) error { | |
| return nil | ||
| } | ||
|
|
||
| // >>> OPENFRAME(host-identity-renewal): certificate renewal helper functions are | ||
| // fork-specific extensions on top of the upstream SCEP issuance flow. | ||
| // See openframe/docs/host-identity-renewal.md | ||
|
|
||
| // certNeedsRenewal checks if the certificate expires within the given duration | ||
| func certNeedsRenewal(cert *x509.Certificate, renewalThreshold time.Duration) bool { | ||
| return time.Until(cert.NotAfter) < renewalThreshold | ||
|
|
@@ -261,8 +272,10 @@ func RenewCertificate( | |
|
|
||
| // Ensure we restore the backup if something goes wrong, like we cannot connect to Fleet server to get a cert | ||
| defer func() { | ||
|
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. 𦩠π Bare error return without wrapping in RenewCertificate's key-backup restore defer swallows context In π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
| if _, err := os.Stat(oldKeyPath); err == nil { | ||
| _ = os.Rename(oldKeyPath, keyPath) | ||
| if _, statErr := os.Stat(oldKeyPath); statErr == nil { | ||
| if renameErr := os.Rename(oldKeyPath, keyPath); renameErr != nil { | ||
| logger.Error().Err(renameErr).Msg("failed to restore key backup after failed certificate renewal; host may be left without a usable key") | ||
| } | ||
| } | ||
| }() | ||
|
|
||
|
|
@@ -358,3 +371,5 @@ func fetchCertWithRenewal( | |
| // Fetch the certificate with the renewal extension in the CSR | ||
| return scepClient.FetchCert(ctx) | ||
| } | ||
|
|
||
| // <<< OPENFRAME(host-identity-renewal) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -135,10 +135,12 @@ export interface IRemoveTeamSecretFormData { | |
|
|
||
| export const API_ALL_TEAMS_ID = undefined; | ||
| export const APP_CONTEXT_ALL_TEAMS_ID = -1; | ||
| // >>> OPENFRAME(FLEETMDM-001): rebranded "All teams" summary name to "All fleets" | ||
| export const APP_CONTEXT_ALL_TEAMS_SUMMARY: ITeamSummary = { | ||
| id: APP_CONTEXT_ALL_TEAMS_ID, | ||
| name: "All fleets", | ||
| } as const; | ||
| // <<< OPENFRAME(FLEETMDM-001) | ||
|
|
||
| export const API_NO_TEAM_ID = 0; | ||
| export const APP_CONTEXT_NO_TEAM_ID = 0; | ||
|
|
@@ -155,7 +157,11 @@ export const getTeamDisplayName = (team: ITokenTeam) => | |
| ? APP_CONTEXT_NO_TEAM_SUMMARY.name | ||
| : team.name; | ||
|
|
||
| // >>> OPENFRAME(FLEETMDM-001): fork-specific "fleet" rename of getTeamDisplayName | ||
| // added for ITokenFleet; reuses APP_CONTEXT_NO_TEAM_SUMMARY.name for both team | ||
| // and fleet display names. Preserve this block through upstream syncs. | ||
| export const getFleetDisplayName = (fleet: ITokenFleet) => | ||
| fleet.fleet_id === APP_CONTEXT_NO_TEAM_ID | ||
| ? APP_CONTEXT_NO_TEAM_SUMMARY.name | ||
| : fleet.name; | ||
| // <<< OPENFRAME(FLEETMDM-001) | ||
|
Comment on lines
157
to
+167
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. 𦩠π TypeScript rename in shared frontend/interfaces/team.ts lacks OPENFRAME sentinel comments In π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,11 +35,13 @@ func FleetFlags(osqueryVersion string, fleetURL *url.URL) []string { | |
| "--carver_block_size=8000000", | ||
| } | ||
|
|
||
| // >>> OPENFRAME(gzip-flag): enable gzip transport for osquery >= 5.21.0 β openframe/docs/osquery-gzip.md | ||
| if v, err := semver.NewVersion(osqueryVersion); err == nil { | ||
|
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. 𦩠π΄ orbit/pkg/osquery/flags.go adds gzip flag logic without OPENFRAME sentinel comments Wrapped the gzip flag conditional in π€ Prompt for AI agentsfix confidence: π’ 90 high β react π/π to teach the reviewer |
||
| if !semver.New(v.Major(), v.Minor(), v.Patch(), "", "").LessThan(semver.New(5, 21, 0, "", "")) { | ||
| flags = append(flags, "--tls_accept_gzip=true") | ||
| } | ||
| } | ||
| // <<< OPENFRAME(gzip-flag) | ||
|
|
||
| return flags | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,6 +72,7 @@ func (e *Forbidden) LogFields() []interface{} { | |
| } | ||
| } | ||
|
|
||
| // >>> OPENFRAME(authz-platform-http-migration): re-export platform_http error types for backward compatibility during the authz->platform_http migration β openframe/docs/authz-platform-http-migration.md | ||
| // CheckMissing is the error to return when no authorization check was performed | ||
|
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. 𦩠π authz.CheckMissing alias in shared upstream file lacks OPENFRAME sentinel comments Wrapped the π€ Prompt for AI agentsfix confidence: π’ 90 high β react π/π to teach the reviewer |
||
| // by the service. | ||
| // | ||
|
|
@@ -86,3 +87,4 @@ type CheckMissing = platform_http.CheckMissing | |
| // Deprecated: Use platform_http.CheckMissingWithResponse instead. This alias is | ||
| // kept for backward compatibility. | ||
| var CheckMissingWithResponse = platform_http.CheckMissingWithResponse | ||
| // <<< OPENFRAME(authz-platform-http-migration) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,7 +88,16 @@ func (ds *Datastore) SaveDistributedQueryCampaign(ctx context.Context, camp *fle | |
| user_id = ? | ||
| WHERE id = ? | ||
| ` | ||
| result, err := ds.writer(ctx).ExecContext(ctx, sqlStatement, camp.QueryID, camp.Status, camp.UserID, camp.ID) | ||
| args := []interface{}{camp.QueryID, camp.Status, camp.UserID, camp.ID} | ||
| // >>> OPENFRAME(mysql-multitenancy): same fence as DistributedQueryCampaign β an UPDATE by bare | ||
| // campaign.ID must not let one tenant overwrite another tenant's campaign row. No-op when unpinned. | ||
| // β openframe/docs/mysql-multitenancy-feature.md | ||
| if teamID, ok := fleet.OpenframeTeamID(ctx); ok { | ||
| sqlStatement += ` AND EXISTS (SELECT 1 FROM queries q WHERE q.id = distributed_query_campaigns.query_id AND q.team_id = ?)` | ||
| args = append(args, teamID) | ||
| } | ||
| // <<< OPENFRAME(mysql-multitenancy) | ||
| result, err := ds.writer(ctx).ExecContext(ctx, sqlStatement, args...) | ||
| if err != nil { | ||
| return ctxerr.Wrap(ctx, err, "updating distributed query campaign") | ||
| } | ||
|
Comment on lines
88
to
103
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. 𦩠π΄ SaveDistributedQueryCampaign and NewDistributedQueryCampaignTarget missing tenant fencing present in sibling methods In π€ Prompt for AI agentsfix confidence: π‘ 75 medium β react π/π to teach the reviewer |
||
|
|
@@ -154,6 +163,27 @@ func (ds *Datastore) DistributedQueryCampaignTargetIDs(ctx context.Context, id u | |
| } | ||
|
|
||
| func (ds *Datastore) NewDistributedQueryCampaignTarget(ctx context.Context, target *fleet.DistributedQueryCampaignTarget) (*fleet.DistributedQueryCampaignTarget, error) { | ||
| // >>> OPENFRAME(mysql-multitenancy): a target references its campaign by bare ID β verify the | ||
| // campaign belongs to the caller's tenant (via its query's team) before inserting a target row | ||
| // against it, matching the fence on DistributedQueryCampaignTargetIDs. No-op when unpinned. | ||
| // β openframe/docs/mysql-multitenancy-feature.md | ||
| if teamID, ok := fleet.OpenframeTeamID(ctx); ok { | ||
| var exists bool | ||
| checkStmt := ` | ||
| SELECT EXISTS ( | ||
| SELECT 1 FROM distributed_query_campaigns dqc | ||
| JOIN queries q ON q.id = dqc.query_id | ||
| WHERE dqc.id = ? AND q.team_id = ? | ||
| ) | ||
| ` | ||
| if err := sqlx.GetContext(ctx, ds.reader(ctx), &exists, checkStmt, target.DistributedQueryCampaignID, teamID); err != nil { | ||
| return nil, ctxerr.Wrap(ctx, err, "checking distributed query campaign tenant") | ||
| } | ||
| if !exists { | ||
| return nil, notFound("DistributedQueryCampaign").WithID(target.DistributedQueryCampaignID) | ||
| } | ||
| } | ||
| // <<< OPENFRAME(mysql-multitenancy) | ||
| sqlStatement := ` | ||
| INSERT into distributed_query_campaign_targets ( | ||
| type, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,7 @@ | ||
| // >>> OPENFRAME(host-identity-team-scope): scopes the upstream hosts table's | ||
| // osquery_host_id uniqueness constraint per-team instead of globally, so the | ||
| // same device can enroll into more than one tenant team under shared-database | ||
| // multitenancy β openframe/docs/upstream-sync-conflict-resolution.md | ||
| package openframe | ||
|
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. 𦩠π΄ OpenFrame-specific migration file lacks OPENFRAME sentinel comment wrapping Added the required π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
|
|
||
| import ( | ||
|
|
@@ -95,6 +99,51 @@ func Up_20260626000001(tx *sql.Tx) error { | |
| return nil | ||
| } | ||
|
|
||
| // Down_20260626000001 restores the pre-migration schema: it re-creates the | ||
| // original global UNIQUE(osquery_host_id) index and drops the per-team unique | ||
| // index and its supporting generated column. This is only safe to run if no | ||
| // rows currently violate a global-unique(osquery_host_id) constraint (i.e., no | ||
| // device has actually been enrolled into more than one team since Up ran); if | ||
| // such rows exist, re-adding idx_osquery_host_id will fail with a duplicate-key | ||
| // error, which is the correct, safe failure mode for an unsound rollback. | ||
| func Down_20260626000001(tx *sql.Tx) error { | ||
|
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. 𦩠π Migration comment claims idempotency but Down migration is a no-op that cannot restore the original global-unique constraint Replaced the no-op π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer |
||
| const ( | ||
| table = "hosts" | ||
| oldIndex = "idx_osquery_host_id" | ||
| newIndex = "idx_hosts_team_osquery_host_id" | ||
| genColumn = "openframe_team_key" | ||
| ) | ||
|
|
||
| hasOld, err := indexExists(tx, table, oldIndex) | ||
| if err != nil { | ||
| return fmt.Errorf("checking %s index: %w", oldIndex, err) | ||
| } | ||
| if !hasOld { | ||
| if _, err := tx.Exec("ALTER TABLE hosts ADD UNIQUE KEY idx_osquery_host_id (osquery_host_id)"); err != nil { | ||
| return fmt.Errorf("adding %s unique index: %w", oldIndex, err) | ||
| } | ||
| } | ||
|
|
||
| hasNew, err := indexExists(tx, table, newIndex) | ||
| if err != nil { | ||
| return fmt.Errorf("checking %s index: %w", newIndex, err) | ||
| } | ||
| if hasNew { | ||
| if _, err := tx.Exec("ALTER TABLE hosts DROP INDEX idx_hosts_team_osquery_host_id"); err != nil { | ||
| return fmt.Errorf("dropping %s index: %w", newIndex, err) | ||
| } | ||
| } | ||
|
|
||
| hasCol, err := columnExists(tx, table, genColumn) | ||
| if err != nil { | ||
| return fmt.Errorf("checking %s column: %w", genColumn, err) | ||
| } | ||
| if hasCol { | ||
| if _, err := tx.Exec("ALTER TABLE hosts DROP COLUMN openframe_team_key"); err != nil { | ||
| return fmt.Errorf("dropping %s column: %w", genColumn, err) | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // <<< OPENFRAME(host-identity-team-scope) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,9 +36,11 @@ func Up_20260818000001(tx *sql.Tx) error { | |
| return nil | ||
| } | ||
|
|
||
| // >>> OPENFRAME(policies-managed-column): ALTERs upstream `policies` table β openframe/docs/managed-policies.md | ||
| if _, err := tx.Exec("ALTER TABLE policies ADD COLUMN openframe_managed TINYINT(1) NOT NULL DEFAULT 0"); err != nil { | ||
| return fmt.Errorf("adding %s.%s column: %w", table, column, err) | ||
| } | ||
| // <<< OPENFRAME(policies-managed-column) | ||
| return nil | ||
| } | ||
|
|
||
|
Comment on lines
36
to
46
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. 𦩠π΄ OpenFrame migration files touching upstream tables lack OPENFRAME sentinel comments Wrapped the π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| // >>> OPENFRAME(cisco-secure-client-bundle-id): Fork-specific migration to fix Cisco Secure Client bundle-id β openframe/docs/cisco-secure-client-bundle-id.md | ||
| package tables | ||
|
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. 𦩠π΄ New Go migration file lacks OPENFRAME sentinel comments for fork tracking Wrapped the entire fork-specific migration logic (package declaration through the end of π€ Prompt for AI agentsfix confidence: π‘ 85 medium β react π/π to teach the reviewer |
||
|
|
||
| import ( | ||
|
|
@@ -22,20 +23,20 @@ func Up_20251031154558(tx *sql.Tx) error { | |
| WHERE bundle_identifier IN ('com.cisco.pkg.anyconnect.vpn', 'com.cisco.secureclient.gui') | ||
| `) | ||
| if err != nil { | ||
|
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. 𦩠π Bare error propagation without context wrapping in migration Up function Replaced every bare π€ Prompt for AI agentsfix confidence: π‘ 60 medium β react π/π to teach the reviewer |
||
| return err | ||
| return fmt.Errorf("querying software_titles for cisco bundle ids: %w", err) | ||
| } | ||
| defer titleRows.Close() | ||
|
|
||
| bundleIdToTitleId := map[string]string{} | ||
| for titleRows.Next() { | ||
| var id, bundleIdentifier string | ||
| if err := titleRows.Scan(&id, &bundleIdentifier); err != nil { | ||
| return err | ||
| return fmt.Errorf("scanning software_titles row: %w", err) | ||
| } | ||
| bundleIdToTitleId[bundleIdentifier] = id | ||
| } | ||
| if err := titleRows.Err(); err != nil { | ||
| return err | ||
| return fmt.Errorf("iterating software_titles rows: %w", err) | ||
| } | ||
|
|
||
| if len(bundleIdToTitleId) == 0 { | ||
|
|
@@ -51,12 +52,12 @@ func Up_20251031154558(tx *sql.Tx) error { | |
| ('Cisco Secure Client', 'apps', 'com.cisco.secureclient.gui') | ||
| `) | ||
| if err != nil { | ||
| return err | ||
| return fmt.Errorf("inserting correct cisco secure client software title: %w", err) | ||
| } | ||
|
|
||
| lastInsertId, err := res.LastInsertId() | ||
| if err != nil { | ||
| return err | ||
| return fmt.Errorf("getting last insert id for cisco secure client software title: %w", err) | ||
| } | ||
| bundleIdToTitleId["com.cisco.secureclient.gui"] = fmt.Sprintf("%d", lastInsertId) | ||
| } | ||
|
|
@@ -66,23 +67,22 @@ func Up_20251031154558(tx *sql.Tx) error { | |
| SELECT id | ||
| FROM software_installers | ||
| WHERE title_id = ? | ||
| AND extension = 'pkg' | ||
| `, bundleIdToTitleId["com.cisco.pkg.anyconnect.vpn"]) | ||
| if err != nil { | ||
| return err | ||
| return fmt.Errorf("querying software_installers with incorrect cisco title id: %w", err) | ||
| } | ||
| defer installerRows.Close() | ||
|
|
||
| var softwareInstallerIds []string | ||
| for installerRows.Next() { | ||
| var id string | ||
| if err := installerRows.Scan(&id); err != nil { | ||
| return err | ||
| return fmt.Errorf("scanning software_installers row: %w", err) | ||
| } | ||
| softwareInstallerIds = append(softwareInstallerIds, id) | ||
| } | ||
| if err := installerRows.Err(); err != nil { | ||
| return err | ||
| return fmt.Errorf("iterating software_installers rows: %w", err) | ||
| } | ||
|
|
||
| // Update software installers to point to correct title | ||
|
Comment on lines
67
to
88
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. 𦩠π Migration only reassigns installers with extension = 'pkg', but skips exe/msi/deb installers with the incorrect title Removed the π€ Prompt for AI agentsfix confidence: π‘ 70 medium β react π/π to teach the reviewer |
||
|
|
@@ -92,7 +92,7 @@ func Up_20251031154558(tx *sql.Tx) error { | |
| SET title_id = ? | ||
| WHERE id = ? | ||
| `, bundleIdToTitleId["com.cisco.secureclient.gui"], softwareInstallerId); err != nil { | ||
| return err | ||
| return fmt.Errorf("updating software_installers title_id for id %s: %w", softwareInstallerId, err) | ||
| } | ||
| } | ||
|
|
||
|
Comment on lines
92
to
98
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. 𦩠π Migration deletes software_titles row that may still be referenced elsewhere (FK/orphan risk) No schema-level defensive check was added for other tables (host_software, software_title_icons, vpp apps, cve associations) potentially referencing the deleted π€ Prompt for AI agentsfix confidence: π΄ 30 low β review closely β react π/π to teach the reviewer |
||
|
|
@@ -102,11 +102,12 @@ func Up_20251031154558(tx *sql.Tx) error { | |
| DELETE FROM software_titles | ||
| WHERE id = ? | ||
| `, incorrectTitleId); err != nil { | ||
| return err | ||
| return fmt.Errorf("deleting incorrect cisco software title id %s: %w", incorrectTitleId, err) | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
| // <<< OPENFRAME(cisco-secure-client-bundle-id) | ||
|
|
||
| func Down_20251031154558(tx *sql.Tx) error { | ||
| return nil | ||
|
|
||
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.
𦩠π΄ Multi-tenancy Deployment env vars sentinel omits documentation of failure-mode semantics matching the code comment inline vs sentinel boundary mismatch
In the
env:list of thefleetcontainer (OPENFRAME(mysql-multitenancy) block), wrapped the previously-unconditionalFLEET_OPENFRAME_TENANT_UUID(and the already-conditionalFLEET_OPENFRAME_TEAM_ID, now nested inside it) in a new{{- if .Values.fleet.openframe.multiTenancy.enabled }} ... {{- end }}guard. This ensures theconfigMapKeyRefto the tenant ConfigMap is only rendered when multi-tenancy is enabled, preventing the deployment from referencing a possibly-nonexistent ConfigMap key and crash-looping whenmultiTenancy.enabledis false. Risk: if any consumer relied onFLEET_OPENFRAME_TENANT_UUIDbeing present even when disabled (e.g., to explicitly clear/override the value), that behavior changes; a complete fix would also confirm the referenced ConfigMap/template guarantees the key exists wheneverenabledis true.π€ Prompt for AI agents
fix confidence: π‘ 85 medium β react π/π to teach the reviewer