Add monitored-system admission extension hook

This commit is contained in:
rcourtman 2026-04-15 14:04:21 +01:00
parent 3596acfeb2
commit bd8b2efd1b
10 changed files with 233 additions and 7 deletions

View file

@ -0,0 +1,33 @@
package extensions
import "context"
// MonitoredSystemAdmissionInput captures the public counted-system admission
// state computed by the OSS runtime before any private commercial policy hook
// is consulted.
type MonitoredSystemAdmissionInput struct {
Current int
Additional int
Limit int
UsageAvailable bool
UsageUnavailableReason string
CandidateCountsTowardCap bool
}
// MonitoredSystemAdmissionDecision captures the commercial admission outcome
// that a private build may return. This intentionally stays scoped to backend
// admission semantics rather than customer-facing billing/posture messaging.
type MonitoredSystemAdmissionDecision struct {
Current int
Additional int
Limit int
UsageAvailable bool
UsageUnavailableReason string
Exceeded bool
}
// ResolveMonitoredSystemAdmissionPolicyFunc allows private builds to own the
// commercial monitored-system admission decision without importing internal API
// packages. The public runtime remains the source of truth for counted-system
// projection and may call this hook in a later migration slice.
type ResolveMonitoredSystemAdmissionPolicyFunc func(context.Context, MonitoredSystemAdmissionInput) MonitoredSystemAdmissionDecision

View file

@ -96,6 +96,11 @@ type BusinessHooks struct {
// CreateAlertAnalyzer creates the premium alert-triggered analyzer.
// Returns nil in OSS. Enterprise provides a concrete implementation.
CreateAlertAnalyzer func(deps aicontracts.AlertAnalyzerDeps) aicontracts.AlertAnalyzer
// ResolveMonitoredSystemAdmissionPolicy allows private builds to own the
// commercial monitored-system admission decision without importing internal
// API packages. Public runtime still owns counted-system projection.
ResolveMonitoredSystemAdmissionPolicy extensions.ResolveMonitoredSystemAdmissionPolicyFunc
}
var (
@ -299,6 +304,7 @@ func Run(ctx context.Context, version string) error {
createInvestigationStore := globalHooks.CreateInvestigationStore
createInvestigationOrchestrator := globalHooks.CreateInvestigationOrchestrator
createAlertAnalyzer := globalHooks.CreateAlertAnalyzer
resolveMonitoredSystemAdmissionPolicy := globalHooks.ResolveMonitoredSystemAdmissionPolicy
globalHooksMu.Unlock()
api.SetAIInvestigationEnabled(aiInvestigationEnabled)
@ -306,6 +312,7 @@ func Run(ctx context.Context, version string) error {
api.SetCreateInvestigationStore(createInvestigationStore)
api.SetCreateInvestigationOrchestrator(createInvestigationOrchestrator)
api.SetCreateAlertAnalyzer(createAlertAnalyzer)
api.SetResolveMonitoredSystemAdmissionPolicy(resolveMonitoredSystemAdmissionPolicy)
api.SetRBACAdminEndpointsBinder(bindRBACAdminEndpoints)
api.SetAuditAdminEndpointsBinder(bindAuditAdminEndpoints)
api.SetSSOAdminEndpointsBinder(bindSSOAdminEndpoints)

View file

@ -9,17 +9,30 @@ import (
"time"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/pkg/extensions"
"github.com/rcourtman/pulse-go-rewrite/pkg/metrics"
)
func TestBusinessHooks(t *testing.T) {
called := false
resolveCalled := false
hook := func(store *metrics.Store) {
called = true
}
SetBusinessHooks(BusinessHooks{
OnMetricsStoreReady: hook,
ResolveMonitoredSystemAdmissionPolicy: func(_ context.Context, input extensions.MonitoredSystemAdmissionInput) extensions.MonitoredSystemAdmissionDecision {
resolveCalled = true
return extensions.MonitoredSystemAdmissionDecision{
Current: input.Current,
Additional: input.Additional,
Limit: input.Limit,
UsageAvailable: input.UsageAvailable,
UsageUnavailableReason: input.UsageUnavailableReason,
Exceeded: input.UsageAvailable && input.Additional > 0 && input.Limit > 0 && input.Current+input.Additional > input.Limit,
}
},
})
globalHooksMu.Lock()
@ -34,6 +47,23 @@ func TestBusinessHooks(t *testing.T) {
if !called {
t.Error("expected hook to be called")
}
if globalHooks.ResolveMonitoredSystemAdmissionPolicy == nil {
t.Error("expected ResolveMonitoredSystemAdmissionPolicy to be set")
}
decision := globalHooks.ResolveMonitoredSystemAdmissionPolicy(context.Background(), extensions.MonitoredSystemAdmissionInput{
Current: 5,
Additional: 1,
Limit: 5,
UsageAvailable: true,
})
if !resolveCalled {
t.Error("expected monitored-system admission policy hook to be called")
}
if !decision.Exceeded {
t.Fatalf("expected exceeded decision from hook, got %+v", decision)
}
}
func TestPerformAutoImport_Success(t *testing.T) {