fix(enterprise/coderd/license): suppress AI Governance seat-count error for not-entitled licenses

This commit is contained in:
Sas Swart
2026-06-01 06:29:03 +00:00
parent 76d3181aba
commit ff61087df2
2 changed files with 57 additions and 3 deletions
+4 -3
View File
@@ -494,9 +494,10 @@ func LicensesEntitlements(
feature := entitlements.Features[codersdk.FeatureAIGovernanceUserLimit]
switch {
case feature.Entitlement == codersdk.EntitlementNotEntitled:
// If the limit is not set
entitlements.Errors = append(entitlements.Errors,
fmt.Sprintf("Your deployment has %d active AI Governance seats but the license is not entitled to this feature.", actual))
// Not-entitled deployments can accumulate phantom ai_seat_state
// rows from prior Gateway testing or Task usage. Surfacing an
// error here is alarming and inactionable for customers who
// never purchased the AI Governance addon.
case feature.Entitlement == codersdk.EntitlementGracePeriod && feature.Limit != nil:
entitlements.Warnings = append(entitlements.Warnings,
fmt.Sprintf(
+53
View File
@@ -1146,6 +1146,59 @@ func TestEntitlements(t *testing.T) {
require.NotContains(t, warning, "over the limit")
}
})
t.Run("NotEntitledSuppressed", func(t *testing.T) {
t.Parallel()
const activeSeatCount int64 = 42
ctrl := gomock.NewController(t)
mDB := dbmock.NewMockStore(ctrl)
// Premium license without the AI Governance addon.
licenseOpts := (&coderdenttest.LicenseOptions{
FeatureSet: codersdk.FeatureSetPremium,
NotBefore: dbtime.Now().Add(-time.Hour).Truncate(time.Second),
GraceAt: dbtime.Now().Add(time.Hour * 24 * 60).Truncate(time.Second),
ExpiresAt: dbtime.Now().Add(time.Hour * 24 * 90).Truncate(time.Second),
}).
UserLimit(100)
lic := database.License{
ID: 1,
JWT: coderdenttest.GenerateLicense(t, *licenseOpts),
Exp: licenseOpts.ExpiresAt,
}
mDB.EXPECT().
GetUnexpiredLicenses(gomock.Any()).
Return([]database.License{lic}, nil)
mDB.EXPECT().
GetActiveUserCount(gomock.Any(), false).
Return(int64(1), nil)
mDB.EXPECT().
GetActiveAISeatCount(gomock.Any()).
Return(activeSeatCount, nil)
mDB.EXPECT().
GetTotalUsageDCManagedAgentsV1(gomock.Any(), gomock.Any()).
Return(int64(0), nil)
mDB.EXPECT().
GetTemplatesWithFilter(gomock.Any(), gomock.Any()).
Return([]database.Template{}, nil)
entitlements, err := license.Entitlements(context.Background(), mDB, 1, 0, coderdenttest.Keys, all)
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
// The not-entitled case should not produce errors about
// AI Governance seat counts.
for _, e := range entitlements.Errors {
require.NotContains(t, e, "AI Governance seats")
}
for _, w := range entitlements.Warnings {
require.NotContains(t, w, "AI Governance seats")
}
})
})
}