Introduce AvailableServices singleton for accessing data
What does this MR do and why?
Introduce CloudConnector::AvailableServices singleton
For SelfManaged
- we will read CloudConnector::Access database record
- we will use CDOT issued token
Goal
Use CloudConnector::AvailableServices singleton as an interface to get information about CC service.
Note: We currently have CloudConnecor::AccessService
with a similar purpose.
The goal is to provide a more generic interface.
In this iteration, the legacy CloudConnecor::AccessService
is still used.
In this iteration, the CloudConnecor::AvailableServices
singleton is not yet used.
I plan to remove CloudConnecor::AccessService
in a separate merge request and replace the hardcoded checks/and usage.
service = CloudConnector::AvailableServices.find_by_name(:duo_chat)
service.free_acccess? # checks if service is available for free (the cut_off_date is in the future)
service.allowed_for?(user) # checks if the user is assigned to one of the add-on seats that are bundled with the service.
service.access_token # Returns access token
In the next iteration (!148543 (closed)), the plan is to reduce the gap between SM and Gitlab.com by using CloudConnector::AvailableServices singleton for both Gitlab.com and Self-Managed instances.
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.
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
Numbered steps to set up and validate the change are strongly suggested.
To simulate add-on purchases and seat assignments
add_on = GitlabSubscriptions::AddOn.find_or_create_by_name(:code_suggestions, nil)
add_on_purchase = ::GitlabSubscriptions::AddOnPurchases::CreateService.new(nil, add_on, {quantity: 10, expires_on: Time.current + 6.months, purchase_xid: 1})
seat_assigment = ::GitlabSubscriptions::UserAddOnAssignments::SelfManaged::CreateService.new(add_on_purchase: add_on_purchase, user: User.last).execute
To test Self Managed flow
To remove free access for duo_chat
Add cut_off_date: 2024-02-15 00:00:00 UTC
in CloudConnector::Accesss data column:
pry(main)> access_data = CloudConnector::Access.create(data: {"available_services"=>[{"name"=>"code_suggestions", "bundledWith"=>.
["code_suggestions"], "minGitlabVersion"=>nil,
"serviceStartTime"=>"2024-02-15T00:00:00Z"}, {"name"=>"duo_chat", "serviceStartTime"=>"2024-02-15T00:00:00Z", "bundledWith"=>["code_suggestions"], "minGitlabVersion"=>"16.8",
"serviceStartTime"=>nil}]}
Test Steps
-
Create new CloudConnector::Access record
pry(main)> access_data = CloudConnector::Access.create(data: {"available_services"=>[{"name"=>"code_suggestions", "bundledWith"=>["code_suggestions"], "minGitlabVersion"=>nil, "serviceStartTime"=>"2024-02-15T00:00:00Z"}, {"name"=>"duo_chat", "bundledWith"=>["code_suggestions"], "minGitlabVersion"=>"16.8", "serviceStartTime"=>nil}]}
-
Start rails console:
bundle exec rails c
-
Clear the cache:
CloudConnector::AvailableServices.clear_services_cache!
-
Use
CloudConnector::AvailableServices.find_by_name
to find the servicepry(main)> service = CloudConnector::AvailableServices.find_by_name(:duo_chat) => #<CloudConnector::SelfManaged::AvailableServiceData:0x000000013d934d90 @add_on_names=["code_suggestions"], @allowed_scopes_during_free_access=[:duo_chat], @bundled_with={"code_suggestions"=>[:duo_chat]}, @cut_off_date=nil, @name=:duo_chat> pry(main)> service.free_access? => false pry(main)> service.access_token => "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI1NGM3ZWIzOS1mODQ4LTQxOTEtOTI5Yy0xODBkNTJiMWYzYjAiLCJhdWQiOiJnaXRsYWItYWktZ2F0ZXdheSIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC8iLCJpYXQiOjE3MDc0OTUzOTQsIm5iZiI6MTcwNzQ5NTM4OSwiZXhwIjoxNzA3NzU0NTk0LCJnaXRsYWJfcmVhbG0iOiJzZWxmLW1hbmFnZWQiLCJzY29wZXMiOlsiY29kZV9zdWdnZXN0aW9ucyIsImR1b19jaGF0Il19.hHZEDBkQY9aSlP3aUVj6TAQP2XBPv-7QvggB6DiAHZhhdZtLVkdSY-dYLdZ8XLKi9ng5HiA-5q55Taw3ZjErK-xLkE1uzd4_AbLFRSdtRvv7iMioWG4kCsy67-MaSQ-um4av_KUkEQEZRlEWeEBx6GgPdIPGypp02dtbK1Gr7aTpjyx15_pTg_aflu8BJTjVQGAgi1_38uwzKRZlFsSxDTUKGoMhL3UZURQCc-Y1rRe1he-tKrd_-95ae6ozOKzQhN_51ZMEfxsbYxhurr2YGas0V_-zFrnulQhco0jGQeL3OZPPW6CLtw1rRc5pQ1WI47IStPkeqyz-u4pBoNN7WQ" pry(main)> service.allowed_for?(User.last) User Load (1.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1 /*application:console,db_config_name:main,console_hostname:Nikolas-MacBook-Pro.local,console_username:nikola,line:(pry):9:in `__pry__'*/ => true
Related to https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/8975