feat: add managed agent license limit checks (#18937)

- Adds a query for counting managed agent workspace builds between two
timestamps
- The "Actual" field in the feature entitlement for managed agents is
now populated with the value read from the database
- The wsbuilder package now validates AI agent usage against the limit
when a license is installed

Closes coder/internal#777
This commit is contained in:
Dean Sheather
2025-07-22 13:39:26 +10:00
committed by GitHub
parent aa1a985381
commit 9a6dd73f68
24 changed files with 586 additions and 74 deletions
+12
View File
@@ -21,6 +21,7 @@ import (
"github.com/coder/coder/v2/coderd/oauth2provider"
"github.com/coder/coder/v2/coderd/prebuilds"
"github.com/coder/coder/v2/coderd/wsbuilder"
"github.com/andybalholm/brotli"
"github.com/go-chi/chi/v5"
@@ -559,6 +560,13 @@ func New(options *Options) *API {
// bugs that may only occur when a key isn't precached in tests and the latency cost is minimal.
cryptokeys.StartRotator(ctx, options.Logger, options.Database)
// AGPL uses a no-op build usage checker as there are no license
// entitlements to enforce. This is swapped out in
// enterprise/coderd/coderd.go.
var buildUsageChecker atomic.Pointer[wsbuilder.UsageChecker]
var noopUsageChecker wsbuilder.UsageChecker = wsbuilder.NoopUsageChecker{}
buildUsageChecker.Store(&noopUsageChecker)
api := &API{
ctx: ctx,
cancel: cancel,
@@ -579,6 +587,7 @@ func New(options *Options) *API {
TemplateScheduleStore: options.TemplateScheduleStore,
UserQuietHoursScheduleStore: options.UserQuietHoursScheduleStore,
AccessControlStore: options.AccessControlStore,
BuildUsageChecker: &buildUsageChecker,
FileCache: files.New(options.PrometheusRegistry, options.Authorizer),
Experiments: experiments,
WebpushDispatcher: options.WebPushDispatcher,
@@ -1650,6 +1659,9 @@ type API struct {
FileCache *files.Cache
PrebuildsClaimer atomic.Pointer[prebuilds.Claimer]
PrebuildsReconciler atomic.Pointer[prebuilds.ReconciliationOrchestrator]
// BuildUsageChecker is a pointer as it's passed around to multiple
// components.
BuildUsageChecker *atomic.Pointer[wsbuilder.UsageChecker]
UpdatesProvider tailnet.WorkspaceUpdatesProvider