Skip to content

Fix: filter out verified remove android certs in host details#37539

Merged
mostlikelee merged 4 commits intomainfrom
37535-fix-filter
Dec 19, 2025
Merged

Fix: filter out verified remove android certs in host details#37539
mostlikelee merged 4 commits intomainfrom
37535-fix-filter

Conversation

@mostlikelee
Copy link
Copy Markdown
Contributor

@mostlikelee mostlikelee commented Dec 19, 2025

Related issue: Resolves #37535

Updates and renames existing query used by host details

Summary by CodeRabbit

  • New Features

    • Added capability to remove host certificate templates from individual hosts.
  • Tests

    • Added comprehensive test coverage for host certificate template deletion scenarios, including successful deletion and edge cases.

✏️ Tip: You can customize this high-level summary in your review settings.

@mostlikelee mostlikelee requested a review from a team as a code owner December 19, 2025 15:19
@codecov
Copy link
Copy Markdown

codecov bot commented Dec 19, 2025

Codecov Report

❌ Patch coverage is 77.77778% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.92%. Comparing base (514ac23) to head (a98abe7).
⚠️ Report is 33 commits behind head on main.

Files with missing lines Patch % Lines
server/service/certificates.go 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #37539      +/-   ##
==========================================
+ Coverage   65.91%   65.92%   +0.01%     
==========================================
  Files        2357     2357              
  Lines      186781   186880      +99     
  Branches     7862     7862              
==========================================
+ Hits       123124   123208      +84     
- Misses      52408    52417       +9     
- Partials    11249    11255       +6     
Flag Coverage Δ
backend 67.76% <77.77%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

WHERE host_uuid = ?`
WHERE host_uuid = ?
AND NOT (status = '%s' AND operation_type = '%s')`,
fleet.CertificateTemplateVerified, fleet.MDMOperationTypeRemove)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why even keep this row around? If remove is verified, can't we just delete the row?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We indeed can, but wasn't sure if we may need it in the future for auditing purposes. Anything on the roadmap?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should delete it. We should solve auditing with activities or another table. Keeping old data in this table (and special casing this query) will have some performance impact.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good i'll update that in this PR

@getvictor getvictor self-assigned this Dec 19, 2025
Comment on lines +481 to +506
t.Run("deletes single record successfully", func(t *testing.T) {
defer TruncateTables(t, ds)
setup := createCertTemplateTestSetup(t, ctx, ds, "")

// Insert a host certificate template record
_, err := ds.writer(ctx).ExecContext(ctx,
"INSERT INTO host_certificate_templates (host_uuid, certificate_template_id, fleet_challenge, status, operation_type, name) VALUES (?, ?, ?, ?, ?, ?)",
"host-1", setup.template.ID, "challenge", fleet.CertificateTemplateVerified, fleet.MDMOperationTypeRemove, setup.template.Name,
)
require.NoError(t, err)

// Verify record exists
var count int
err = ds.writer(ctx).GetContext(ctx, &count, "SELECT COUNT(*) FROM host_certificate_templates WHERE host_uuid = ? AND certificate_template_id = ?", "host-1", setup.template.ID)
require.NoError(t, err)
require.Equal(t, 1, count)

// Delete the record
err = ds.DeleteHostCertificateTemplate(ctx, "host-1", setup.template.ID)
require.NoError(t, err)

// Verify record was deleted
err = ds.writer(ctx).GetContext(ctx, &count, "SELECT COUNT(*) FROM host_certificate_templates WHERE host_uuid = ? AND certificate_template_id = ?", "host-1", setup.template.ID)
require.NoError(t, err)
require.Equal(t, 0, count)
})
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. I don't see much value in this test. It seems to be already covered by only deletes specified record below.

@getvictor
Copy link
Copy Markdown
Member

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Full review triggered.

getvictor
getvictor previously approved these changes Dec 19, 2025
Copy link
Copy Markdown
Member

@getvictor getvictor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Approving.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 19, 2025

Walkthrough

This PR adds a new DeleteHostCertificateTemplate method to the datastore layer to delete individual host_certificate_template records, integrates it with the certificate service to remove verified certificate requests, and includes comprehensive tests and mock implementations.

Changes

Cohort / File(s) Summary
DataStore Interface Definition
server/fleet/datastore.go
Added DeleteHostCertificateTemplate method signature to the Datastore interface for deleting a host_certificate_template by hostUUID and certificateTemplateID.
MySQL Implementation
server/datastore/mysql/host_certificate_templates.go
Implemented DeleteHostCertificateTemplate method executing a DELETE statement with context-wrapped error handling.
MySQL Tests
server/datastore/mysql/host_certificate_templates_test.go
Added three subtests covering: successful deletion, no error on non-existent record, and isolation (only specified record deleted).
Mock DataStore
server/mock/datastore_mock.go
Added DeleteHostCertificateTemplateFunc type, invocation tracking field, and method implementation for test mocking.
Service Integration
server/service/certificates.go
Updated UpdateCertificateStatus to conditionally delete host_certificate_template record when operation_type is "remove" and status is "verified".

Sequence Diagram

sequenceDiagram
    participant Client
    participant Service as UpdateCertificateStatus
    participant Datastore
    participant Database

    Client->>Service: UpdateCertificateStatus(ctx, operation_type="remove", status="verified", ...)
    alt operation_type == "remove" AND status == "verified"
        Service->>Datastore: DeleteHostCertificateTemplate(hostUUID, certificateTemplateID)
        Datastore->>Database: DELETE FROM host_certificate_templates WHERE host_uuid=? AND certificate_template_id=?
        Database-->>Datastore: Success/Error
        Datastore-->>Service: Error (if any)
        Service-->>Client: Return deletion result
    else Other conditions
        Service->>Datastore: UpsertCertificateStatus(...)
        Datastore-->>Service: Result
        Service-->>Client: Return result
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay special attention to the conditional logic in server/service/certificates.go to ensure the operation_type and status checks align with intended behavior for certificate removal workflows.
  • Verify test isolation in host_certificate_templates_test.go, particularly the "only deletes specified record" subtest, to ensure no unintended side effects across multiple records.

Possibly related PRs

Suggested reviewers

  • dantecatalfamo
  • JordanMontgomery

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The PR description is minimal but provides the related issue number (#37535). However, it lacks detailed explanation of what was changed, why, and testing information required by the template. Expand the description to explain the specific changes made (new DeleteHostCertificateTemplate method, test coverage, and UpdateCertificateStatus logic) and confirm checklist items like testing and database considerations were addressed.
Linked Issues check ❓ Inconclusive The linked issue #37535 provides minimal context ('Filter out verified removed cert requests'). The code changes appear to implement deletion of host certificate templates, which aligns with the general intent to handle verified removed certificates. Review the full issue #37535 details to confirm all coding requirements are met and verify that the implementation fully satisfies the stated objectives.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix: filter out verified remove android certs in host details' is specific and closely related to the main changes, which add deletion functionality for host certificate templates when operation_type is 'remove' and status is 'verified'.
Out of Scope Changes check ✅ Passed All changes are directly related to adding a DeleteHostCertificateTemplate method and integrating it into the certificate status update flow, which aligns with filtering/removing verified certificates in host details.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 37535-fix-filter

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
server/service/certificates.go (1)

589-592: Delete-on-remove+verified path looks correct and idempotent

The new branch cleanly short-circuits UpdateCertificateStatus for operation_type="remove" and status="verified", delegating to DeleteHostCertificateTemplate. Given the prior status/operation-type guards and the datastore’s behavior of not erroring on missing rows, this is safe and idempotent, and it aligns with the goal of hiding successfully removed certificates from host details. If you don’t already have one, a small service-level test exercising this exact combination would lock the behavior in.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 514ac23 and 24d73b8.

📒 Files selected for processing (5)
  • server/datastore/mysql/host_certificate_templates.go (1 hunks)
  • server/datastore/mysql/host_certificate_templates_test.go (2 hunks)
  • server/fleet/datastore.go (1 hunks)
  • server/mock/datastore_mock.go (3 hunks)
  • server/service/certificates.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

⚙️ CodeRabbit configuration file

When reviewing SQL queries that are added or modified, ensure that appropriate filtering criteria are applied—especially when a query is intended to return data for a specific entity (e.g., a single host). Check for missing WHERE clauses or incorrect filtering that could lead to incorrect or non-deterministic results (e.g., returning the first row instead of the correct one). Flag any queries that may return unintended results due to lack of precise scoping.

Files:

  • server/fleet/datastore.go
  • server/datastore/mysql/host_certificate_templates.go
  • server/service/certificates.go
  • server/mock/datastore_mock.go
  • server/datastore/mysql/host_certificate_templates_test.go
🧬 Code graph analysis (2)
server/service/certificates.go (1)
server/fleet/mdm.go (2)
  • MDMOperationTypeRemove (532-532)
  • MDMDeliveryVerified (505-505)
server/datastore/mysql/host_certificate_templates_test.go (1)
server/fleet/host_certificate_template.go (1)
  • HostCertificateTemplate (6-17)
🔇 Additional comments (7)
server/datastore/mysql/host_certificate_templates.go (1)

179-189: Single-row delete is properly scoped and idempotent

The new DeleteHostCertificateTemplate uses a parameterized DELETE with a precise (host_uuid, certificate_template_id) filter and wraps any DB error, while treating “no matching row” as success. That’s a good fit for the service’s idempotent delete-on-verify semantics and respects the SQL scoping guideline.

server/fleet/datastore.go (1)

2576-2578: Interface extension for single-row delete is consistent

Adding DeleteHostCertificateTemplate alongside the existing bulk delete keeps the Datastore contract aligned with the new service behavior and mysql implementation; the comment accurately documents its purpose.

server/datastore/mysql/host_certificate_templates_test.go (2)

27-27: New table-driven test entry is correctly wired

Registering "DeleteHostCertificateTemplate" in the cases slice ensures the new test runs under TestHostCertificateTemplates like the rest of this suite.


478-560: Good coverage for DeleteHostCertificateTemplate semantics

The new testDeleteHostCertificateTemplate subtests exercise successful deletion, idempotent deletion of non-existent rows, and selective deletion when multiple host/template pairs exist. This matches the datastore behavior and guards against regressions in the new delete-on-verify path.

server/mock/datastore_mock.go (3)

1688-1689: New DeleteHostCertificateTemplateFunc type matches existing patterns

The function type’s signature and naming are consistent with the surrounding certificate-related datastore function types and the Datastore interface. No issues here.


4200-4202: DataStore fields correctly wired for DeleteHostCertificateTemplate

The added DeleteHostCertificateTemplateFunc and DeleteHostCertificateTemplateFuncInvoked fields follow the established convention used throughout DataStore for other methods, so they will integrate cleanly with existing test patterns.


10047-10052: DeleteHostCertificateTemplate mock implementation follows existing lock/delegate pattern

The method acquires the mutex, flips the DeleteHostCertificateTemplateFuncInvoked flag, releases the lock, and then delegates to the configured function. This matches the behavior of other mock methods and maintains thread-safety in the same way.

@mostlikelee mostlikelee merged commit f97284c into main Dec 19, 2025
48 checks passed
@mostlikelee mostlikelee deleted the 37535-fix-filter branch December 19, 2025 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Filter out verified removed cert requests

2 participants