Skip to content

Decide on CloudConnector unit primitives config and api

Configuration structure

EDR

erDiagram
    UNIT-PRIMITIVE {
      string name
      string description
      date_time cut_off_date
      string min_gitlab_version
      string min_gitlab_version_for_free
      string min_backend_version
      string introduced_by_url
      string group
      string feature_category 
    }
    BACKEND-SERVICE {
      string name
      string group
      string project_url
      string jwt_aud
    }
    ADD-ON {
      string name
    }
    LICENSE-TYPE {
      string name
    }
    GITLAB-REALM {
      string name
    }
    BACKEND-SERVICE }|--|{ UNIT-PRIMITIVE: hosted_by  
    UNIT-PRIMITIVE }|--o{ ADD-ON : bundled_with
    UNIT-PRIMITIVE }|--|{ LICENSE-TYPE : bundled_with
    UNIT-PRIMITIVE }|--|{ GITLAB-REALM: available_for
     

Proposal 1

Update: This proposal was chosen for simplicity. The MR: gitlab-org/cloud-connector/gitlab-cloud-connector!3 (merged)

config
├─ backend_services
│  ├─ ai_gateway.yml
│  └─ duo_workflows.yml
├─ unit_primitives
│  ├─ explain_vulnerability.yml
│  ├─ code_suggestions.yml
│  └─ documentation_search.yml
├─ add_ons
│  ├─ duo_pro.yml
│  └─ duo_enterprise.yml
├─ license_types
│  ├─ premium.yml
│  └─ ultimate.yml
└─ gitlab_realm
   ├─ saas.yml
   └─ self_managed.yml

Backend services

Represents the definition of backend service where the unit primitive is hosted. Contains useful metadata such as project_url or group responsible for the project. It also contains an audience header used when a JWT token is issued.

# backend_services/ai_gateway.yml
---
name: ai_gateway
project_url: https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist
group: group::ai framework
jwt_aud: gitlab-ai-gateway

Unit Primitives

We have yml file per unit primitive. It contains information on how this unit_primitive is bundled with add-ons and license_types, if it is available for saas or self-managed only, and other useful metadata.

# unit_primitives/code_suggesitions.yml
---
name: code_suggestions
description: 
backend_services: 
  - ai_gateway
  - duo_workflows
cut_off_date: 2024-02-15 00:00:00 UTC
min_gitlab_version_for_free_access:
min_gitlab_version: '16.8'
add_ons:
  - duo_pro
  - duo_enterprise
license_types: # List of license types that unit primitive is available for
  - premium
  - ultimate
gitlab_realms: # Some unit primitives could be only enabled for saas or self-managed
  - saas
  - self-managed
introduced_by_url:
group: group::code suggestions
feature_category: code_suggestions

Add Ons

# add_ons/duo_pro.yml
---
name: duo_pro
description: For developers that want to focus on innovation and deliver high-quality software
documentation_url: https://about.gitlab.com/pricing/

License Types

# add_ons/ultimate.yml
---
name: ultimate
description: The ultimate license
documentation_url: https://about.gitlab.com/pricing/

Gitlab Realms

Represents if unit primitives are available for specific gitlab-realm. The unit primitive can be available only for SaaS, or SelfManaged (currently both self-managed and dedicated) instances or for both.

# gitlab-realms/saas.yml
---
name: saas
description: The unit primitive is available only on Gitlab.com

PROS

  • Configuration is simple, stage-groups need just to add a single new_unit_primitive.yml file. And everything is ready.
  • We can provide a 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/unit_primitives/[backend_service]/[unit_primitive_name].yml file.
  • We can use json-schema to validate configuration in ci/cd pipeline

CONS

  • Not clear at first glance which unit primitives are sold under the duo_enterprise or duo_pro add-on. The same goes for license type or which unit_primitives are available only for saas.
    • I talked with @alipniagov, and we could have CI/CD job that would generate a simple HTML static page based on configuration, that would show whole unit primitive structure and relations... and this can be served as Gitlab pages for gitlab-cloud-connector project.
  • The unit primitives YML file is rather complex.

Proposal 2

config
├─ backend_services
│ └─ ai_gateway.yml
├─ unit_primitives
│  ├─ explain_vulnerability.yml
│  ├─ code_suggestions.yml
│  └─ documentation_search.yml
├─ add_ons
│  ├─ duo_pro.yml
│  └─ duo_enterprise.yml
├─ license_types
│  ├─ premium.yml
│  └─ ultimate.yml
└─ gitlab_realm
   ├─ saas.yml
   └─ self_managed.yml

Backend services

Represents the definition of backend service where the unit primitive is hosted. Contains useful metadata such as project_url or group responsible for the project. It contains an audience header used when a JWT token is issued. It also contains a list of unit primitives that are hosted by this backend service.

# ai_gateway.yml
---
name: ai_gateway
project_url: https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist
group: group::ai framework
jwt_aud: gitlab-ai-gateway
unit_primitives:
  - explain_vulnerability
  - code_suggestions
  - documentation_search

Unit Primitives

We have yml file per unit primitive.

# unit_primitives/code_suggesitions.yml
---
name: code_suggestions
description: 
cut_off_date: 2024-02-15 00:00:00 UTC
min_gitlab_version_for_free_access:
min_gitlab_version: '16.8'
min_backend_version:
introduced_by_url:
group: group::code suggestions
feature_category: code_suggestions

Addons

Represents how unit primitives are sold/bundled with add-ons. If unit primitive is listed here, after the cut-off date, to use it, you need to purchase the listed add-on.

# add_ons/duo_pro.yml
---
name: duo_pro
unit_primitives:
  - explain_vulnerability
  - documentation_search
  - ...

License Types

Represents how unit primitives are bundled with licenses/subscriptions. If unit primitive is listed here, to use it, the customer needs to be on the proper license.

# license_types/premium.yml
---
name: premium
unit_primitives:
  - explain_vulnerability
  - documentation_search
  - ...

Gitlab Realms

Represents if unit primitives are available for specific gitlab-realm. The unit primitive can be available only for SaaS, or SelfManaged (currently both self-managed and dedicated) instances or for both.

# gitlab-realms/saas.yml
---
name: saas
unit_primitives:
  - explain_vulnerability
  - documentation_search
  - ...

While similar in structure, the difference compared to Proposal 1 is where we store the associations

  • In proposal 1, we store the association to backend_services, add_ons and license_types in unit_primitive YAML file.
  • In proposal 2, we store the association to unit_primitives in backend_services, add_ons and license_types,` YAML definitions.

Thus in proposal 2 we do have a lot of moving parts when we add a new unit primitive, as we need to update backend_services, add_ons, license_types, and there is a lot of duplications.

In proposal 1 we don't touch add_ons or any of these files unless we are introducing a new add_on.

PROS

  • It is clear to observe how unit primitives are grouped:
    • per add-on
    • per license-type
    • per gitlab-realm
    • per common-user-interface
  • Each config file is small and simple. The parsing logic is also simpler.

CONS

  • There are various places that the stage-group developer needs to update when a new unit primitive is added
  • There is a lot of redundancy as most unit primitives are available for both duo_pro and duo_enterprise add-ons and for both premium and ultimate licenses.. and they are available mostly for both saas and self-managed.
  • We cannot use a dedicated tool to simply configure new unit primitive (it's at least more complex)

Proposal 3

config
├─ backend_services
│  └─ ai_gateway.yml
├─ unit_primitives
│  ├─ explain_vulnerability.yml
│  ├─ code_suggestions.yml
│  └─ documentation_search.yml
└─ unit_primitive_groups.yml

Backend services

Represents the definition of backend service where the unit primitive is hosted. Contains useful metadata such as project_url or group responsible for the project. It contains an audience header used when a JWT token is issued.

# ai_gateway.yml
---
name: ai_gateway
project_url: https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist
group: group::ai framework
jwt_aud: gitlab-ai-gateway

Unit Primitives

We have yml file per unit primitive. It contains information on how this unit_primitive is bundled with add-ons and license_types, if it is available for saas or self-managed only, and other useful metadata.

# unit_primitives/ai_gateway/code_suggesitions.yml
---
name: code_suggestions
description: 
backend_service: ai-gateway
cut_off_date: 2024-02-15 00:00:00 UTC
min_gitlab_version_for_free_access:
min_gitlab_version: '16.8'
min_backend_version:
introduced_by_url:
group: group::code suggestions
feature_category: code_suggestions

Unit Primitive groups

Here the unit primitive groups represent how the unit primitives are grouped. They can be grouped by:

  • add_on
  • license_type
  • gitlab_realm
  • common_user_interface

Each unit primitive can belong to more than one group.

# unit_primitive_groups.yml
---
add_ons:
  duo_pro:
    unit_primitives: &duo_pro
      - documentation_search
      - code_suggestions
  duo_enterprise:
    unit_primitives: &duo_enterprise
      - <<: *duo_pro
      - explain_vulnerability
license_types:
  premium:
    unit_primitives:
      - <<: *duo_pro
  ultimate:
    unit_primitives:
      - <<: *duo_enterprise
gitlab_realms:
  saas:
    unit_primitives:
      - <<: *duo_enterprise
  self-managed:
    unit_primitives:
      - <<: *duo_enterprise

PROS

  • It is clear to observe how unit primitives are grouped:
    • per add-on
    • per license-type
    • per gitlab-realm
  • We can use yml anchors and aliases to reduce redundancy.

CONS

  • the unit_primitive_groups.yml is complex and possibly confusing.
  • We cannot use a dedicated tool to simply configure new unit primitive (it's at least more complex)

Ruby API

Proposal 1

Unit primitives

To find specific unit primitive by name:

  code_suggestions = Gitlab::CloudConnector::UnitPrimitvie.find_by_name(:code_suggestions)
  code_suggestions.name
  code_suggestions.description
  code_suggestions.min_gitlab_version
  code_suggestions.cut_off_date
  code_suggestions.add_ons
  code_suggestions.license_types
  code_suggestions.gitlab_realm
  code_suggestions.backend_services
  code_suggestions.feature_category
  code_suggestions.group

To iterate over unit primitives:

Gitlab::CloudConnector::UnitPrimitvie.find_each do |unit_primitive|
  ...
end

To list all unit primitives:

Gitlab::CloudConnector::UnitPrimitvie.all

Backend services

To find specific backend service by name

  ai_gateway = Gitlab::CloudConnector::BackendService.find_by_name(:ai_gateway)
  ai_gateway.project_url # URL to backend_service project
  ai_gateway.group # Group responsible for backend_service
  ai_gateway.jwt_aud # Audience used when issuing the token for this backend service
  ai_gateway.unit_primitives # returns a list of unit primitives that are hosted by this backend service

To iterate over backend_services:

Gitlab::CloudConnector::BackendService.find_each do |backend_service|
  ...
end

To list all backend services:

Gitlab::CloudConnector::BackendService.all

Addons

To find specific add_on by name:

 add_on = Gitlab::CloudConnector::AddOn.find_by_name(:duo_enterprise)
 add_on.name
 add_on.unit_primitives

To iterate over add_ons:

Gitlab::CloudConnector::AddOn.find_each do |add_on|
  ...
end

To list all add_ons:

Gitlab::CloudConnector::AddOn.all

License Types

To find specific license type per name

 add_on = Gitlab::CloudConnector::AddOn.find_by_name(:duo_enterprise)
 add_on.name
 add_on.unit_primitives

To iterate over license types:

Gitlab::CloudConnector::LicenseType.find_each do |license_type|
  ...
end

To list all license types:

Gitlab::CloudConnector::LicenseType.all

Logging

TBD

Python API

https://gitlab.com/shinya.maeda/poc-cloud-connector/-/tree/master?ref_type=heads#apis

Edited by Nikola Milojevic