Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
abb667b8e8
commit
d92f387cfd
|
@ -81,7 +81,16 @@ with the deployed staging AI Gateway. To do this:
|
||||||
export GITLAB_SIMULATE_SAAS=0
|
export GITLAB_SIMULATE_SAAS=0
|
||||||
```
|
```
|
||||||
|
|
||||||
On a non-GDK instance, you can set the variables using `gitlab_rails['env']` in the `gitlab.rb` file.
|
On a non-GDK instance, you can set the variables using `gitlab_rails['env']` in the `gitlab.rb` file:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
gitlab_rails['env'] = {
|
||||||
|
'GITLAB_LICENSE_MODE' => 'test',
|
||||||
|
'CUSTOMER_PORTAL_URL' => 'https://customers.staging.gitlab.com',
|
||||||
|
'AI_GATEWAY_URL' => 'https://cloud.staging.gitlab.com/ai'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
1. Restart your GDK.
|
1. Restart your GDK.
|
||||||
1. Go to `/admin/subscription`.
|
1. Go to `/admin/subscription`.
|
||||||
1. Optional. Remove any active license.
|
1. Optional. Remove any active license.
|
||||||
|
|
|
@ -0,0 +1,760 @@
|
||||||
|
---
|
||||||
|
stage: Fulfillment
|
||||||
|
group: Provision
|
||||||
|
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments"
|
||||||
|
---
|
||||||
|
|
||||||
|
# GitLab Subscriptions Internal API
|
||||||
|
|
||||||
|
The GitLab Subscriptions internal API is used by the CustomersDot application,
|
||||||
|
it cannot be used by other consumers. This documentation is intended for people
|
||||||
|
working on the GitLab and CustomersDot codebases.
|
||||||
|
|
||||||
|
## Add new endpoints
|
||||||
|
|
||||||
|
API endpoints should be externally accessible by default, with proper authentication and authorization.
|
||||||
|
Before adding a new internal endpoint, consider if the API would benefit the wider GitLab community and
|
||||||
|
can be made externally accessible.
|
||||||
|
|
||||||
|
For the GitLab Subscription portal, we might chose to use an internal API when we need to make updates
|
||||||
|
to GitLab without the context of a user. This means we don't have access to a user's access token, and
|
||||||
|
instead make updates as the CustomersDot application in general.
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
### CustomersDot JWT
|
||||||
|
|
||||||
|
These endpoints are all authenticated using JWT authentication from CustomersDot.
|
||||||
|
|
||||||
|
To authenticate using the JWT, clients:
|
||||||
|
|
||||||
|
1. Read the contents of the signing key from the credentials.
|
||||||
|
1. Use the signing key to generate a JSON Web Token (`JWT`).
|
||||||
|
1. Pass the JWT in the `X-CUSTOMERS-DOT-INTERNAL-TOKEN` header.
|
||||||
|
|
||||||
|
### Admin personal access token (PAT)
|
||||||
|
|
||||||
|
This authentication method is deprecated as it is not supported in the Cells architecture. It will be
|
||||||
|
[removed in a future milestone](https://gitlab.com/gitlab-org/gitlab/-/issues/473625). Please use JWT authentication instead.
|
||||||
|
|
||||||
|
To authenticate as an administrator, generate a personal access token for an administrator with the
|
||||||
|
`api` and `admin_mode` scopes. This token can then be supplied in the `PRIVATE-TOKEN` header.
|
||||||
|
|
||||||
|
## Internal Endpoints
|
||||||
|
|
||||||
|
### Namespaces
|
||||||
|
|
||||||
|
#### Fetch group owners
|
||||||
|
|
||||||
|
Use a GET command to get direct owners of the namespace. CustomersDot uses this endpoint to find users to notify about
|
||||||
|
billing events.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /internal/gitlab_subscriptions/namespaces/:id/owners
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1234/owners"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"id": 1,
|
||||||
|
"username": "john_smith",
|
||||||
|
"name": "John Smith"
|
||||||
|
},
|
||||||
|
"access_level": 50,
|
||||||
|
"notification_email": "name@example.com"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Fetch a namespace by ID
|
||||||
|
|
||||||
|
Used to fetch information about a namespace.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /internal/gitlab_subscriptions/namespaces/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------- | -------------- | -------- | ----------- |
|
||||||
|
| `id` | integer/string | yes | ID or [URL-encoded path of the namespace](../../api/rest/index.md#namespaced-path-encoding) |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request GET --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "group1",
|
||||||
|
"path": "group1",
|
||||||
|
"kind": "group",
|
||||||
|
"full_path": "group1",
|
||||||
|
"parent_id": null,
|
||||||
|
"avatar_url": null,
|
||||||
|
"web_url": "https://gitlab.example.com/groups/group1",
|
||||||
|
"members_count_with_descendants": 2,
|
||||||
|
"billable_members_count": 2,
|
||||||
|
"max_seats_used": 0,
|
||||||
|
"seats_in_use": 0,
|
||||||
|
"plan": "default",
|
||||||
|
"end_date": null,
|
||||||
|
"trial_ends_on": null,
|
||||||
|
"trial": false,
|
||||||
|
"root_repository_size": 100,
|
||||||
|
"projects_count": 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Update a namespace
|
||||||
|
|
||||||
|
Use a PUT command to update an existing namespace.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
PUT /internal/gitlab_subscriptions/namespaces/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------- | -------------- | -------- | ----------- |
|
||||||
|
| `id` | integer/string | yes | ID or [URL-encoded path of the namespace](../../api/rest/index.md#namespaced-path-encoding) |
|
||||||
|
| `shared_runners_minutes_limit` | integer | no | Compute minutes quota |
|
||||||
|
| `extra_shared_runners_minutes_limit` | integer | no | Extra compute minutes |
|
||||||
|
| `additional_purchased_storage_size` | integer | no | Additional storage size |
|
||||||
|
| `additional_purchased_storage_ends_on` | date | no | Additional purchased storage Ends on |
|
||||||
|
| `gitlab_subscription_attributes` | hash | no | Hash object containing GitLab Subscription attributes. Accepts `seats`,`max_seats_used`,`plan_code`,`end_date`,`auto_renew`,`trial`,`trial_ends_on`,`trial_starts_on`,`trial_extension_type` |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request PUT --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1 --data '{"shared_runners_minutes_limit":1000}'"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "group1",
|
||||||
|
"path": "group1",
|
||||||
|
"kind": "group",
|
||||||
|
"full_path": "group1",
|
||||||
|
"parent_id": null,
|
||||||
|
"avatar_url": null,
|
||||||
|
"web_url": "https://gitlab.example.com/groups/group1",
|
||||||
|
"members_count_with_descendants": 2,
|
||||||
|
"billable_members_count": 2,
|
||||||
|
"max_seats_used": 0,
|
||||||
|
"seats_in_use": 0,
|
||||||
|
"plan": "default",
|
||||||
|
"end_date": null,
|
||||||
|
"trial_ends_on": null,
|
||||||
|
"trial": false,
|
||||||
|
"root_repository_size": 100,
|
||||||
|
"projects_count": 3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Subscriptions
|
||||||
|
|
||||||
|
The subscription endpoints are used by
|
||||||
|
[CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`) to
|
||||||
|
apply subscriptions (including trials, and add-on purchases) to personal namespaces, or top-level
|
||||||
|
groups on GitLab.com.
|
||||||
|
|
||||||
|
#### Fetch a subscription
|
||||||
|
|
||||||
|
Use a GET command to view an existing subscription.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /internal/gitlab_subscriptions/namespaces/:id/gitlab_subscription
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1234/gitlab_subscription"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"plan": {
|
||||||
|
"code": "premium",
|
||||||
|
"name": "premium",
|
||||||
|
"trial": false,
|
||||||
|
"auto_renew": null,
|
||||||
|
"upgradable": false,
|
||||||
|
"exclude_guests": false
|
||||||
|
},
|
||||||
|
"usage": {
|
||||||
|
"seats_in_subscription": 80,
|
||||||
|
"seats_in_use": 82,
|
||||||
|
"max_seats_used": 82,
|
||||||
|
"seats_owed": 2
|
||||||
|
},
|
||||||
|
"billing": {
|
||||||
|
"subscription_start_date": "2020-07-15",
|
||||||
|
"subscription_end_date": "2021-07-15",
|
||||||
|
"trial_ends_on": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Upcoming Reconciliations
|
||||||
|
|
||||||
|
The `upcoming_reconciliations` endpoint is used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
|
||||||
|
to update upcoming reconciliations for namespaces.
|
||||||
|
|
||||||
|
#### Update an upcoming reconciliation
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
PUT /internal/gitlab_subscriptions/namespaces/:namespace_id/upcoming_reconciliations
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:---------------------------|:-----|:---------|:--------------------------------------------------------|
|
||||||
|
| `namespace_id` | ID | yes | ID of the namespace with the upcoming reconciliation |
|
||||||
|
| `next_reconciliation_date` | date | yes | Date the reconciliation will occur on |
|
||||||
|
| `display_alert_from` | date | yes | Date to start display the upcoming reconciliation alert |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request PUT --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" --header "Content-Type: application/json" \
|
||||||
|
--data '{"upcoming_reconciliations": [{"next_reconciliation_date": "12 Jun 2021", "display_alert_from": "05 Jun 2021"}]}' \
|
||||||
|
"https://gitlab.com/api/v4/internal/gitlab_subscriptions/129/upcoming_reconciliations"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
200
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Delete an upcoming reconciliation
|
||||||
|
|
||||||
|
Use a DELETE command to delete an `upcoming_reconciliation`.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
DELETE /internal/gitlab_subscriptions/namespaces/:namespace_id/upcoming_reconciliations
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request DELETE \
|
||||||
|
--url "http://localhost:3000/api/v4/internal/gitlab_subscriptions/namespaces/22/upcoming_reconciliations" \
|
||||||
|
--header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
204
|
||||||
|
```
|
||||||
|
|
||||||
|
### Users
|
||||||
|
|
||||||
|
#### Retrieve a user
|
||||||
|
|
||||||
|
Use a GET command to get the User object based on user ID.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /internal/gitlab_subscriptions/users/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/users/:id"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"username": "john_smith",
|
||||||
|
"name": "John Smith",
|
||||||
|
"web_url": "http://localhost:3000/john_smith"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Fetch user permissions in a namespace
|
||||||
|
|
||||||
|
Use a GET command to fetch the permissions a user has in a namespace.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /internal/gitlab_subscriptions/namespaces/:namespace_id/user_permissions/:user_id
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/:namespace_id/user_permissions/:user_id"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"edit_billing": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Update credit card validation
|
||||||
|
|
||||||
|
Use a PUT command to update the User's credit card validation
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
PUT /internal/gitlab_subscriptions/users/:user_id/credit_card_validation
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request PUT --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" \
|
||||||
|
--data '{"credit_card_validated_at": "2020-01-01 00:00:00 UTC", "credit_card_expiration_year": "2010", "credit_card_expiration_month": "12", "credit_card_holder_name": "John Smith", "credit_card_type": "American Express", "credit_card_mask_number": "1111", "zuora_payment_method_xid": "abc123", "stripe_setup_intent_xid": "seti_abc123", "stripe_payment_method_xid": "pm_abc123", "stripe_card_fingerprint": "card123"}' \
|
||||||
|
"https://gitlab.com/api/v4/internal/gitlab_subscriptions/users/:user_id/credit_card_validation"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migrating Endpoints
|
||||||
|
|
||||||
|
These endpoints are going to be [migrated to internal endpoints](https://gitlab.com/gitlab-org/gitlab/-/issues/463741). After that, they will be
|
||||||
|
deprecated and then [removed in a future milestone](https://gitlab.com/gitlab-org/gitlab/-/issues/473625).
|
||||||
|
|
||||||
|
### Add-On Purchases
|
||||||
|
|
||||||
|
This API is used by CustomersDot to manage add-on purchases, excluding Compute Minutes
|
||||||
|
and Storage packs.
|
||||||
|
|
||||||
|
#### Create a subscription add-on purchase
|
||||||
|
|
||||||
|
Use a POST command to create a subscription add-on purchase.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
POST /namespaces/:id/subscription_add_on_purchase/:add_on_name
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:------------|:--------|:---------|:------------|
|
||||||
|
| `quantity` | integer | yes | Amount of units in the subscription add-on purchase (Example: Number of seats for a Code Suggestions add-on) |
|
||||||
|
| `started_on` | date | yes | Date the subscription add-on purchase became available |
|
||||||
|
| `expires_on` | date | yes | Expiration date of the subscription add-on purchase |
|
||||||
|
| `purchase_xid` | string | yes | Identifier for the subscription add-on purchase (Example: Subscription name for a Code Suggestions add-on) |
|
||||||
|
| `trial` | boolean | no | Whether the add-on is a trial |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request POST --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/namespaces/1234/subscription_add_on_purchase/code_suggestions?&quantity=10&started_on="2024-06-15"&expires_on="2024-07-15"&purchase_xid="A-S12345678"&trial=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"namespace_id":1234,
|
||||||
|
"namespace_name":"A Namespace Name",
|
||||||
|
"add_on":"Code Suggestions",
|
||||||
|
"quantity":10,
|
||||||
|
"started_on":"2024-06-15",
|
||||||
|
"expires_on":"2024-07-15",
|
||||||
|
"purchase_xid":"A-S12345678",
|
||||||
|
"trial":true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Update a subscription add-on purchase
|
||||||
|
|
||||||
|
Use a PUT command to update an existing subscription add-on purchase.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
PUT /namespaces/:id/subscription_add_on_purchase/:add_on_name
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:------------|:--------|:---------|:------------|
|
||||||
|
| `quantity` | integer | no | Amount of units in the subscription add-on purchase (Example: Number of seats for a Code Suggestions add-on) |
|
||||||
|
| `started_on` | date | yes | Date the subscription add-on purchase became available |
|
||||||
|
| `expires_on` | date | yes | Expiration date of the subscription add-on purchase |
|
||||||
|
| `purchase_xid` | string | no | Identifier for the subscription add-on purchase (Example: Subscription name for a Code Suggestions add-on) |
|
||||||
|
| `trial` | boolean | no | Whether the add-on is a trial |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request PUT --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/namespaces/1234/subscription_add_on_purchase/code_suggestions?&quantity=15&started_on="2024-06-15"&expires_on="2024-07-15"&purchase_xid="A-S12345678"&trial=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"namespace_id":1234,
|
||||||
|
"namespace_name":"A Namespace Name",
|
||||||
|
"add_on":"Code Suggestions",
|
||||||
|
"quantity":15,
|
||||||
|
"started_on":"2024-06-15",
|
||||||
|
"expires_on":"2024-07-15",
|
||||||
|
"purchase_xid":"A-S12345678",
|
||||||
|
"trial":true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Fetch a subscription add-on purchases
|
||||||
|
|
||||||
|
Use a GET command to view an existing subscription add-on purchase.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /namespaces/:id/subscription_add_on_purchase/:add_on_name
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/namespaces/1234/subscription_add_on_purchase/code_suggestions"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"namespace_id":1234,
|
||||||
|
"namespace_name":"A Namespace Name",
|
||||||
|
"add_on":"Code Suggestions",
|
||||||
|
"quantity":15,
|
||||||
|
"started_on":"2024-06-15",
|
||||||
|
"expires_on":"2024-07-15",
|
||||||
|
"purchase_xid":"A-S12345678",
|
||||||
|
"trial":true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compute quota provisioning
|
||||||
|
|
||||||
|
> - [Renamed](https://gitlab.com/groups/gitlab-com/-/epics/2150) from "CI/CD minutes" to "compute quota" and "compute minutes" in GitLab 16.1.
|
||||||
|
|
||||||
|
The compute quota endpoints are used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
|
||||||
|
to apply additional packs of compute minutes, for personal namespaces or top-level groups in GitLab.com.
|
||||||
|
|
||||||
|
#### Create an additional pack
|
||||||
|
|
||||||
|
Use a POST command to create additional packs.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
POST /namespaces/:id/minutes
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:------------|:--------|:---------|:------------|
|
||||||
|
| `packs` | array | yes | An array of purchased compute packs |
|
||||||
|
| `packs[expires_at]` | date | yes | Expiry date of the purchased pack|
|
||||||
|
| `packs[number_of_minutes]` | integer | yes | Number of additional compute minutes |
|
||||||
|
| `packs[purchase_xid]` | string | yes | The unique ID of the purchase |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request POST \
|
||||||
|
--url "http://localhost:3000/api/v4/namespaces/123/minutes" \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--header 'X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>' \
|
||||||
|
--data '{
|
||||||
|
"packs": [
|
||||||
|
{
|
||||||
|
"number_of_minutes": 10000,
|
||||||
|
"expires_at": "2022-01-01",
|
||||||
|
"purchase_xid": "46952fe69bebc1a4de10b2b4ff439d0c"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"namespace_id": 123,
|
||||||
|
"expires_at": "2022-01-01",
|
||||||
|
"number_of_minutes": 10000,
|
||||||
|
"purchase_xid": "46952fe69bebc1a4de10b2b4ff439d0c"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Move additional packs
|
||||||
|
|
||||||
|
Use a `PATCH` command to move additional packs from one namespace to another.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
PATCH /namespaces/:id/minutes/move/:target_id
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:------------|:--------|:---------|:------------|
|
||||||
|
| `id` | string | yes | The ID of the namespace to transfer packs from |
|
||||||
|
| `target_id` | string | yes | The ID of the target namespace to transfer the packs to |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request PATCH \
|
||||||
|
--url "http://localhost:3000/api/v4/namespaces/123/minutes/move/321" \
|
||||||
|
--header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "202 Accepted"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Subscriptions (being migrated)
|
||||||
|
|
||||||
|
The subscription endpoints are used by
|
||||||
|
[CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`) to
|
||||||
|
apply subscriptions (including trials) to personal namespaces, or top-level groups on GitLab.com.
|
||||||
|
|
||||||
|
#### Create a subscription
|
||||||
|
|
||||||
|
Use a POST command to create a subscription.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
POST /namespaces/:id/gitlab_subscription
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:------------|:--------|:---------|:------------|
|
||||||
|
| `start_date` | date | yes | Start date of subscription |
|
||||||
|
| `end_date` | date | no | End date of subscription |
|
||||||
|
| `plan_code` | string | no | Subscription tier code |
|
||||||
|
| `seats` | integer | no | Number of seats in subscription |
|
||||||
|
| `max_seats_used` | integer | no | Highest number of active users in the last month |
|
||||||
|
| `auto_renew` | boolean | no | Whether subscription auto-renews on end date |
|
||||||
|
| `trial` | boolean | no | Whether subscription is a trial |
|
||||||
|
| `trial_starts_on` | date | no | Start date of trial |
|
||||||
|
| `trial_ends_on` | date | no | End date of trial |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request POST --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/namespaces/1234/gitlab_subscription?start_date="2020-07-15"&plan="premium"&seats=10"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"plan": {
|
||||||
|
"code":"premium",
|
||||||
|
"name":"premium",
|
||||||
|
"trial":false,
|
||||||
|
"auto_renew":null,
|
||||||
|
"upgradable":false
|
||||||
|
},
|
||||||
|
"usage": {
|
||||||
|
"seats_in_subscription":10,
|
||||||
|
"seats_in_use":1,
|
||||||
|
"max_seats_used":0,
|
||||||
|
"seats_owed":0
|
||||||
|
},
|
||||||
|
"billing": {
|
||||||
|
"subscription_start_date":"2020-07-15",
|
||||||
|
"subscription_end_date":null,
|
||||||
|
"trial_ends_on":null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Update a subscription
|
||||||
|
|
||||||
|
Use a PUT command to update an existing subscription.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
PUT /namespaces/:id/gitlab_subscription
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:------------|:--------|:---------|:------------|
|
||||||
|
| `start_date` | date | no | Start date of subscription |
|
||||||
|
| `end_date` | date | no | End date of subscription |
|
||||||
|
| `plan_code` | string | no | Subscription tier code |
|
||||||
|
| `seats` | integer | no | Number of seats in subscription |
|
||||||
|
| `max_seats_used` | integer | no | Highest number of active users in the last month |
|
||||||
|
| `auto_renew` | boolean | no | Whether subscription auto-renews on end date |
|
||||||
|
| `trial` | boolean | no | Whether subscription is a trial |
|
||||||
|
| `trial_starts_on` | date | no | Start date of trial. Required if trial is true. |
|
||||||
|
| `trial_ends_on` | date | no | End date of trial |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request PUT --header "X-CUSTOMERS-DOT-INTERNAL-TOKEN: <json-web-token>" "https://gitlab.com/api/v4/namespaces/1234/gitlab_subscription?max_seats_used=0"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"plan": {
|
||||||
|
"code":"premium",
|
||||||
|
"name":"premium",
|
||||||
|
"trial":false,
|
||||||
|
"auto_renew":null,
|
||||||
|
"upgradable":false
|
||||||
|
},
|
||||||
|
"usage": {
|
||||||
|
"seats_in_subscription":80,
|
||||||
|
"seats_in_use":82,
|
||||||
|
"max_seats_used":0,
|
||||||
|
"seats_owed":2
|
||||||
|
},
|
||||||
|
"billing": {
|
||||||
|
"subscription_start_date":"2020-07-15",
|
||||||
|
"subscription_end_date":"2021-07-15",
|
||||||
|
"trial_ends_on":null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deprecated Endpoints
|
||||||
|
|
||||||
|
These endpoints are no longer being used by CustomersDot as an internal version of these endpoints
|
||||||
|
has already been created. They will be [removed in a future milestone](https://gitlab.com/gitlab-org/gitlab/-/issues/473625).
|
||||||
|
|
||||||
|
### Subscriptions (deprecated)
|
||||||
|
|
||||||
|
These endpoints have been replaced with the ones in the [Internal Subscriptions API](#subscriptions).
|
||||||
|
|
||||||
|
#### Fetch a subscription (namespaces API)
|
||||||
|
|
||||||
|
Use a GET command to view an existing subscription.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /namespaces/:id/gitlab_subscription
|
||||||
|
```
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --header "TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/namespaces/1234/gitlab_subscription"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"plan": {
|
||||||
|
"code":"premium",
|
||||||
|
"name":"premium",
|
||||||
|
"trial":false,
|
||||||
|
"auto_renew":null,
|
||||||
|
"upgradable":false,
|
||||||
|
"exclude_guests":false
|
||||||
|
},
|
||||||
|
"usage": {
|
||||||
|
"seats_in_subscription":80,
|
||||||
|
"seats_in_use":82,
|
||||||
|
"max_seats_used":82,
|
||||||
|
"seats_owed":2
|
||||||
|
},
|
||||||
|
"billing": {
|
||||||
|
"subscription_start_date":"2020-07-15",
|
||||||
|
"subscription_end_date":"2021-07-15",
|
||||||
|
"trial_ends_on":null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Upcoming Reconciliations (deprecated)
|
||||||
|
|
||||||
|
These endpoints have been replaced with the ones in the [Internal Upcoming Reconciliations API](#upcoming-reconciliations).
|
||||||
|
|
||||||
|
### Update `upcoming_reconciliations`
|
||||||
|
|
||||||
|
Use a PUT command to update `upcoming_reconciliations`.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
PUT /internal/upcoming_reconciliations
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:-------------------|:-----------|:---------|:------------|
|
||||||
|
| `upcoming_reconciliations` | array | yes | Array of upcoming reconciliations |
|
||||||
|
|
||||||
|
Each array element contains:
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:-------------------|:-----------|:---------|:------------|
|
||||||
|
| `namespace_id` | integer | yes | ID of the namespace to be reconciled |
|
||||||
|
| `next_reconciliation_date` | date | yes | Date of the next reconciliation |
|
||||||
|
| `display_alert_from` | date | yes | Start date to display alert of upcoming reconciliation |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request PUT --header "PRIVATE-TOKEN: <admin_access_token>" --header "Content-Type: application/json" \
|
||||||
|
--data '{"upcoming_reconciliations": [{"namespace_id": 127, "next_reconciliation_date": "13 Jun 2021", "display_alert_from": "06 Jun 2021"}, {"namespace_id": 129, "next_reconciliation_date": "12 Jun 2021", "display_alert_from": "05 Jun 2021"}]}' \
|
||||||
|
"https://gitlab.com/api/v4/internal/upcoming_reconciliations"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
200
|
||||||
|
```
|
||||||
|
|
||||||
|
### Delete an `upcoming_reconciliation`
|
||||||
|
|
||||||
|
Use a DELETE command to delete an `upcoming_reconciliation`.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
DELETE /internal/upcoming_reconciliations
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
|:---------------|:--------|:---------|:----------------------------------------------------------------------------------|
|
||||||
|
| `namespace_id` | integer | yes | The ID of the GitLab.com namespace that no longer has an upcoming reconciliation. |
|
||||||
|
|
||||||
|
Example request:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --request DELETE \
|
||||||
|
--url "http://localhost:3000/api/v4/internal/upcoming_reconciliations?namespace_id=22" \
|
||||||
|
--header 'PRIVATE-TOKEN: <admin_access_token>'
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
204
|
||||||
|
```
|
|
@ -13,6 +13,8 @@ working on the GitLab codebase.
|
||||||
This documentation does not yet include the internal API used by
|
This documentation does not yet include the internal API used by
|
||||||
GitLab Pages.
|
GitLab Pages.
|
||||||
|
|
||||||
|
For information on the GitLab Subscriptions internal API, see [the dedicated page](gitlab_subscriptions.md).
|
||||||
|
|
||||||
## Add new endpoints
|
## Add new endpoints
|
||||||
|
|
||||||
API endpoints should be externally accessible by default, with proper authentication and authorization.
|
API endpoints should be externally accessible by default, with proper authentication and authorization.
|
||||||
|
@ -738,404 +740,6 @@ Example response:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Subscriptions
|
|
||||||
|
|
||||||
The subscriptions endpoint is used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`) to apply subscriptions including trials, and add-on purchases, for personal namespaces, or top-level groups in GitLab.com.
|
|
||||||
|
|
||||||
### Create a subscription
|
|
||||||
|
|
||||||
Use a POST command to create a subscription.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
POST /namespaces/:id/gitlab_subscription
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:------------|:--------|:---------|:------------|
|
|
||||||
| `start_date` | date | yes | Start date of subscription |
|
|
||||||
| `end_date` | date | no | End date of subscription |
|
|
||||||
| `plan_code` | string | no | Subscription tier code |
|
|
||||||
| `seats` | integer | no | Number of seats in subscription |
|
|
||||||
| `max_seats_used` | integer | no | Highest number of active users in the last month |
|
|
||||||
| `auto_renew` | boolean | no | Whether subscription auto-renews on end date |
|
|
||||||
| `trial` | boolean | no | Whether subscription is a trial |
|
|
||||||
| `trial_starts_on` | date | no | Start date of trial |
|
|
||||||
| `trial_ends_on` | date | no | End date of trial |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request POST --header "TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/namespaces/1234/gitlab_subscription?start_date="2020-07-15"&plan="premium"&seats=10"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"plan": {
|
|
||||||
"code":"premium",
|
|
||||||
"name":"premium",
|
|
||||||
"trial":false,
|
|
||||||
"auto_renew":null,
|
|
||||||
"upgradable":false,
|
|
||||||
},
|
|
||||||
"usage": {
|
|
||||||
"seats_in_subscription":10,
|
|
||||||
"seats_in_use":1,
|
|
||||||
"max_seats_used":0,
|
|
||||||
"seats_owed":0
|
|
||||||
},
|
|
||||||
"billing": {
|
|
||||||
"subscription_start_date":"2020-07-15",
|
|
||||||
"subscription_end_date":null,
|
|
||||||
"trial_ends_on":null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Update a subscription
|
|
||||||
|
|
||||||
Use a PUT command to update an existing subscription.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
PUT /namespaces/:id/gitlab_subscription
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:------------|:--------|:---------|:------------|
|
|
||||||
| `start_date` | date | no | Start date of subscription |
|
|
||||||
| `end_date` | date | no | End date of subscription |
|
|
||||||
| `plan_code` | string | no | Subscription tier code |
|
|
||||||
| `seats` | integer | no | Number of seats in subscription |
|
|
||||||
| `max_seats_used` | integer | no | Highest number of active users in the last month |
|
|
||||||
| `auto_renew` | boolean | no | Whether subscription auto-renews on end date |
|
|
||||||
| `trial` | boolean | no | Whether subscription is a trial |
|
|
||||||
| `trial_starts_on` | date | no | Start date of trial. Required if trial is true. |
|
|
||||||
| `trial_ends_on` | date | no | End date of trial |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request PUT --header "TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/namespaces/1234/gitlab_subscription?max_seats_used=0"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"plan": {
|
|
||||||
"code":"premium",
|
|
||||||
"name":"premium",
|
|
||||||
"trial":false,
|
|
||||||
"auto_renew":null,
|
|
||||||
"upgradable":false,
|
|
||||||
},
|
|
||||||
"usage": {
|
|
||||||
"seats_in_subscription":80,
|
|
||||||
"seats_in_use":82,
|
|
||||||
"max_seats_used":0,
|
|
||||||
"seats_owed":2
|
|
||||||
},
|
|
||||||
"billing": {
|
|
||||||
"subscription_start_date":"2020-07-15",
|
|
||||||
"subscription_end_date":"2021-07-15",
|
|
||||||
"trial_ends_on":null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Retrieve a subscription (internal API)
|
|
||||||
|
|
||||||
Use a GET command to view an existing subscription. Requests from CustomersDot are being migrated to this endpoint.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
GET /internal/gitlab_subscriptions/namespaces/:id/gitlab_subscription
|
|
||||||
```
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --header "TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1234/gitlab_subscription"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"plan": {
|
|
||||||
"code": "premium",
|
|
||||||
"name": "premium",
|
|
||||||
"trial": false,
|
|
||||||
"auto_renew": null,
|
|
||||||
"upgradable": false,
|
|
||||||
"exclude_guests": false
|
|
||||||
},
|
|
||||||
"usage": {
|
|
||||||
"seats_in_subscription": 80,
|
|
||||||
"seats_in_use": 82,
|
|
||||||
"max_seats_used": 82,
|
|
||||||
"seats_owed": 2
|
|
||||||
},
|
|
||||||
"billing": {
|
|
||||||
"subscription_start_date": "2020-07-15",
|
|
||||||
"subscription_end_date": "2021-07-15",
|
|
||||||
"trial_ends_on": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
### Retrieve owners
|
|
||||||
|
|
||||||
Use a GET command to get direct owners of the namespace. Requests from CustomersDot are being migrated to this endpoint.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
GET /internal/gitlab_subscriptions/namespaces/:id/owners
|
|
||||||
```
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --header "TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1234/owners"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"user": {
|
|
||||||
"id": 1,
|
|
||||||
"username": "john_smith",
|
|
||||||
"name": "John Smith"
|
|
||||||
},
|
|
||||||
"access_level": 50,
|
|
||||||
"notification_email": "name@example.com",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
### Retrieve a subscription (namespaces API)
|
|
||||||
|
|
||||||
Use a GET command to view an existing subscription.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
GET /namespaces/:id/gitlab_subscription
|
|
||||||
```
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --header "TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/namespaces/1234/gitlab_subscription"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"plan": {
|
|
||||||
"code":"premium",
|
|
||||||
"name":"premium",
|
|
||||||
"trial":false,
|
|
||||||
"auto_renew":null,
|
|
||||||
"upgradable":false,
|
|
||||||
"exclude_guests":false,
|
|
||||||
},
|
|
||||||
"usage": {
|
|
||||||
"seats_in_subscription":80,
|
|
||||||
"seats_in_use":82,
|
|
||||||
"max_seats_used":82,
|
|
||||||
"seats_owed":2
|
|
||||||
},
|
|
||||||
"billing": {
|
|
||||||
"subscription_start_date":"2020-07-15",
|
|
||||||
"subscription_end_date":"2021-07-15",
|
|
||||||
"trial_ends_on":null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot (deprecated - [being removed](https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/9773))
|
|
||||||
|
|
||||||
## Subscription add-on purchases (excluding storage and compute packs)
|
|
||||||
|
|
||||||
The subscription add-on purchase endpoint is used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`) to apply subscription add-on purchases like Code Suggestions for personal namespaces, or top-level groups in GitLab.com. It is not used to apply storage and compute pack purchases.
|
|
||||||
|
|
||||||
### Create a subscription add-on purchase
|
|
||||||
|
|
||||||
Use a POST command to create a subscription add-on purchase.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
POST /namespaces/:id/subscription_add_on_purchase/:add_on_name
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:------------|:--------|:---------|:------------|
|
|
||||||
| `quantity` | integer | yes | Amount of units in the subscription add-on purchase (Example: Number of seats for a Code Suggestions add-on) |
|
|
||||||
| `started_on` | date | yes | Date the subscription add-on purchase became available |
|
|
||||||
| `expires_on` | date | yes | Expiration date of the subscription add-on purchase |
|
|
||||||
| `purchase_xid` | string | yes | Identifier for the subscription add-on purchase (Example: Subscription name for a Code Suggestions add-on) |
|
|
||||||
| `trial` | boolean | no | Whether the add-on is a trial |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request POST --header "PRIVATE-TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/namespaces/1234/subscription_add_on_purchase/code_suggestions?&quantity=10&started_on="2024-06-15"&expires_on="2024-07-15"&purchase_xid="A-S12345678"&trial=true"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"namespace_id":1234,
|
|
||||||
"namespace_name":"A Namespace Name",
|
|
||||||
"add_on":"Code Suggestions",
|
|
||||||
"quantity":10,
|
|
||||||
"started_on":"2024-06-15",
|
|
||||||
"expires_on":"2024-07-15",
|
|
||||||
"purchase_xid":"A-S12345678",
|
|
||||||
"trial":true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Update a subscription add-on purchases
|
|
||||||
|
|
||||||
Use a PUT command to update an existing subscription add-on purchase.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
PUT /namespaces/:id/subscription_add_on_purchase/:add_on_name
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:------------|:--------|:---------|:------------|
|
|
||||||
| `quantity` | integer | no | Amount of units in the subscription add-on purchase (Example: Number of seats for a Code Suggestions add-on) |
|
|
||||||
| `started_on` | date | yes | Date the subscription add-on purchase became available |
|
|
||||||
| `expires_on` | date | yes | Expiration date of the subscription add-on purchase |
|
|
||||||
| `purchase_xid` | string | no | Identifier for the subscription add-on purchase (Example: Subscription name for a Code Suggestions add-on) |
|
|
||||||
| `trial` | boolean | no | Whether the add-on is a trial |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request PUT --header "PRIVATE-TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/namespaces/1234/subscription_add_on_purchase/code_suggestions?&quantity=15&started_on="2024-06-15"&expires_on="2024-07-15"&purchase_xid="A-S12345678"&trial=true"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"namespace_id":1234,
|
|
||||||
"namespace_name":"A Namespace Name",
|
|
||||||
"add_on":"Code Suggestions",
|
|
||||||
"quantity":15,
|
|
||||||
"started_on":"2024-06-15",
|
|
||||||
"expires_on":"2024-07-15",
|
|
||||||
"purchase_xid":"A-S12345678",
|
|
||||||
"trial":true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Retrieve a subscription add-on purchases
|
|
||||||
|
|
||||||
Use a GET command to view an existing subscription add-on purchase.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
GET /namespaces/:id/subscription_add_on_purchase/:add_on_name
|
|
||||||
```
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --header "PRIVATE-TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/namespaces/1234/subscription_add_on_purchase/code_suggestions"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"namespace_id":1234,
|
|
||||||
"namespace_name":"A Namespace Name",
|
|
||||||
"add_on":"Code Suggestions",
|
|
||||||
"quantity":15,
|
|
||||||
"started_on":"2024-06-15",
|
|
||||||
"expires_on":"2024-07-15",
|
|
||||||
"purchase_xid":"A-S12345678",
|
|
||||||
"trial":true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
## Users
|
|
||||||
|
|
||||||
### Retrieve a user (internal API)
|
|
||||||
|
|
||||||
Use a GET command to get the User object based on user ID.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
GET /internal/gitlab_subscriptions/users/:id
|
|
||||||
```
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --header "PRIVATE-TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/users/:id"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"username": "john_smith",
|
|
||||||
"name": "John Smith",
|
|
||||||
"web_url": "http://localhost:3000/john_smith"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
### Update Credit Card Validation (internal API)
|
|
||||||
|
|
||||||
Use a PUT command to update the User's credit card validation
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
PUT /internal/gitlab_subscriptions/users/:user_id/credit_card_validation
|
|
||||||
```
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request PUT --header "PRIVATE-TOKEN: <admin_access_token>" \
|
|
||||||
--data '{"credit_card_validated_at": "2020-01-01 00:00:00 UTC", "credit_card_expiration_year": "2010", "credit_card_expiration_month": "12", "credit_card_holder_name": "John Smith", "credit_card_type": "American Express", "credit_card_mask_number": "1111", "zuora_payment_method_xid": "abc123", "stripe_setup_intent_xid": "seti_abc123", "stripe_payment_method_xid": "pm_abc123", "stripe_card_fingerprint": "card123"}' \
|
|
||||||
"https://gitlab.com/api/v4/internal/gitlab_subscriptions/users/:user_id/credit_card_validation"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
## Storage limit exclusions
|
## Storage limit exclusions
|
||||||
|
|
||||||
The namespace storage limit exclusion endpoints manage storage limit exclusions on top-level namespaces on GitLab.com.
|
The namespace storage limit exclusion endpoints manage storage limit exclusions on top-level namespaces on GitLab.com.
|
||||||
|
@ -1237,222 +841,6 @@ Example response:
|
||||||
|
|
||||||
- GitLab.com **Admin** area
|
- GitLab.com **Admin** area
|
||||||
|
|
||||||
## Compute quota provisioning
|
|
||||||
|
|
||||||
> - [Renamed](https://gitlab.com/groups/gitlab-com/-/epics/2150) from "CI/CD minutes" to "compute quota" and "compute minutes" in GitLab 16.1.
|
|
||||||
|
|
||||||
The compute quota endpoints are used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
|
|
||||||
to apply additional packs of compute minutes, for personal namespaces or top-level groups in GitLab.com.
|
|
||||||
|
|
||||||
### Create an additional pack
|
|
||||||
|
|
||||||
Use a POST command to create additional packs.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
POST /namespaces/:id/minutes
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:------------|:--------|:---------|:------------|
|
|
||||||
| `packs` | array | yes | An array of purchased compute packs |
|
|
||||||
| `packs[expires_at]` | date | yes | Expiry date of the purchased pack|
|
|
||||||
| `packs[number_of_minutes]` | integer | yes | Number of additional compute minutes |
|
|
||||||
| `packs[purchase_xid]` | string | yes | The unique ID of the purchase |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request POST \
|
|
||||||
--url "http://localhost:3000/api/v4/namespaces/123/minutes" \
|
|
||||||
--header 'Content-Type: application/json' \
|
|
||||||
--header 'PRIVATE-TOKEN: <admin access token>' \
|
|
||||||
--data '{
|
|
||||||
"packs": [
|
|
||||||
{
|
|
||||||
"number_of_minutes": 10000,
|
|
||||||
"expires_at": "2022-01-01",
|
|
||||||
"purchase_xid": "46952fe69bebc1a4de10b2b4ff439d0c"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"namespace_id": 123,
|
|
||||||
"expires_at": "2022-01-01",
|
|
||||||
"number_of_minutes": 10000,
|
|
||||||
"purchase_xid": "46952fe69bebc1a4de10b2b4ff439d0c"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Move additional packs
|
|
||||||
|
|
||||||
Use a `PATCH` command to move additional packs from one namespace to another.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
PATCH /namespaces/:id/minutes/move/:target_id
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:------------|:--------|:---------|:------------|
|
|
||||||
| `id` | string | yes | The ID of the namespace to transfer packs from |
|
|
||||||
| `target_id` | string | yes | The ID of the target namespace to transfer the packs to |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request PATCH \
|
|
||||||
--url "http://localhost:3000/api/v4/namespaces/123/minutes/move/321" \
|
|
||||||
--header 'PRIVATE-TOKEN: <admin access token>'
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "202 Accepted"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
## Upcoming reconciliations
|
|
||||||
|
|
||||||
The `upcoming_reconciliations` endpoint is used by [CustomersDot](https://gitlab.com/gitlab-org/customers-gitlab-com) (`customers.gitlab.com`)
|
|
||||||
to update upcoming reconciliations for namespaces.
|
|
||||||
|
|
||||||
### Update `upcoming_reconciliations`
|
|
||||||
|
|
||||||
Use a PUT command to update `upcoming_reconciliations`.
|
|
||||||
|
|
||||||
#### Old API (deprecated)
|
|
||||||
|
|
||||||
For the new API, see **New Update upcoming_reconciliations API** below.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
PUT /internal/upcoming_reconciliations
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:-------------------|:-----------|:---------|:------------|
|
|
||||||
| `upcoming_reconciliations` | array | yes | Array of upcoming reconciliations |
|
|
||||||
|
|
||||||
Each array element contains:
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:-------------------|:-----------|:---------|:------------|
|
|
||||||
| `namespace_id` | integer | yes | ID of the namespace to be reconciled |
|
|
||||||
| `next_reconciliation_date` | date | yes | Date of the next reconciliation |
|
|
||||||
| `display_alert_from` | date | yes | Start date to display alert of upcoming reconciliation |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request PUT --header "PRIVATE-TOKEN: <admin_access_token>" --header "Content-Type: application/json" \
|
|
||||||
--data '{"upcoming_reconciliations": [{"namespace_id": 127, "next_reconciliation_date": "13 Jun 2021", "display_alert_from": "06 Jun 2021"}, {"namespace_id": 129, "next_reconciliation_date": "12 Jun 2021", "display_alert_from": "05 Jun 2021"}]}' \
|
|
||||||
"https://gitlab.com/api/v4/internal/upcoming_reconciliations"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
200
|
|
||||||
```
|
|
||||||
|
|
||||||
#### New Update upcoming_reconciliations API
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
PUT /internal/gitlab_subscriptions/namespaces/:namespace_id/upcoming_reconciliations
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:-------------------|:-----------|:---------|:------------|
|
|
||||||
| `upcoming_reconciliations` | array | yes | Array of upcoming reconciliations |
|
|
||||||
|
|
||||||
Each array element contains:
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:-------------------|:-----------|:---------|:------------|
|
|
||||||
| `next_reconciliation_date` | date | yes | Date of the next reconciliation |
|
|
||||||
| `display_alert_from` | date | yes | Start date to display alert of upcoming reconciliation |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request PUT --header "PRIVATE-TOKEN: <admin_access_token>" --header "Content-Type: application/json" \
|
|
||||||
--data '{"upcoming_reconciliations": [{"next_reconciliation_date": "12 Jun 2021", "display_alert_from": "05 Jun 2021"}]}' \
|
|
||||||
"https://gitlab.com/api/v4/internal/gitlab_subscriptions/129/upcoming_reconciliations"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
200
|
|
||||||
```
|
|
||||||
|
|
||||||
### Delete an `upcoming_reconciliation`
|
|
||||||
|
|
||||||
#### Old API (deprecated)
|
|
||||||
|
|
||||||
Use a DELETE command to delete an `upcoming_reconciliation`.
|
|
||||||
|
|
||||||
For the new API, see **New delete upcoming_reconciliations API** below.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
DELETE /internal/upcoming_reconciliations
|
|
||||||
```
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
|:---------------|:--------|:---------|:----------------------------------------------------------------------------------|
|
|
||||||
| `namespace_id` | integer | yes | The ID of the GitLab.com namespace that no longer has an upcoming reconciliation. |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request DELETE \
|
|
||||||
--url "http://localhost:3000/api/v4/internal/upcoming_reconciliations?namespace_id=22" \
|
|
||||||
--header 'PRIVATE-TOKEN: <admin_access_token>'
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
204
|
|
||||||
```
|
|
||||||
|
|
||||||
#### New delete upcoming_reconciliations API
|
|
||||||
|
|
||||||
Use a DELETE command to delete an `upcoming_reconciliation`.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
DELETE /internal/gitlab_subscriptions/namespaces/:namespace_id/upcoming_reconciliations
|
|
||||||
```
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request DELETE \
|
|
||||||
--url "http://localhost:3000/api/v4/internal/gitlab_subscriptions/namespaces/22/upcoming_reconciliations" \
|
|
||||||
--header 'PRIVATE-TOKEN: <admin_access_token>'
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
204
|
|
||||||
```
|
|
||||||
|
|
||||||
### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
## Group SCIM API
|
## Group SCIM API
|
||||||
|
|
||||||
DETAILS:
|
DETAILS:
|
||||||
|
@ -1965,106 +1353,3 @@ Example:
|
||||||
```json
|
```json
|
||||||
{ "op": "Add", "path": "name.formatted", "value": "New Name" }
|
{ "op": "Add", "path": "name.formatted", "value": "New Name" }
|
||||||
```
|
```
|
||||||
|
|
||||||
## Namespaces
|
|
||||||
|
|
||||||
### Get a namespace by ID
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
GET /internal/gitlab_subscriptions/namespaces/:id
|
|
||||||
```
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
| --------- | -------------- | -------- | ----------- |
|
|
||||||
| `id` | integer/string | yes | ID or [URL-encoded path of the namespace](../../api/rest/index.md#namespaced-path-encoding) |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request GET --header "PRIVATE-TOKEN: <admin_access_token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "group1",
|
|
||||||
"path": "group1",
|
|
||||||
"kind": "group",
|
|
||||||
"full_path": "group1",
|
|
||||||
"parent_id": null,
|
|
||||||
"avatar_url": null,
|
|
||||||
"web_url": "https://gitlab.example.com/groups/group1",
|
|
||||||
"members_count_with_descendants": 2,
|
|
||||||
"billable_members_count": 2,
|
|
||||||
"max_seats_used": 0,
|
|
||||||
"seats_in_use": 0,
|
|
||||||
"plan": "default",
|
|
||||||
"end_date": null,
|
|
||||||
"trial_ends_on": null,
|
|
||||||
"trial": false,
|
|
||||||
"root_repository_size": 100,
|
|
||||||
"projects_count": 3
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
||||||
### Update a namespace
|
|
||||||
|
|
||||||
Use a PUT command to update an existing namespace.
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
PUT /internal/gitlab_subscriptions/namespaces/:id
|
|
||||||
```
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
|
|
||||||
| Attribute | Type | Required | Description |
|
|
||||||
| --------- | -------------- | -------- | ----------- |
|
|
||||||
| `id` | integer/string | yes | ID or [URL-encoded path of the namespace](../../api/rest/index.md#namespaced-path-encoding) |
|
|
||||||
| `shared_runners_minutes_limit` | integer | no | Compute minutes quota |
|
|
||||||
| `extra_shared_runners_minutes_limit` | integer | no | Extra compute minutes |
|
|
||||||
| `additional_purchased_storage_size` | integer | no | Additional storage size |
|
|
||||||
| `additional_purchased_storage_ends_on` | date | no | Additional purchased storage Ends on |
|
|
||||||
| `gitlab_subscription_attributes` | hash | no | Hash object containing GitLab Subscription attributes. Accepts `seats`,`max_seats_used`,`plan_code`,`end_date`,`auto_renew`,`trial`,`trial_ends_on`,`trial_starts_on`,`trial_extension_type` |
|
|
||||||
|
|
||||||
Example request:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.com/api/v4/internal/gitlab_subscriptions/namespaces/1 --data '{"shared_runners_minutes_limit":1000}'"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"name": "group1",
|
|
||||||
"path": "group1",
|
|
||||||
"kind": "group",
|
|
||||||
"full_path": "group1",
|
|
||||||
"parent_id": null,
|
|
||||||
"avatar_url": null,
|
|
||||||
"web_url": "https://gitlab.example.com/groups/group1",
|
|
||||||
"members_count_with_descendants": 2,
|
|
||||||
"billable_members_count": 2,
|
|
||||||
"max_seats_used": 0,
|
|
||||||
"seats_in_use": 0,
|
|
||||||
"plan": "default",
|
|
||||||
"end_date": null,
|
|
||||||
"trial_ends_on": null,
|
|
||||||
"trial": false,
|
|
||||||
"root_repository_size": 100,
|
|
||||||
"projects_count": 3
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Known consumers
|
|
||||||
|
|
||||||
- CustomersDot
|
|
||||||
|
|
|
@ -399,10 +399,7 @@ Your IdP may need additional configuration. For more information, see
|
||||||
|
|
||||||
You can configure GitLab to use multiple SAML IdPs if:
|
You can configure GitLab to use multiple SAML IdPs if:
|
||||||
|
|
||||||
- Each provider has a unique name set that matches a name set in `args`. At least
|
- Each provider has a unique name set that matches a name set in `args`.
|
||||||
one provider must have the name `saml` to mitigate a
|
|
||||||
[known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/366450) in GitLab
|
|
||||||
14.6 and later.
|
|
||||||
- The providers' names are used:
|
- The providers' names are used:
|
||||||
- In OmniAuth configuration for properties based on the provider name. For example,
|
- In OmniAuth configuration for properties based on the provider name. For example,
|
||||||
`allowBypassTwoFactor`, `allowSingleSignOn`, and `syncProfileFromProvider`.
|
`allowBypassTwoFactor`, `allowSingleSignOn`, and `syncProfileFromProvider`.
|
||||||
|
|
|
@ -541,8 +541,13 @@ The amount of storage and transfer for self-managed instances has no application
|
||||||
|
|
||||||
### Subscription data fails to synchronize
|
### Subscription data fails to synchronize
|
||||||
|
|
||||||
If the synchronization job is not working, ensure you allow network traffic from your GitLab
|
Your subscription data might fail to synchronize.
|
||||||
instance to IP addresses `172.64.146.11:443` and `104.18.41.245:443` (`customers.gitlab.com`).
|
|
||||||
|
This issue can occur when network traffic between your GitLab instance and certain
|
||||||
|
IP addresses is not allowed.
|
||||||
|
|
||||||
|
To resolve this issue, allow network traffic from your GitLab instance to IP
|
||||||
|
addresses `172.64.146.11:443` and `104.18.41.245:443` (`customers.gitlab.com`).
|
||||||
|
|
||||||
### Credit card declined
|
### Credit card declined
|
||||||
|
|
||||||
|
@ -554,13 +559,20 @@ If your credit card is declined when purchasing a GitLab subscription, possible
|
||||||
- The transaction exceeds the credit limit.
|
- The transaction exceeds the credit limit.
|
||||||
- The transaction exceeds the credit card's maximum transaction amount.
|
- The transaction exceeds the credit card's maximum transaction amount.
|
||||||
|
|
||||||
Check with your financial institution to confirm if any of these reasons apply. If they don't
|
Check with your financial institution to confirm if any of these reasons apply. If they do not
|
||||||
apply, contact [GitLab Support](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293).
|
apply, contact [GitLab Support](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293).
|
||||||
|
|
||||||
### Error: `Attempt_Exceed_Limitation - Attempt exceed the limitation, refresh page to try again`
|
### Error: `Attempt_Exceed_Limitation`
|
||||||
|
|
||||||
You might get the error `Attempt_Exceed_Limitation - Attempt exceed the limitation, refresh page to try again.` when purchasing a GitLab subscription.
|
You might get the following error when purchasing a GitLab subscription:
|
||||||
|
|
||||||
This issue occurs when the credit card form is re-submitted too quickly within a specific time frame (three submissions within one minute or six submissions within one hour).
|
```plaintext
|
||||||
|
Attempt_Exceed_Limitation - Attempt exceed the limitation, refresh page to try again.
|
||||||
|
```
|
||||||
|
|
||||||
|
This issue occurs when the credit card form is re-submitted either:
|
||||||
|
|
||||||
|
- Three times or more in one minute.
|
||||||
|
- Six times or more in one hour.
|
||||||
|
|
||||||
To resolve this issue, wait a few minutes and try the purchase process again.
|
To resolve this issue, wait a few minutes and try the purchase process again.
|
||||||
|
|
|
@ -104,6 +104,7 @@ DETAILS:
|
||||||
|
|
||||||
- Helps you determine the root cause for a CI/CD job failure by analyzing the logs.
|
- Helps you determine the root cause for a CI/CD job failure by analyzing the logs.
|
||||||
- LLM: Anthropic [Claude 3.5 Sonnet](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet)
|
- LLM: Anthropic [Claude 3.5 Sonnet](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet)
|
||||||
|
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=MLjhVbMjFAY&list=PLFGfElNsQthZGazU1ZdfDpegu0HflunXW)
|
||||||
- [View documentation](../gitlab_duo_chat/examples.md#troubleshoot-failed-cicd-jobs-with-root-cause-analysis).
|
- [View documentation](../gitlab_duo_chat/examples.md#troubleshoot-failed-cicd-jobs-with-root-cause-analysis).
|
||||||
|
|
||||||
### Vulnerability explanation
|
### Vulnerability explanation
|
||||||
|
@ -114,6 +115,7 @@ DETAILS:
|
||||||
|
|
||||||
- Helps you understand vulnerabilities, how they can be exploited, and how to fix them.
|
- Helps you understand vulnerabilities, how they can be exploited, and how to fix them.
|
||||||
- LLM: Anthropic [Claude 3 Haiku](https://docs.anthropic.com/en/docs/about-claude/models#claude-3-a-new-generation-of-ai).
|
- LLM: Anthropic [Claude 3 Haiku](https://docs.anthropic.com/en/docs/about-claude/models#claude-3-a-new-generation-of-ai).
|
||||||
|
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=MMVFvGrmMzw&list=PLFGfElNsQthZGazU1ZdfDpegu0HflunXW)
|
||||||
- [View documentation](../application_security/vulnerabilities/index.md#explaining-a-vulnerability).
|
- [View documentation](../application_security/vulnerabilities/index.md#explaining-a-vulnerability).
|
||||||
|
|
||||||
### AI Impact dashboard
|
### AI Impact dashboard
|
||||||
|
@ -139,6 +141,7 @@ DETAILS:
|
||||||
|
|
||||||
- Helps populate a merge request more quickly by generating a description based on the code changes.
|
- Helps populate a merge request more quickly by generating a description based on the code changes.
|
||||||
- LLM: Vertex AI Codey [`text-bison`](https://console.cloud.google.com/vertex-ai/publishers/google/model-garden/text-bison)
|
- LLM: Vertex AI Codey [`text-bison`](https://console.cloud.google.com/vertex-ai/publishers/google/model-garden/text-bison)
|
||||||
|
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=CKjkVsfyFd8&list=PLFGfElNsQthZGazU1ZdfDpegu0HflunXW)
|
||||||
- [View documentation](../project/merge_requests/duo_in_merge_requests.md#generate-a-description-by-summarizing-code-changes).
|
- [View documentation](../project/merge_requests/duo_in_merge_requests.md#generate-a-description-by-summarizing-code-changes).
|
||||||
|
|
||||||
### Vulnerability resolution
|
### Vulnerability resolution
|
||||||
|
@ -150,6 +153,7 @@ DETAILS:
|
||||||
|
|
||||||
- Help resolve a vulnerability by generating a merge request that addresses it.
|
- Help resolve a vulnerability by generating a merge request that addresses it.
|
||||||
- LLM: Anthropic's [`claude-3.5-sonnet`](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet).
|
- LLM: Anthropic's [`claude-3.5-sonnet`](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet).
|
||||||
|
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=VJmsw_C125E&list=PLFGfElNsQthZGazU1ZdfDpegu0HflunXW)
|
||||||
- [View documentation](../application_security/vulnerabilities/index.md#vulnerability-resolution).
|
- [View documentation](../application_security/vulnerabilities/index.md#vulnerability-resolution).
|
||||||
|
|
||||||
### Discussion summary
|
### Discussion summary
|
||||||
|
|
|
@ -148,7 +148,7 @@ module API
|
||||||
def find_project!(id)
|
def find_project!(id)
|
||||||
project = find_project(id)
|
project = find_project(id)
|
||||||
|
|
||||||
return forbidden! unless authorized_project_scope?(project)
|
return forbidden!("This project's CI/CD job token cannot be used to authenticate with the container registry of a different project.") unless authorized_project_scope?(project)
|
||||||
|
|
||||||
unless can?(current_user, read_project_ability, project)
|
unless can?(current_user, read_project_ability, project)
|
||||||
return unauthorized! if authenticate_non_public?
|
return unauthorized! if authenticate_non_public?
|
||||||
|
|
|
@ -4,7 +4,7 @@ module Gitlab
|
||||||
module Logging
|
module Logging
|
||||||
module CloudflareHelper
|
module CloudflareHelper
|
||||||
CLOUDFLARE_CUSTOM_HEADERS = { 'Cf-Ray' => :cf_ray, 'Cf-Request-Id' => :cf_request_id,
|
CLOUDFLARE_CUSTOM_HEADERS = { 'Cf-Ray' => :cf_ray, 'Cf-Request-Id' => :cf_request_id,
|
||||||
'Cf-IPCountry' => :cf_ipcountry }.freeze
|
'Cf-IPCountry' => :cf_ipcountry, 'Cf-Worker' => :cf_worker }.freeze
|
||||||
|
|
||||||
def store_cloudflare_headers!(payload, request)
|
def store_cloudflare_headers!(payload, request)
|
||||||
CLOUDFLARE_CUSTOM_HEADERS.each do |header, value|
|
CLOUDFLARE_CUSTOM_HEADERS.each do |header, value|
|
||||||
|
@ -15,7 +15,7 @@ module Gitlab
|
||||||
def valid_cloudflare_header?(value)
|
def valid_cloudflare_header?(value)
|
||||||
return false unless value.present?
|
return false unless value.present?
|
||||||
return false if value.length > 64
|
return false if value.length > 64
|
||||||
return false if value.index(/[^[A-Za-z0-9-]]/)
|
return false if value.index(/[^[.A-Za-z0-9-]]/)
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ module QA
|
||||||
context 'when user adds a new file' do
|
context 'when user adds a new file' do
|
||||||
let(:file_name) { 'first_file.txt' }
|
let(:file_name) { 'first_file.txt' }
|
||||||
|
|
||||||
it 'shows successfully added and visible in project',
|
it 'shows successfully added and visible in project', :blocking,
|
||||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/432898' do
|
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/432898' do
|
||||||
Page::Project::WebIDE::VSCode.perform do |ide|
|
Page::Project::WebIDE::VSCode.perform do |ide|
|
||||||
ide.create_new_file(file_name)
|
ide.create_new_file(file_name)
|
||||||
|
|
|
@ -45,7 +45,7 @@ RSpec.describe 'User reverts a merge request', :js, feature_category: :code_revi
|
||||||
expect(page).to have_content('Merge request revert failed:')
|
expect(page).to have_content('Merge request revert failed:')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'reverts a merge request in a new merge request', :sidekiq_might_not_need_inline do
|
it 'reverts a merge request in a new merge request', :sidekiq_might_not_need_inline, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/457549' do
|
||||||
revert_commit(create_merge_request: true)
|
revert_commit(create_merge_request: true)
|
||||||
|
|
||||||
expect(page).to have_content('The merge request has been successfully reverted. You can now submit a merge request to get this change into the original branch.')
|
expect(page).to have_content('The merge request has been successfully reverted. You can now submit a merge request to get this change into the original branch.')
|
||||||
|
|
|
@ -174,6 +174,31 @@ RSpec.describe API::Helpers, feature_category: :shared do
|
||||||
context 'private project' do
|
context 'private project' do
|
||||||
it_behaves_like 'private project without access'
|
it_behaves_like 'private project without access'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'user authenticated with job token' do
|
||||||
|
let_it_be(:job) { create(:ci_build, project: project) }
|
||||||
|
let_it_be(:outside_project) { create(:project) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(helper).to receive(:route_authentication_setting).and_return(job_token_scope: :project)
|
||||||
|
allow(helper).to receive(:initial_current_user).and_return(user)
|
||||||
|
helper.instance_variable_set(:@current_authenticated_job, job)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and requested project is not equal pipeline's project" do
|
||||||
|
it 'returns forbidden' do
|
||||||
|
expect(helper).to receive(:forbidden!).with("This project's CI/CD job token cannot be used to authenticate with the container registry of a different project.")
|
||||||
|
|
||||||
|
helper.find_project!(outside_project.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "and requested project is equal pipeline's project" do
|
||||||
|
it 'finds a project' do
|
||||||
|
expect(helper.find_project!(project.id)).to eq(project)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user is not authenticated' do
|
context 'when user is not authenticated' do
|
||||||
|
|
|
@ -20,7 +20,12 @@ RSpec.describe Gitlab::Logging::CloudflareHelper do
|
||||||
|
|
||||||
context 'with normal headers' do
|
context 'with normal headers' do
|
||||||
let(:headers) do
|
let(:headers) do
|
||||||
{ 'Cf-Ray' => '592f0aa22b3dea38-IAD', 'Cf-Request-Id' => SecureRandom.hex, 'Cf-IPCountry' => 'US' }
|
{
|
||||||
|
'Cf-Ray' => '592f0aa22b3dea38-IAD',
|
||||||
|
'Cf-Request-Id' => SecureRandom.hex,
|
||||||
|
'Cf-IPCountry' => 'US',
|
||||||
|
'Cf-Worker' => 'subdomain.domain.com'
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds Cf-Ray-Id and Cf-Request-Id' do
|
it 'adds Cf-Ray-Id and Cf-Request-Id' do
|
||||||
|
@ -29,6 +34,7 @@ RSpec.describe Gitlab::Logging::CloudflareHelper do
|
||||||
expect(payload[:cf_ray]).to eq(headers['Cf-Ray'])
|
expect(payload[:cf_ray]).to eq(headers['Cf-Ray'])
|
||||||
expect(payload[:cf_request_id]).to eq(headers['Cf-Request-Id'])
|
expect(payload[:cf_request_id]).to eq(headers['Cf-Request-Id'])
|
||||||
expect(payload[:cf_ipcountry]).to eq(headers['Cf-IPCountry'])
|
expect(payload[:cf_ipcountry]).to eq(headers['Cf-IPCountry'])
|
||||||
|
expect(payload[:cf_worker]).to eq(headers['Cf-Worker'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,17 @@ RSpec.describe API::ProjectContainerRepositories, feature_category: :container_r
|
||||||
describe 'GET /projects/:id/registry/repositories' do
|
describe 'GET /projects/:id/registry/repositories' do
|
||||||
let(:url) { "/projects/#{project.id}/registry/repositories" }
|
let(:url) { "/projects/#{project.id}/registry/repositories" }
|
||||||
|
|
||||||
|
context 'using job token' do
|
||||||
|
include_context 'using job token' do
|
||||||
|
context "when requested project is not equal job's project" do
|
||||||
|
let(:url) { "/projects/#{project2.id}/registry/repositories" }
|
||||||
|
|
||||||
|
it_behaves_like 'rejected container repository access',
|
||||||
|
:maintainer, :forbidden, "403 Forbidden - This project's CI/CD job token cannot be used to authenticate with the container registry of a different project."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
['using API user', 'using job token'].each do |context|
|
['using API user', 'using job token'].each do |context|
|
||||||
context context do
|
context context do
|
||||||
include_context context
|
include_context context
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_examples 'rejected container repository access' do |user_type, status|
|
RSpec.shared_examples 'rejected container repository access' do |user_type, status, body_message = nil|
|
||||||
context "for #{user_type}" do
|
context "for #{user_type}" do
|
||||||
let(:api_user) { users[user_type] }
|
let(:api_user) { users[user_type] }
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ RSpec.shared_examples 'rejected container repository access' do |user_type, stat
|
||||||
subject
|
subject
|
||||||
|
|
||||||
expect(response).to have_gitlab_http_status(status)
|
expect(response).to have_gitlab_http_status(status)
|
||||||
|
|
||||||
|
expect(Gitlab::Json.parse(response.body)['message']).to eq(body_message) if body_message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue