mirror of
https://github.com/zitadel/zitadel.git
synced 2025-11-02 03:38:46 +00:00
# Which Problems Are Solved
Using the service ping, we want to have some additional insights to how
zitadel is configured. The current resource count report contains
already some amount of configured policies, such as the login_policy.
But we do not know if for example MFA is enforced.
# How the Problems Are Solved
- Added the following counts to the report:
- service users per organization
- MFA enforcements (though login policy)
- Notification policies with password change option enabled
- SCIM provisioned users (using user metadata)
- Since all of the above are conditional based on at least a column
inside a projection, a new `migration.CountTriggerConditional` has been
added, where a condition (column values) and an option to track updates
on that column should be considered for the count.
- For this to be possible, the following changes had to be made to the
existing sql resources:
- the `resource_name` has been added to unique constraint on the
`projection.resource_counts` table
- triggers have been added / changed to individually track `INSERT`,
`UPDATE`(s) and `DELETE` and be able to handle conditions
- an optional argument has been added to the
`projections.count_resource()` function to allow providing the
information to `UP` or `DOWN` count the resource on an update.
# Additional Changes
None
# Additional Context
- partially solves #10244 (reporting audit log retention limit will be
handled in #10245 directly)
- backport to v4.x
(cherry picked from commit 2dbe21fb30)
180 lines
5.8 KiB
Go
180 lines
5.8 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.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,
|
|
},
|
|
),
|
|
}
|
|
}
|