Fixed error message when deleting a certificate authority (#41635)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #41532

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved error messaging when deleting a certificate authority that is
referenced by certificate templates. Users now receive a clear,
user-friendly message instead of a generic database error.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Victor Lyuboslavsky
2026-03-13 13:25:35 -05:00
committed by GitHub
parent 0a00d20969
commit fe1e4d295b
4 changed files with 35 additions and 1 deletions
@@ -394,6 +394,11 @@ func (ds *Datastore) DeleteCertificateAuthority(ctx context.Context, certificate
stmt = "DELETE FROM certificate_authorities WHERE id = ?"
result, err := ds.writer(ctx).ExecContext(ctx, stmt, certificateAuthorityID)
if err != nil {
if isMySQLForeignKey(err) {
return nil, fleet.ConflictError{
Message: "Couldn't delete. This certificate authority is used in a certificate. Please remove the certificate first.",
}
}
return nil, ctxerr.Wrap(ctx, err, fmt.Sprintf("deleting certificate authority with id %d", certificateAuthorityID))
}
@@ -378,6 +378,31 @@ func testDeleteCertificateAuthority(t *testing.T, ds *Datastore) {
_, err = ds.DeleteCertificateAuthority(ctx, ca.ID)
require.Error(t, err)
require.Contains(t, err.Error(), "not found")
// Test that deleting a CA referenced by a certificate template returns a conflict error
ca, err = ds.NewCertificateAuthority(ctx, &fleet.CertificateAuthority{
Type: string(fleet.CATypeCustomSCEPProxy),
Name: ptr.String("Referenced CA"),
URL: ptr.String("https://localhost"),
})
require.NoError(t, err)
require.NotNil(t, ca)
team, err := ds.NewTeam(ctx, &fleet.Team{Name: "cert-test-team"})
require.NoError(t, err)
// Insert a certificate template that references the CA
_, err = ds.writer(ctx).ExecContext(ctx,
`INSERT INTO certificate_templates (team_id, certificate_authority_id, name, subject_name) VALUES (?, ?, ?, ?)`,
team.ID, ca.ID, "test-cert", "CN=test",
)
require.NoError(t, err)
_, err = ds.DeleteCertificateAuthority(ctx, ca.ID)
require.Error(t, err)
var conflictErr fleet.ConflictError
require.ErrorAs(t, err, &conflictErr)
require.Contains(t, conflictErr.Error(), "certificate authority is used in a certificate")
}
func testUpdateCertificateAuthorityByID(t *testing.T, ds *Datastore) {