diff --git a/enterprise/coderd/license/license.go b/enterprise/coderd/license/license.go index e66915f221..3cf23823d2 100644 --- a/enterprise/coderd/license/license.go +++ b/enterprise/coderd/license/license.go @@ -262,6 +262,36 @@ func LicensesEntitlements( claims.FeatureSet = codersdk.FeatureSetEnterprise } + // Temporary: If the license doesn't have a managed agent limit, we add + // a default of 1000 managed agents per deployment for a 100 + // year license term. + // This only applies to "Premium" licenses. + if claims.FeatureSet == codersdk.FeatureSetPremium { + var ( + // We intentionally use a fixed issue time here, before the + // entitlement was added to any new licenses, so any + // licenses with the corresponding features actually set + // trump this default entitlement, even if they are set to a + // smaller value. + defaultManagedAgentsIsuedAt = time.Date(2025, 7, 1, 0, 0, 0, 0, time.UTC) + defaultManagedAgentsStart = defaultManagedAgentsIsuedAt + defaultManagedAgentsEnd = defaultManagedAgentsStart.AddDate(100, 0, 0) + defaultManagedAgentsSoftLimit int64 = 1000 + defaultManagedAgentsHardLimit int64 = 1000 + ) + entitlements.AddFeature(codersdk.FeatureManagedAgentLimit, codersdk.Feature{ + Enabled: true, + Entitlement: entitlement, + SoftLimit: &defaultManagedAgentsSoftLimit, + Limit: &defaultManagedAgentsHardLimit, + UsagePeriod: &codersdk.UsagePeriod{ + IssuedAt: defaultManagedAgentsIsuedAt, + Start: defaultManagedAgentsStart, + End: defaultManagedAgentsEnd, + }, + }) + } + // Add all features from the feature set defined. for _, featureName := range claims.FeatureSet.Features() { if _, ok := licenseForbiddenFeatures[featureName]; ok { @@ -338,33 +368,6 @@ func LicensesEntitlements( Limit: &featureValue, Actual: &featureArguments.ActiveUserCount, }) - - // Temporary: If the license doesn't have a managed agent limit, - // we add a default of 800 managed agents per user. - // This only applies to "Premium" licenses. - if claims.FeatureSet == codersdk.FeatureSetPremium { - var ( - // We intentionally use a fixed issue time here, before the - // entitlement was added to any new licenses, so any - // licenses with the corresponding features actually set - // trump this default entitlement, even if they are set to a - // smaller value. - issueTime = time.Date(2025, 7, 1, 0, 0, 0, 0, time.UTC) - defaultSoftAgentLimit = 800 * featureValue - defaultHardAgentLimit = 1000 * featureValue - ) - entitlements.AddFeature(codersdk.FeatureManagedAgentLimit, codersdk.Feature{ - Enabled: true, - Entitlement: entitlement, - SoftLimit: &defaultSoftAgentLimit, - Limit: &defaultHardAgentLimit, - UsagePeriod: &codersdk.UsagePeriod{ - IssuedAt: issueTime, - Start: usagePeriodStart, - End: usagePeriodEnd, - }, - }) - } default: if featureValue <= 0 { // The feature is disabled. diff --git a/enterprise/coderd/license/license_test.go b/enterprise/coderd/license/license_test.go index 0e540989b6..6c53fb3d89 100644 --- a/enterprise/coderd/license/license_test.go +++ b/enterprise/coderd/license/license_test.go @@ -520,8 +520,8 @@ func TestEntitlements(t *testing.T) { t.Run("Premium", func(t *testing.T) { t.Parallel() const userLimit = 1 - const expectedAgentSoftLimit = 800 * userLimit - const expectedAgentHardLimit = 1000 * userLimit + const expectedAgentSoftLimit = 1000 + const expectedAgentHardLimit = 1000 db, _ := dbtestutil.NewDB(t) licenseOptions := coderdenttest.LicenseOptions{ @@ -530,9 +530,7 @@ func TestEntitlements(t *testing.T) { ExpiresAt: dbtime.Now().Add(time.Hour * 24 * 2), FeatureSet: codersdk.FeatureSetPremium, Features: license.Features{ - // Temporary: allows the default value for the - // managed_agent_limit feature to be used. - codersdk.FeatureUserLimit: 1, + codersdk.FeatureUserLimit: userLimit, }, } _, err := db.InsertLicense(context.Background(), database.InsertLicenseParams{ @@ -557,11 +555,15 @@ func TestEntitlements(t *testing.T) { require.Equal(t, codersdk.EntitlementEntitled, agentEntitlement.Entitlement) require.EqualValues(t, expectedAgentSoftLimit, *agentEntitlement.SoftLimit) require.EqualValues(t, expectedAgentHardLimit, *agentEntitlement.Limit) + // This might be shocking, but there's a sound reason for this. // See license.go for more details. - require.Equal(t, time.Date(2025, 7, 1, 0, 0, 0, 0, time.UTC), agentEntitlement.UsagePeriod.IssuedAt) - require.WithinDuration(t, licenseOptions.NotBefore, agentEntitlement.UsagePeriod.Start, time.Second) - require.WithinDuration(t, licenseOptions.ExpiresAt, agentEntitlement.UsagePeriod.End, time.Second) + agentUsagePeriodIssuedAt := time.Date(2025, 7, 1, 0, 0, 0, 0, time.UTC) + agentUsagePeriodStart := agentUsagePeriodIssuedAt + agentUsagePeriodEnd := agentUsagePeriodStart.AddDate(100, 0, 0) + require.Equal(t, agentUsagePeriodIssuedAt, agentEntitlement.UsagePeriod.IssuedAt) + require.WithinDuration(t, agentUsagePeriodStart, agentEntitlement.UsagePeriod.Start, time.Second) + require.WithinDuration(t, agentUsagePeriodEnd, agentEntitlement.UsagePeriod.End, time.Second) continue } @@ -1496,14 +1498,14 @@ func TestManagedAgentLimitDefault(t *testing.T) { }) // "Premium" licenses should receive a default managed agent limit of: - // soft = 800 * user_limit - // hard = 1000 * user_limit + // soft = 1000 + // hard = 1000 t.Run("Premium", func(t *testing.T) { t.Parallel() - const userLimit = 100 - const softLimit = 800 * userLimit - const hardLimit = 1000 * userLimit + const userLimit = 33 + const softLimit = 1000 + const hardLimit = 1000 lic := database.License{ ID: 1, UploadedAt: time.Now(),