Files
zitadel/cmd/setup/trigger_steps.go
921414fa16 fix(telemetry): count IDP template data (#11720)
# Which Problems Are Solved

The total number of configured IDPs seemed of.
We were counting only the IDP table for non-templated IDPs.

# How the Problems Are Solved

Add a count trigger migration for the IDP template table.
Entries will be counted under the existing
`ResourceCountIdentityProvider`

# Additional Changes

- none

# Additional Context

- Reported internally
- Implemented in #9979
- Related https://github.com/zitadel/zitadel/issues/9957

Co-authored-by: Livio Spring <livio.a@gmail.com>
2026-03-17 05:12:43 +00:00

187 lines
6.0 KiB
Go

package setup
import (
"fmt"
"github.com/zitadel/zitadel/internal/api/scim/metadata"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/migration"
"github.com/zitadel/zitadel/internal/query/projection"
"github.com/zitadel/zitadel/internal/serviceping"
)
// triggerSteps defines the repeatable migrations that set up triggers
// for counting resources in the database.
func triggerSteps(db *database.DB) []migration.RepeatableMigration {
return []migration.RepeatableMigration{
// Delete parent count triggers for instances and organizations
migration.DeleteParentCountsTrigger(db,
projection.InstanceProjectionTable,
domain.CountParentTypeInstance,
projection.InstanceColumnID,
projection.InstanceColumnID,
serviceping.ResourceCountInstance,
),
migration.DeleteParentCountsTrigger(db,
projection.OrgProjectionTable,
domain.CountParentTypeOrganization,
projection.OrgColumnInstanceID,
projection.OrgColumnID,
serviceping.ResourceCountOrganization,
),
// Count triggers for all the resources
migration.CountTrigger(db,
projection.OrgProjectionTable,
domain.CountParentTypeInstance,
projection.OrgColumnInstanceID,
projection.OrgColumnInstanceID,
serviceping.ResourceCountOrganization,
),
migration.CountTrigger(db,
projection.ProjectProjectionTable,
domain.CountParentTypeOrganization,
projection.ProjectColumnInstanceID,
projection.ProjectColumnResourceOwner,
serviceping.ResourceCountProject,
),
migration.CountTrigger(db,
projection.UserTable,
domain.CountParentTypeOrganization,
projection.UserInstanceIDCol,
projection.UserResourceOwnerCol,
serviceping.ResourceCountUser,
),
migration.CountTriggerConditional(db,
projection.UserTable,
domain.CountParentTypeOrganization,
projection.UserInstanceIDCol,
projection.UserResourceOwnerCol,
serviceping.ResourceCountUserMachine,
false, // the user type cannot change, so we do not need to track updates
&migration.TriggerCondition{
Column: projection.UserTypeCol,
// since we marshal the value into and from json,
// we directly use the float64 value to prevent issues with the comparison of the previous migration
Value: float64(2),
},
),
migration.CountTrigger(db,
projection.InstanceMemberProjectionTable,
domain.CountParentTypeInstance,
projection.MemberInstanceID,
projection.MemberResourceOwner,
serviceping.ResourceCountIAMAdmin,
),
migration.CountTrigger(db,
projection.IDPTable,
domain.CountParentTypeInstance,
projection.IDPInstanceIDCol,
projection.IDPInstanceIDCol,
serviceping.ResourceCountIdentityProvider,
),
migration.CountTrigger(db,
projection.IDPTemplateTable,
domain.CountParentTypeInstance,
projection.IDPTemplateInstanceIDCol,
projection.IDPTemplateInstanceIDCol,
serviceping.ResourceCountIdentityProvider,
),
migration.CountTrigger(db,
projection.IDPTemplateLDAPTable,
domain.CountParentTypeInstance,
projection.LDAPInstanceIDCol,
projection.LDAPInstanceIDCol,
serviceping.ResourceCountIdentityProviderLDAP,
),
migration.CountTrigger(db,
projection.ActionTable,
domain.CountParentTypeInstance,
projection.ActionInstanceIDCol,
projection.ActionInstanceIDCol,
serviceping.ResourceCountActionV1,
),
migration.CountTrigger(db,
projection.ExecutionTable,
domain.CountParentTypeInstance,
projection.ExecutionInstanceIDCol,
projection.ExecutionInstanceIDCol,
serviceping.ResourceCountActionExecution,
),
migration.CountTrigger(db,
fmt.Sprintf("%s_%s", projection.ExecutionTable, projection.ExecutionTargetSuffix),
domain.CountParentTypeInstance,
projection.ExecutionTargetInstanceIDCol,
projection.ExecutionTargetInstanceIDCol,
serviceping.ResourceCountActionExecutionTarget,
),
migration.CountTrigger(db,
projection.LoginPolicyTable,
domain.CountParentTypeInstance,
projection.LoginPolicyInstanceIDCol,
projection.LoginPolicyInstanceIDCol,
serviceping.ResourceCountLoginPolicy,
),
migration.CountTriggerConditional(db,
projection.LoginPolicyTable,
domain.CountParentTypeInstance,
projection.LoginPolicyInstanceIDCol,
projection.LoginPolicyInstanceIDCol,
serviceping.ResourceCountEnforceMFA,
true,
&migration.OrCondition{
Conditions: []migration.TriggerCondition{
{Column: projection.LoginPolicyForceMFACol, Value: true},
{Column: projection.LoginPolicyForceMFALocalOnlyCol, Value: true},
},
},
),
migration.CountTrigger(db,
projection.PasswordComplexityTable,
domain.CountParentTypeInstance,
projection.ComplexityPolicyInstanceIDCol,
projection.ComplexityPolicyInstanceIDCol,
serviceping.ResourceCountPasswordComplexityPolicy,
),
migration.CountTrigger(db,
projection.PasswordAgeTable,
domain.CountParentTypeInstance,
projection.AgePolicyInstanceIDCol,
projection.AgePolicyInstanceIDCol,
serviceping.ResourceCountPasswordExpiryPolicy,
),
migration.CountTrigger(db,
projection.LockoutPolicyTable,
domain.CountParentTypeInstance,
projection.LockoutPolicyInstanceIDCol,
projection.LockoutPolicyInstanceIDCol,
serviceping.ResourceCountLockoutPolicy,
),
migration.CountTriggerConditional(db,
projection.NotificationPolicyProjectionTable,
domain.CountParentTypeInstance,
projection.NotificationPolicyColumnInstanceID,
projection.NotificationPolicyColumnInstanceID,
serviceping.ResourceCountPasswordChangeNotification,
true,
&migration.TriggerCondition{
Column: projection.NotificationPolicyColumnPasswordChange,
Value: true,
},
),
migration.CountTriggerConditional(db,
projection.UserMetadataProjectionTable,
domain.CountParentTypeOrganization,
projection.UserMetadataColumnInstanceID,
projection.LockoutPolicyResourceOwnerCol,
serviceping.ResourceCountScimProvisionedUser,
false, // the key cannot change, so we do not need to track updates
&migration.TriggerCondition{
Column: projection.UserMetadataColumnKey,
Value: metadata.KeyEmails,
},
),
}
}