Skip to content

PoC: Use synchronized CC access data to check CC service status

Nikola Milojevic requested to merge 8975-cloud_connector_access_service into master

What does this MR do and why?

Introduce CloudConnector::Access::Services

For Gitlab.com

  • we will read access_data.yml file
  • access_data.yml will be parsed for Gitlab.com, and included_scopes will be used when Gitlab.com self-issues a token with the proper scopes

For SelfManaged

  • we will read CloudConnector::Access database record
  • we will use CDOT issued token

Goal

Reduce the gap between SM and Gitlab.com by using CloudConnector::Access::Services interface for both Gitlab.com and Self-Managed

You can use:

  service = CloudConnector::Access::Services.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

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 Gitlab.com flow:

To remove free access for duo_chat

Add cut_off_date: 2024-02-15 00:00:00 UTC under duo_chat in access_data.yml file

Test Steps

  1. Edit access_data.yml

      ---
        services:
          code_suggestions:
            cut_off_date: 2024-02-15 00:00:00 UTC
            bundled_with:
              code_suggestions:
                included_scopes:
                  - code_suggestions
            free_access:
              included_scopes:
                - code_suggestions
           duo_chat:
             bundled_with:
               code_suggestions:
                 included_scopes:
                   - duo_chat
             free_access:
               included_scopes:
                 - duo_cha
  2. Start rails console by simulating SAAS:

      GITLAB_SIMULATE_SAAS=true bundle exec rails c
  3. Clear the cache:

      Rails.cache.delete(CloudConnector::Access::Services::CLOUD_CONNECTOR_SERVICES_KEY)
      cache_key = format(User::DUO_PRO_ADD_ON_CACHE_KEY, user_id: User.last.id)
      Rails.cache.delete(cache_key)
  4. Use CloudConnector::Access::Services.find_by_name to find the service

      pry(main)> service = CloudConnector::Access::Services.find_by_name(:duo_chat)
      => #<CloudConnector::Access::GitlabCom::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.purchased?
      => true
    
      pry(main)> service = CloudConnector::Access::Services.find_by_name(:duo_chat).access_token
      => "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJiZGQzMTkxZi00YTkzLTRiYzQtYmRlNS03ZTM5Yjk0M2NmYmQiLCJhdWQiOiJnaXRsYWItYWktZ2F0ZXdheSIsImlzcyI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMCIsImlhdCI6MTcxMDc1OTM1NCwibmJmIjoxNzEwNzU5MzQ5LCJleHAiOjE3MTA3NjI5NTQsImdpdGxhYl9yZWFsbSI6InNhYXMiLCJzY29wZXMiOlsiZHVvX2NoYXQiXX0.15DSkUf1BRmyuvscUTPk8gvQYJOEWhZGdbFz56_nAsr2e-YtVCwpR2yVS6gdIds_BQWm4gwzwlw2xQ8j7w6NgDWCxIAoy-VxN8PS__eUJdTfHxm_07zcIMdT3IUH3TKfjdQh-dwuANtMZVME2bdGMJxq5chj0gCLS1EK-BiMuQxrrD5oAi0lGkdMIKr5QC9sN69MbIpSTYdaBZ7rhFwuPho2mEWeccA3LkMHP5SifSshhSsIyF_U0zYgHqFzW3WtYcqmxL995fA_ulNQvkah8DsGDAcp5oSBmq-fkJ801rJ4EpEZzGJ_rOW-rWCyZLIMBozXtNVBYbjXDDheGjq14g"
    

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

  1. 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}]}
  2. Start rails console:

      bundle exec rails c
  3. Clear the cache:

      Rails.cache.delete(CloudConnector::Access::Services::CLOUD_CONNECTOR_SERVICES_KEY)
      cache_key = format(User::DUO_PRO_ADD_ON_CACHE_KEY, user_id: User.last.id)
      Rails.cache.delete(cache_key)
  4. Use CloudConnector::Access::Services.find_by_name to find the service

      pry(main)> service = CloudConnector::Access::Services.find_by_name(:duo_chat)
      => #<CloudConnector::Access::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.purchased?
      => true
    
      pry(main)> service = CloudConnector::Access::Services.find_by_name(:duo_chat).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

Edited by Nikola Milojevic

Merge request reports

Loading