Add gitlab-cloud-connector gem
Create gitlab-cloud-connector
ruby gem. The gem should contain:
- The YML configuration per UP, similar to feature flags, that would contain all needed metadata per UP.
- The business logic to read UP information.
- The business logic for issuing JWT token with scopes based on UP configuration.
- The gem should be designed to be used by both CDot and Gitlab.com
- The dedicated tool to create new unit primitive definitions (similar to bin/featur_flag tool). The tool would ask various questions about the new unit primitive and then create a YAML definition in config/backend_services/[backend_service]/unit_primitives/[unit_primitive_name].yml file.
Usage in CDOT or Gitlab Rails
We would need to configure the Gitlab Cloud Connector gem. Create a class that inherits Gitlab::CloudConnector::PurchasableDecorator
class and overrides the purchased?
method
Example:
require 'gitlab/cloud_connector/unit_primitives'
class CustomPurchasableDecorator < Gitlab::CloudConnector::PurchasableDecorator
extend ::Gitlab::Utils::Override
override :purchased?
def purchased?(namespace)
add_on_purchases(namespace).any?
end
private
def add_on_purchases(namespace = nil)
results = GitlabSubscriptions::AddOnPurchase
.by_add_on_name(add_ons)
.active
results = results.by_namespace_id(namespace.self_and_ancestor_ids) if namespace
results
end
end
Create config/initializers/cloud_connector.rb
initializer
# config/initializers/cloud_connector.rb
require 'gitlab/cloud_connector'
require 'custom_unit_primitives'
::CloudConnector::UnitPrimitives.reload!
Gitlab::CloudConnector::UnitPrimitives.register_hot_reloader! unless Rails.configuration.cache_classes
Gitlab::CloudConnector.configure do |config|
config.purchasable_decorator_class = CustomPurchasableDecorator
config.token_issuer = -> { Doorkeeper::OpenidConnect.configuration.issuer }
config.subject = Gitlab::CurrentSettings.uuid
config.gitlab_version = Gitlab::VERSION
end
The CloudConnector unit primitives are grouped by backend_services
and by the way how they are delivered: delivered_by
(trough common interface i.e Duo Chat).
Proposed RubyGem interface
To access specific unit primitive:
code_suggestions = Gitlab::CloudConnector.unit_primitives[:code_suggestions]
code_suggestions.min_gitlab_version
code_suggestions.cut_off_date
code_suggestions.add_ons
code_suggestions.feature_categories
code_suggestions.free_access?
code_suggestions.supported_gitlab_version?('16.8')
You can group unit primitives by backend service that is hosting the unit primitive.
ai_gateway = Gitlab::CloudConnector.backend_services[:ai_gateway]
ai_gateway.min_gitlab_version # returns the smallest required gitlab version from all grouped unit primitives
ai_gateway.cut_off_date # returns the latest cut-off-date from all grouped unit primitives
ai_gateway.add_ons # returns uniq union of all add-on names bundled with grouped unit primitives
ai_gateway.feature_categories # returns uniq union of all feature-categories that introduced grouped unit primitives
ai_gateway.delivered_by # return groups of unit primitives that are delivered together and hosted by this backend service
ai_gateway.unit_primitives # return list of unit primitives that are hosted by this backend service
You can group unit primitives that are delivered together. The unit primitives can share common user interface. (i.e. Duo Chat)
delivered_by = Gitlab::CloudConnector.delivered_by[:duo_chat]
delivered_by.min_gitlab_version # returns the smallest required gitlab version from all grouped unit primitives
delivered_by.cut_off_date # returns the latest cut-off-date from all grouped unit primitives
delivered_by.add_ons # returns uniq union of all add-on names bundled with grouped unit primitives
delivered_by.feature_categories # returns uniq union of all feature-categories that introduced grouped unit primitives
delivered_by.free_access? # checks if at least one UP in the group has free access
delivered_by.supported_gitlab_version?('16.8') # checks if at least one UP in the group is supported by provided gitlab version
delivered_by.unit_primitives # return list of unit primitives that are delivered together via duo_chat
To list all available add-ons for the instance:
Gitlab::CloudConnector.add_ons
AccessTokens
You can issue an isntance access token that will contain all allowed scopes across all backend services. Note that audience header will contain the list of audiences, containing multiple supported backends, that can authenticate this JWT token.
Gitlab::CloudConnector.instance_access_token(License.last, gitlab_version: '16.8')
You can issue a token per backend service, that will contain all allowed scopes for unit primitives that are hosted by specified backend service.
Gitlab::CloudConnector.backend_services[:ai_gateway].access_token(License.last, gitlab_version: '16.8')
You can issue a token per delivered_by group, that will contain all allowed scopes for unit primitives that are delivered by a common user interface (i.e. Duo Chat)
Gitlab::CloudConnector.delivered_by[:duo_chat].access_token(License.last, gitlab_version: '16.8')
Permission checks
You can call all public methods implemented in PurchasableDecorator on delivered_by group or on unit primitive level
If you want to check if the access to the group has free access
Gitlab::CloudConnector.delivered_by[:duo_chat].free_access?
You can also call any other public method that is implemented by CloudConnector::PurchasableInterface
Or you can check for specific unit primitive:
Gitlab::CloudConnector.unit_primitives[:documentation_search].free_access?