Skip to content
代码片段 群组 项目
未验证 提交 db685766 编辑于 作者: Mohamed Hamda's avatar Mohamed Hamda 提交者: GitLab
浏览文件

Change lib to a service

Change the bulk assign lib to a service
上级 326e0a18
No related branches found
No related tags found
无相关合并请求
......@@ -190,7 +190,7 @@ DETAILS:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142189) in GitLab 16.9.
The Rake task for bulk user assignment is available in GitLab 16.9 and later. For GitLab 16.8, use the script [`bulk_user_assignment.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/duo_pro/bulk_user_assignment.rb) instead.
The Rake task for bulk user assignment is available in GitLab 16.9 and later. For GitLab 16.8, use the script [`bulk_user_assignment.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/services/gitlab_subscriptions/duo_pro/bulk_user_assignment.rb) instead.
To perform bulk user assignment for GitLab Duo Pro, you can use the following Rake task:
......
# frozen_string_literal: true
# GitLab Duo Pro Bulk User Assignment
# 1. Set the `add_on_purchase` variable to point to your AddOnPurchase record
# add_on_purchase = GitlabSubscriptions::AddOnPurchase.find_by(add_on: GitlabSubscriptions::AddOn.code_suggestions.last)
# 2. Set the `usernames` variable to point to an array of usernames:
# usernames = ["user1", "user2", "user3", "user4", "user5"]
# If reading from a CSV file
# usernames = CSV.read(FILE_PATH, headers: true).pluck('username')
# 3. Execute the bulk assignment:
# GitlabSubscriptions::DuoPro::BulkUserAssignment.new(usernames, add_on_purchase).execute
# Error Messages:
# - `User is not found`
# - `ERROR_NO_SEATS_AVAILABLE`: No more seats are available.
# - `ERROR_INVALID_USER_MEMBERSHIP`: User is not eligible for assignment due to being inactive, a bot, or a ghost.
module GitlabSubscriptions
module DuoPro
class BulkUserAssignment
include ::GitlabSubscriptions::SubscriptionHelper
attr_reader :usernames, :add_on_purchase, :successful_assignments, :failed_assignments
THROTTLE_BATCH_SIZE = 50
THROTTLE_SLEEP_DELAY = 0.5.seconds
def initialize(usernames, add_on_purchase)
@usernames = usernames
@add_on_purchase = add_on_purchase
@successful_assignments = []
@failed_assignments = []
end
def execute
return 'AddOn not purchased' unless add_on_purchase
process_users(usernames)
{ successful_assignments: successful_assignments, failed_assignments: failed_assignments }
end
private
def process_users(usernames)
usernames.each.with_index(1) do |username, index|
user_to_be_assigned = User.find_by_username(username)
unless user_to_be_assigned
log_failed_assignment("User is not found: #{username}")
next
end
result = assign(user_to_be_assigned)
if result.errors.include?("NO_SEATS_AVAILABLE")
log_no_seats_available(result, username)
break
end
log_result(result, username)
sleep(THROTTLE_SLEEP_DELAY) if index % THROTTLE_BATCH_SIZE == 0
end
end
def assign(user)
service_class = if gitlab_com_subscription?
::GitlabSubscriptions::UserAddOnAssignments::Saas::CreateService
else
::GitlabSubscriptions::UserAddOnAssignments::SelfManaged::CreateService
end
service_class.new(add_on_purchase: add_on_purchase, user: user).execute
end
def log_no_seats_available(result, username)
log_failed_assignment("Failed to assign seat to user: #{username}, Errors: #{result.errors}")
log_failed_assignment("##No seats are left; users starting from @#{username} onwards were not assigned.##")
end
def log_successful_assignment(username)
successful_assignments << "User assigned: #{username}"
end
def log_failed_assignment(message)
failed_assignments << message
end
def log_result(result, username)
if result.errors.empty?
log_successful_assignment(username)
else
log_failed_assignment("Failed to assign seat to user: #{username}, Errors: #{result.errors}")
end
end
end
end
end
# frozen_string_literal: true
# Duo Pro Bulk User Assignment
# 1. Set the `add_on_purchase` variable to point to your AddOnPurchase record
# add_on_purchase = GitlabSubscriptions::AddOnPurchase.find_by(add_on: GitlabSubscriptions::AddOn.code_suggestions.last)
# 2. Set the `usernames` variable to point to an array of usernames:
# usernames = ["user1", "user2", "user3", "user4", "user5"]
# If reading from a CSV file
# usernames = CSV.read(FILE_PATH, headers: true).pluck('username')
# 3. Execute the bulk assignment:
# DuoPro::BulkUserAssignment.new(usernames, add_on_purchase).execute
# Error Messages:
# - `User is not found`
# - `ERROR_NO_SEATS_AVAILABLE`: No more seats are available.
# - `ERROR_INVALID_USER_MEMBERSHIP`: User is not eligible for assignment due to being inactive, a bot, or a ghost.
module DuoPro
class BulkUserAssignment
include ::GitlabSubscriptions::SubscriptionHelper
attr_reader :usernames, :add_on_purchase, :successful_assignments, :failed_assignments
THROTTLE_BATCH_SIZE = 50
THROTTLE_SLEEP_DELAY = 0.5.seconds
def initialize(usernames, add_on_purchase)
@usernames = usernames
@add_on_purchase = add_on_purchase
@successful_assignments = []
@failed_assignments = []
end
def execute
return 'AddOn not purchased' unless add_on_purchase
process_users(usernames)
{ successful_assignments: successful_assignments, failed_assignments: failed_assignments }
end
private
def process_users(usernames)
usernames.each.with_index(1) do |username, index|
user_to_be_assigned = User.find_by_username(username)
unless user_to_be_assigned
log_failed_assignment("User is not found: #{username}")
next
end
result = assign(user_to_be_assigned)
if result.errors.include?("NO_SEATS_AVAILABLE")
log_no_seats_available(result, username)
break
end
log_result(result, username)
sleep(THROTTLE_SLEEP_DELAY) if index % THROTTLE_BATCH_SIZE == 0
end
end
def assign(user)
service_class = if gitlab_com_subscription?
::GitlabSubscriptions::UserAddOnAssignments::Saas::CreateService
else
::GitlabSubscriptions::UserAddOnAssignments::SelfManaged::CreateService
end
service_class.new(add_on_purchase: add_on_purchase, user: user).execute
end
def log_no_seats_available(result, username)
log_failed_assignment("Failed to assign seat to user: #{username}, Errors: #{result.errors}")
log_failed_assignment("##No seats are left; users starting from @#{username} onwards were not assigned.##")
end
def log_successful_assignment(username)
successful_assignments << "User assigned: #{username}"
end
def log_failed_assignment(message)
failed_assignments << message
end
def log_result(result, username)
if result.errors.empty?
log_successful_assignment(username)
else
log_failed_assignment("Failed to assign seat to user: #{username}, Errors: #{result.errors}")
end
end
end
end
......@@ -29,7 +29,7 @@ namespace :duo_pro do
ERROR_MESSAGE
end
result = DuoPro::BulkUserAssignment.new(user_names, add_on_purchase).execute
result = GitlabSubscriptions::DuoPro::BulkUserAssignment.new(user_names, add_on_purchase).execute
display_results(result)
end
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe DuoPro::BulkUserAssignment, feature_category: :purchase do
RSpec.describe GitlabSubscriptions::DuoPro::BulkUserAssignment, feature_category: :seat_cost_management do
describe '#initialize' do
subject(:bulk_assignment) { described_class.new([], nil) }
......
......@@ -33,7 +33,8 @@
before do
add_on_purchase = create(:gitlab_subscription_add_on_purchase, :self_managed, quantity: 10, add_on: add_on)
allow_next_instance_of(DuoPro::BulkUserAssignment, %w[user1 user2 user3], add_on_purchase) do |instance|
allow_next_instance_of(GitlabSubscriptions::DuoPro::BulkUserAssignment, %w[user1 user2 user3],
add_on_purchase) do |instance|
response = { successful_assignments: ['success'], failed_assignments: ['Failed'] }
allow(instance).to receive(:execute).and_return(response)
end
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册