Create rake task to cleanup wrongly provisioned add-on purchases and update existing Duo Pro to Duo Enterprise
What does this MR do and why?
Create rake task to cleanup wrongly provisioned add-on purchases. For more information see the related issue here. The one-time rake task will only be executed for gitlab-org
(ID 9970
) and gitlab-com
(ID 6543
).
This MR will be executed as part of the CR here.
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Queries
Namespace
Namespace.find_by(id: 22)
SELECT "namespaces"."id", "namespaces"."name", "namespaces"."path", "namespaces"."owner_id", "namespaces"."created_at", "namespaces"."updated_at", "namespaces"."type", "namespaces"."description", "namespaces"."avatar", "namespaces"."membership_lock", "namespaces"."share_with_group_lock", "namespaces"."visibility_level", "namespaces"."request_access_enabled", "namespaces"."ldap_sync_status", "namespaces"."ldap_sync_error", "namespaces"."ldap_sync_last_update_at", "namespaces"."ldap_sync_last_successful_update_at", "namespaces"."ldap_sync_last_sync_at", "namespaces"."description_html", "namespaces"."lfs_enabled", "namespaces"."parent_id", "namespaces"."shared_runners_minutes_limit", "namespaces"."repository_size_limit", "namespaces"."require_two_factor_authentication", "namespaces"."two_factor_grace_period", "namespaces"."cached_markdown_version", "namespaces"."project_creation_level", "namespaces"."runners_token", "namespaces"."file_template_project_id", "namespaces"."saml_discovery_token", "namespaces"."runners_token_encrypted", "namespaces"."custom_project_templates_group_id", "namespaces"."auto_devops_enabled", "namespaces"."extra_shared_runners_minutes_limit", "namespaces"."last_ci_minutes_notification_at", "namespaces"."last_ci_minutes_usage_notification_level", "namespaces"."subgroup_creation_level", "namespaces"."max_pages_size", "namespaces"."max_artifacts_size", "namespaces"."mentions_disabled", "namespaces"."default_branch_protection", "namespaces"."max_personal_access_token_lifetime", "namespaces"."push_rule_id", "namespaces"."shared_runners_enabled", "namespaces"."allow_descendants_override_disabled_shared_runners", "namespaces"."traversal_ids", "namespaces"."organization_id" FROM "namespaces" WHERE "namespaces"."id" = 22 LIMIT 1
SELECT "feature_gates"."key", "feature_gates"."value" FROM "feature_gates" WHERE "feature_gates"."feature_key" = 'cached_route_lookups'
SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = 22 AND "routes"."source_type" = 'Namespace' LIMIT 1
Add-on purchases
GitlabSubscriptions::AddOnPurchase.by_namespace(namespace).for_gitlab_duo_pro.first
SELECT "subscription_add_ons"."id" FROM "subscription_add_ons" WHERE "subscription_add_ons"."name" = 1 LIMIT 1
SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."namespace_id" = 22 AND "subscription_add_on_purchases"."subscription_add_on_id" = 1 ORDER BY "subscription_add_on_purchases"."id" ASC LIMIT 1
- Query plan first select: https://postgres.ai/console/gitlab/gitlab-production-main/sessions/32728/commands/100930
- Query plan second select: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/32728/commands/100934
GitlabSubscriptions::AddOnPurchase.by_namespace(namespace).for_duo_enterprise.first
SELECT "subscription_add_ons"."id" FROM "subscription_add_ons" WHERE "subscription_add_ons"."name" = 3 LIMIT 1
SELECT "subscription_add_on_purchases".* FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."namespace_id" = 22 AND "subscription_add_on_purchases"."subscription_add_on_id" = 3 ORDER BY "subscription_add_on_purchases"."id" ASC LIMIT 1
- Query plan first select: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/32728/commands/100932
- Query plan second select: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/32728/commands/100935
Destroy redundant Duo Enterprise add-on purchase
duo_enterprise.destroy
SAVEPOINT active_record_1
DELETE FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."id" = 232
RELEASE SAVEPOINT active_record_1
- Query plan destroy: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/32728/commands/100940
Upgrade Duo Pro add-on purchase to Duo Enterprise
duo_pro.update(add_on: GitlabSubscriptions::AddOn.find_by(name: "duo_enterprise"))
SELECT "subscription_add_ons".* FROM "subscription_add_ons" WHERE "subscription_add_ons"."name" = 3 LIMIT 1
SAVEPOINT active_record_1
SELECT 1 AS one FROM "subscription_add_on_purchases" WHERE "subscription_add_on_purchases"."subscription_add_on_id" = 232 AND "subscription_add_on_purchases"."id" != 231 AND "subscription_add_on_purchases"."namespace_id" = 166 LIMIT 1
UPDATE "subscription_add_on_purchases" SET "updated_at" = '2024-10-18 08:52:24.579714', "subscription_add_on_id" = 232 WHERE "subscription_add_on_purchases"."id" = 23
RELEASE SAVEPOINT active_record_1
- Query plan first select: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/32728/commands/100941
- Query plan second select: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/32728/commands/100942
- Query plan update: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/32728/commands/100945
Screenshots or screen recordings
Screenshots are required for UI changes, and strongly recommended for all other merge requests.
Before | After |
---|---|
How to set up and validate locally
-
Create a group with an Ultimate subscription with Duo Pro
-
Assign Duo Pro seats to group users.
-
Simulate the old version of the rake task with the sync service by manually creating a Duo Enterprise add-on purchase.
GitlabSubscriptions::AddOnPurchase.create( expires_on: 1.year.from_now, started_at: Date.current, namespace: Group.first, quantity: 100, purchase_xid: "test-purchase-xid", subscription_add_on_id: GitlabSubscriptions::AddOn.find_or_create_by_name("duo_enterprise").id, organization_id: Organizations::Organization.first.id )
-
Assign Duo Enterprise seats to others and also to the same group users.
-
Execute the rake task with the namespace ID of your test group.
-
Check the database to see if the Duo Enterprise add-on purchase got deleted.
-
Check the database to see if Duo Pro was upgraded to Duo Enterprise.
-
Check the GitLab Duo UI to see that all previously and newly assigned users are still assigned to the new Duo Enterprise add-on purchase
Resolves #499698 (closed)