API: Add service account routes to the swagger (#52398)

* API: Add service account routes to the swagger
This commit is contained in:
Sofia Papagiannaki 2022-07-19 12:52:51 +03:00 committed by GitHub
parent a0f96ed4e1
commit e6b9ded949
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1772 additions and 69 deletions

View File

@ -115,7 +115,7 @@ Requires basic authentication and that the authenticated user is a Grafana Admin
**Example Response**: **Example Response**:
```http ```http
HTTP/1.1 200 HTTP/1.1 201
Content-Type: application/json Content-Type: application/json
{ {
@ -141,8 +141,8 @@ Content-Type: application/json
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope | | Action | Scope |
| -------------------- | ------------------ | | -------------------- | -------------------- |
| serviceaccounts:read | serviceaccounts:\* | | serviceaccounts:read | serviceaccounts:id:1 |
**Example Request**: **Example Request**:
@ -184,13 +184,13 @@ Content-Type: application/json
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope | | Action | Scope |
| --------------------- | ------------------ | | --------------------- | -------------------- |
| serviceaccounts:write | serviceaccounts:\* | | serviceaccounts:write | serviceaccounts:id:1 |
**Example Request**: **Example Request**:
```http ```http
PUT /api/serviceaccounts/2 HTTP/1.1 PATCH /api/serviceaccounts/2 HTTP/1.1
Accept: application/json Accept: application/json
Content-Type: application/json Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4= Authorization: Basic YWRtaW46YWRtaW4=
@ -236,8 +236,8 @@ Content-Type: application/json
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope | | Action | Scope |
| -------------------- | ------------------ | | -------------------- | -------------------- |
| serviceaccounts:read | serviceaccounts:\* | | serviceaccounts:read | serviceaccounts:id:1 |
**Example Request**: **Example Request**:
@ -278,8 +278,8 @@ Content-Type: application/json
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope | | Action | Scope |
| --------------------- | ------------------ | | --------------------- | -------------------- |
| serviceaccounts:write | serviceaccounts:\* | | serviceaccounts:write | serviceaccounts:id:1 |
**Example Request**: **Example Request**:
@ -319,8 +319,8 @@ Content-Type: application/json
See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation.
| Action | Scope | | Action | Scope |
| --------------------- | ------------------ | | --------------------- | -------------------- |
| serviceaccounts:write | serviceaccounts:\* | | serviceaccounts:write | serviceaccounts:id:1 |
**Example Request**: **Example Request**:

View File

@ -0,0 +1,90 @@
package definitions
import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/serviceaccounts/api"
)
// swagger:route GET /serviceaccounts/{serviceAccountId}/tokens service_accounts listTokens
//
// Get service account tokens
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:read` scope: `global:serviceaccounts:id:1` (single service account)
//
// Requires basic authentication and that the authenticated user is a Grafana Admin.
//
// Responses:
// 200: listTokensResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
// swagger:route POST /serviceaccounts/{serviceAccountId}/tokens service_accounts createToken
//
// Create service account tokens
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)
//
// Responses:
// 200: createTokenResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 409: conflictError
// 500: internalServerError
// swagger:route DELETE /serviceaccounts/{serviceAccountId}/tokens/{tokenId} service_accounts deleteToken
//
// Delete service account tokens
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)
//
// Requires basic authentication and that the authenticated user is a Grafana Admin.
//
// Responses:
// 200: okResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
// swagger:parameters listTokens
type ListTokensParams struct {
// in:path
ServiceAccountId int64 `json:"serviceAccountId"`
}
// swagger:parameters createToken
type CreateTokenParams struct {
// in:path
ServiceAccountId int64 `json:"serviceAccountId"`
// in:body
Body serviceaccounts.AddServiceAccountTokenCommand
}
// swagger:parameters deleteToken
type DeleteTokenParams struct {
// in:path
TokenId int64 `json:"tokenId"`
// in:path
ServiceAccountId int64 `json:"serviceAccountId"`
}
// swagger:response listTokensResponse
type ListTokensResponse struct {
// in:body
Body *api.TokenDTO
}
// swagger:response createTokenResponse
type CreateTokenResponse struct {
// in:body
Body *dtos.NewApiKeyResult
}

View File

@ -0,0 +1,154 @@
package definitions
import "github.com/grafana/grafana/pkg/services/serviceaccounts"
// swagger:route GET /serviceaccounts/search service_accounts searchOrgServiceAccountsWithPaging
//
// Search service accounts with Paging
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:read` scope: `serviceaccounts:*`
//
// Responses:
// 200: searchOrgServiceAccountsWithPagingResponse
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
// swagger:route POST /serviceaccounts service_accounts createServiceAccount
//
// Create service account
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:write` scope: `serviceaccounts:*`
//
// Requires basic authentication and that the authenticated user is a Grafana Admin.
//
// Responses:
// 201: createServiceAccountResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
// swagger:route GET /serviceaccounts/{serviceAccountId} service_accounts retrieveServiceAccount
//
// Get single serviceaccount by Id
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:read` scope: `serviceaccounts:id:1` (single service account)
//
// Responses:
// 200: retrieveServiceAccountResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
// swagger:route PATCH /serviceaccounts/{serviceAccountId} service_accounts updateServiceAccount
//
// Update service account
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)
//
// Responses:
// 200: updateServiceAccountResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
// swagger:route DELETE /serviceaccounts/{serviceAccountId} service_accounts deleteServiceAccount
//
// Delete service account
//
// Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):
// action: `serviceaccounts:delete` scope: `serviceaccounts:id:1` (single service account)
//
// Responses:
// 200: okResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
// swagger:parameters searchOrgServiceAccountsWithPaging
type SearchOrgServiceAccountsWithPagingParams struct {
// in:query
// required:false
Disabled bool `jsson:"disabled"`
// in:query
// required:false
ExpiredTokens bool `json:"expiredTokens"`
// It will return results where the query value is contained in one of the name.
// Query values with spaces need to be URL encoded.
// in:query
// required:false
Query string `json:"query"`
// The default value is 1000.
// in:query
// required:false
PerPage int `json:"perpage"`
// The default value is 1.
// in:query
// required:false
Page int `json:"page"`
}
// swagger:parameters createServiceAccount
type CreateServiceAccountParams struct {
//in:body
Body serviceaccounts.CreateServiceAccountForm
}
// swagger:parameters retrieveServiceAccount
type RetrieveServiceAccountParams struct {
// in:path
ServiceAccountId int64 `json:"serviceAccountId"`
}
// swagger:parameters updateServiceAccount
type UpdateServiceAccountParams struct {
// in:path
ServiceAccountId int64 `json:"serviceAccountId"`
// in:body
Body serviceaccounts.UpdateServiceAccountForm
}
// swagger:parameters deleteServiceAccount
type DeleteServiceAccountParams struct {
// in:path
ServiceAccountId int64 `json:"serviceAccountId"`
}
// swagger:response searchOrgServiceAccountsWithPagingResponse
type SearchOrgServiceAccountsWithPagingResponse struct {
// in:body
Body *serviceaccounts.SearchServiceAccountsResult
}
// swagger:response createServiceAccountResponse
type CreateServiceAccountResponse struct {
// in:body
Body *serviceaccounts.ServiceAccountDTO
}
// swagger:response retrieveServiceAccountResponse
type RetrieveServiceAccountResponse struct {
// in:body
Body *serviceaccounts.ServiceAccountDTO
}
// swagger:response updateServiceAccountResponse
type UpdateServiceAccountResponse struct {
// in:body
Body struct {
Message string `json:"message"`
ID int64 `json:"id"`
Name string `json:"name"`
ServiceAccount *serviceaccounts.ServiceAccountProfileDTO `json:"serviceaccount"`
}
}

View File

@ -83,6 +83,10 @@
{ {
"name": "prometheus", "name": "prometheus",
"description": "Grafana Alerting Prometheus-compatible endpoints" "description": "Grafana Alerting Prometheus-compatible endpoints"
},
{
"name": "service_accounts",
"description": "If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information."
} }
] ]
} }

View File

@ -7,9 +7,13 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol"
) )
// swagger:model
type NewApiKeyResult struct { type NewApiKeyResult struct {
// example: 1
ID int64 `json:"id"` ID int64 `json:"id"`
// example: grafana
Name string `json:"name"` Name string `json:"name"`
// example: glsa_yscW25imSKJIuav8zF37RZmnbiDvB05G_fcaaf58a
Key string `json:"key"` Key string `json:"key"`
} }

View File

@ -20,13 +20,21 @@ const (
ServiceID = "sa" ServiceID = "sa"
) )
// swagger:model
type TokenDTO struct { type TokenDTO struct {
// example: 1
Id int64 `json:"id"` Id int64 `json:"id"`
// example: grafana
Name string `json:"name"` Name string `json:"name"`
// example: 2022-03-23T10:31:02Z
Created *time.Time `json:"created"` Created *time.Time `json:"created"`
// example: 2022-03-23T10:31:02Z
LastUsedAt *time.Time `json:"lastUsedAt"` LastUsedAt *time.Time `json:"lastUsedAt"`
// example: 2022-03-23T10:31:02Z
Expiration *time.Time `json:"expiration"` Expiration *time.Time `json:"expiration"`
// example: 0
SecondsUntilExpiration *float64 `json:"secondsUntilExpiration"` SecondsUntilExpiration *float64 `json:"secondsUntilExpiration"`
// example: false
HasExpired bool `json:"hasExpired"` HasExpired bool `json:"hasExpired"`
} }

View File

@ -25,27 +25,41 @@ type ServiceAccount struct {
Id int64 Id int64
} }
// swagger:model
type CreateServiceAccountForm struct { type CreateServiceAccountForm struct {
// example: grafana
Name string `json:"name" binding:"Required"` Name string `json:"name" binding:"Required"`
// example: Admin
Role *models.RoleType `json:"role"` Role *models.RoleType `json:"role"`
// example: false
IsDisabled *bool `json:"isDisabled"` IsDisabled *bool `json:"isDisabled"`
} }
// swagger:model
type UpdateServiceAccountForm struct { type UpdateServiceAccountForm struct {
Name *string `json:"name"` Name *string `json:"name"`
Role *models.RoleType `json:"role"` Role *models.RoleType `json:"role"`
IsDisabled *bool `json:"isDisabled"` IsDisabled *bool `json:"isDisabled"`
} }
// swagger: model
type ServiceAccountDTO struct { type ServiceAccountDTO struct {
Id int64 `json:"id" xorm:"user_id"` Id int64 `json:"id" xorm:"user_id"`
// example: grafana
Name string `json:"name" xorm:"name"` Name string `json:"name" xorm:"name"`
// example: sa-grafana
Login string `json:"login" xorm:"login"` Login string `json:"login" xorm:"login"`
// example: 1
OrgId int64 `json:"orgId" xorm:"org_id"` OrgId int64 `json:"orgId" xorm:"org_id"`
// example: false
IsDisabled bool `json:"isDisabled" xorm:"is_disabled"` IsDisabled bool `json:"isDisabled" xorm:"is_disabled"`
// example: Viewer
Role string `json:"role" xorm:"role"` Role string `json:"role" xorm:"role"`
// example: 0
Tokens int64 `json:"tokens"` Tokens int64 `json:"tokens"`
// example: /avatar/85ec38023d90823d3e5b43ef35646af9
AvatarUrl string `json:"avatarUrl"` AvatarUrl string `json:"avatarUrl"`
// example: {"serviceaccounts:delete": true, "serviceaccounts:read": true, "serviceaccounts:write": true}
AccessControl map[string]bool `json:"accessControl,omitempty"` AccessControl map[string]bool `json:"accessControl,omitempty"`
} }
@ -57,23 +71,38 @@ type AddServiceAccountTokenCommand struct {
Result *models.ApiKey `json:"-"` Result *models.ApiKey `json:"-"`
} }
// swagger: model
type SearchServiceAccountsResult struct { type SearchServiceAccountsResult struct {
// It can be used for pagination of the user list
// E.g. if totalCount is equal to 100 users and
// the perpage parameter is set to 10 then there are 10 pages of users.
TotalCount int64 `json:"totalCount"` TotalCount int64 `json:"totalCount"`
ServiceAccounts []*ServiceAccountDTO `json:"serviceAccounts"` ServiceAccounts []*ServiceAccountDTO `json:"serviceAccounts"`
Page int `json:"page"` Page int `json:"page"`
PerPage int `json:"perPage"` PerPage int `json:"perPage"`
} }
// swagger:model
type ServiceAccountProfileDTO struct { type ServiceAccountProfileDTO struct {
// example: 2
Id int64 `json:"id" xorm:"user_id"` Id int64 `json:"id" xorm:"user_id"`
// example: test
Name string `json:"name" xorm:"name"` Name string `json:"name" xorm:"name"`
// example: sa-grafana
Login string `json:"login" xorm:"login"` Login string `json:"login" xorm:"login"`
// example: 1
OrgId int64 `json:"orgId" xorm:"org_id"` OrgId int64 `json:"orgId" xorm:"org_id"`
// example: false
IsDisabled bool `json:"isDisabled" xorm:"is_disabled"` IsDisabled bool `json:"isDisabled" xorm:"is_disabled"`
// example: 2022-03-21T14:35:33Z
Created time.Time `json:"createdAt" xorm:"created"` Created time.Time `json:"createdAt" xorm:"created"`
// example: 2022-03-21T14:35:33Z
Updated time.Time `json:"updatedAt" xorm:"updated"` Updated time.Time `json:"updatedAt" xorm:"updated"`
// example: /avatar/8ea890a677d6a223c591a1beea6ea9d2
AvatarUrl string `json:"avatarUrl" xorm:"-"` AvatarUrl string `json:"avatarUrl" xorm:"-"`
// example: Editor
Role string `json:"role" xorm:"role"` Role string `json:"role" xorm:"role"`
// example: []
Teams []string `json:"teams" xorm:"-"` Teams []string `json:"teams" xorm:"-"`
Tokens int64 `json:"tokens,omitempty"` Tokens int64 `json:"tokens,omitempty"`
AccessControl map[string]bool `json:"accessControl,omitempty" xorm:"-"` AccessControl map[string]bool `json:"accessControl,omitempty" xorm:"-"`

View File

@ -119,6 +119,13 @@
"tags": ["access_control", "enterprise"], "tags": ["access_control", "enterprise"],
"summary": "Get all roles.", "summary": "Get all roles.",
"operationId": "getAllRoles", "operationId": "getAllRoles",
"parameters": [
{
"type": "boolean",
"name": "delegatable",
"in": "query"
}
],
"responses": { "responses": {
"200": { "200": {
"$ref": "#/responses/getAllRolesResponse" "$ref": "#/responses/getAllRolesResponse"
@ -142,7 +149,7 @@
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/CreateRoleWithPermissionsCommand" "$ref": "#/definitions/CreateRoleForm"
} }
} }
], ],
@ -233,6 +240,16 @@
"summary": "Delete a custom role.", "summary": "Delete a custom role.",
"operationId": "deleteCustomRole", "operationId": "deleteCustomRole",
"parameters": [ "parameters": [
{
"type": "boolean",
"name": "force",
"in": "query"
},
{
"type": "boolean",
"name": "global",
"in": "query"
},
{ {
"type": "string", "type": "string",
"name": "roleUID", "name": "roleUID",
@ -7073,6 +7090,328 @@
} }
} }
}, },
"/serviceaccounts": {
"post": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:*`\n\nRequires basic authentication and that the authenticated user is a Grafana Admin.",
"tags": ["service_accounts"],
"summary": "Create service account",
"operationId": "createServiceAccount",
"parameters": [
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/CreateServiceAccountForm"
}
}
],
"responses": {
"201": {
"$ref": "#/responses/createServiceAccountResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/search": {
"get": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:read` scope: `serviceaccounts:*`",
"tags": ["service_accounts"],
"summary": "Search service accounts with Paging",
"operationId": "searchOrgServiceAccountsWithPaging",
"parameters": [
{
"type": "boolean",
"name": "Disabled",
"in": "query"
},
{
"type": "boolean",
"name": "expiredTokens",
"in": "query"
},
{
"type": "string",
"description": "It will return results where the query value is contained in one of the name.\nQuery values with spaces need to be URL encoded.",
"name": "query",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "The default value is 1000.",
"name": "perpage",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "The default value is 1.",
"name": "page",
"in": "query"
}
],
"responses": {
"200": {
"$ref": "#/responses/searchOrgServiceAccountsWithPagingResponse"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/{serviceAccountId}": {
"get": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:read` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Get single serviceaccount by Id",
"operationId": "retrieveServiceAccount",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/retrieveServiceAccountResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
},
"delete": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:delete` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Delete service account",
"operationId": "deleteServiceAccount",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/okResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
},
"patch": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Update service account",
"operationId": "updateServiceAccount",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
},
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/UpdateServiceAccountForm"
}
}
],
"responses": {
"200": {
"$ref": "#/responses/updateServiceAccountResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/{serviceAccountId}/tokens": {
"get": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:read` scope: `global:serviceaccounts:id:1` (single service account)\n\nRequires basic authentication and that the authenticated user is a Grafana Admin.",
"tags": ["service_accounts"],
"summary": "Get service account tokens",
"operationId": "listTokens",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/listTokensResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
},
"post": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Create service account tokens",
"operationId": "createToken",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
},
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/AddServiceAccountTokenCommand"
}
}
],
"responses": {
"200": {
"$ref": "#/responses/createTokenResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"409": {
"$ref": "#/responses/conflictError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/{serviceAccountId}/tokens/{tokenId}": {
"delete": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)\n\nRequires basic authentication and that the authenticated user is a Grafana Admin.",
"tags": ["service_accounts"],
"summary": "Delete service account tokens",
"operationId": "deleteToken",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "tokenId",
"in": "path",
"required": true
},
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/okResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/snapshot/shared-options": { "/snapshot/shared-options": {
"get": { "get": {
"tags": ["snapshots"], "tags": ["snapshots"],
@ -7374,16 +7713,15 @@
"operationId": "removeTeamGroupApi", "operationId": "removeTeamGroupApi",
"parameters": [ "parameters": [
{ {
"type": "integer", "type": "string",
"format": "int64", "name": "groupId",
"name": "teamId",
"in": "path", "in": "path",
"required": true "required": true
}, },
{ {
"type": "integer", "type": "integer",
"format": "int64", "format": "int64",
"name": "groupId", "name": "teamId",
"in": "path", "in": "path",
"required": true "required": true
} }
@ -9169,6 +9507,18 @@
} }
} }
}, },
"AddServiceAccountTokenCommand": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"secondsToLive": {
"type": "integer",
"format": "int64"
}
}
},
"AddTeamMemberCommand": { "AddTeamMemberCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10319,7 +10669,7 @@
} }
} }
}, },
"CreateRoleWithPermissionsCommand": { "CreateRoleForm": {
"type": "object", "type": "object",
"properties": { "properties": {
"description": { "description": {
@ -10328,6 +10678,9 @@
"displayName": { "displayName": {
"type": "string" "type": "string"
}, },
"global": {
"type": "boolean"
},
"group": { "group": {
"type": "string" "type": "string"
}, },
@ -10352,6 +10705,24 @@
} }
} }
}, },
"CreateServiceAccountForm": {
"type": "object",
"properties": {
"isDisabled": {
"type": "boolean",
"example": false
},
"name": {
"type": "string",
"example": "grafana"
},
"role": {
"type": "string",
"enum": ["Viewer", "Editor", "Admin"],
"example": "Admin"
}
}
},
"CreateTeamCommand": { "CreateTeamCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10991,6 +11362,83 @@
} }
} }
}, },
"DataSourcePermissionRuleDTO": {
"type": "object",
"properties": {
"builtInRole": {
"type": "string"
},
"created": {
"type": "string",
"format": "date-time"
},
"datasourceId": {
"type": "integer",
"format": "int64"
},
"id": {
"type": "integer",
"format": "int64"
},
"isManaged": {
"type": "boolean"
},
"permission": {
"$ref": "#/definitions/DsPermissionType"
},
"permissionName": {
"type": "string"
},
"team": {
"type": "string"
},
"teamAvatarUrl": {
"type": "string"
},
"teamEmail": {
"type": "string"
},
"teamId": {
"type": "integer",
"format": "int64"
},
"updated": {
"type": "string",
"format": "date-time"
},
"userAvatarUrl": {
"type": "string"
},
"userEmail": {
"type": "string"
},
"userId": {
"type": "integer",
"format": "int64"
},
"userLogin": {
"type": "string"
}
}
},
"DataSourcePermissionsDTO": {
"type": "object",
"properties": {
"datasourceId": {
"type": "integer",
"format": "int64"
},
"enabled": {
"type": "boolean"
},
"permissions": {
"type": "array",
"items": {
"$ref": "#/definitions/DataSourcePermissionRuleDTO"
}
}
}
},
"DateTime": { "DateTime": {
"description": "DateTime is a time but it serializes to ISO8601 format with millis\nIt knows how to read 3 different variations of a RFC3339 date time.\nMost APIs we encounter want either millisecond or second precision times.\nThis just tries to make it worry-free.", "description": "DateTime is a time but it serializes to ISO8601 format with millis\nIt knows how to read 3 different variations of a RFC3339 date time.\nMost APIs we encounter want either millisecond or second precision times.\nThis just tries to make it worry-free.",
"type": "string", "type": "string",
@ -12763,13 +13211,16 @@
"properties": { "properties": {
"id": { "id": {
"type": "integer", "type": "integer",
"format": "int64" "format": "int64",
"example": 1
}, },
"key": { "key": {
"type": "string" "type": "string",
"example": "glsa_yscW25imSKJIuav8zF37RZmnbiDvB05G_fcaaf58a"
}, },
"name": { "name": {
"type": "string" "type": "string",
"example": "grafana"
} }
} }
}, },
@ -14684,6 +15135,31 @@
} }
} }
}, },
"SearchServiceAccountsResult": {
"description": "swagger: model",
"type": "object",
"properties": {
"page": {
"type": "integer",
"format": "int64"
},
"perPage": {
"type": "integer",
"format": "int64"
},
"serviceAccounts": {
"type": "array",
"items": {
"$ref": "#/definitions/ServiceAccountDTO"
}
},
"totalCount": {
"description": "It can be used for pagination of the user list\nE.g. if totalCount is equal to 100 users and\nthe perpage parameter is set to 10 then there are 10 pages of users.",
"type": "integer",
"format": "int64"
}
}
},
"SearchTeamQueryResult": { "SearchTeamQueryResult": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -14738,6 +15214,119 @@
"title": "SecretURL is a URL that must not be revealed on marshaling.", "title": "SecretURL is a URL that must not be revealed on marshaling.",
"$ref": "#/definitions/URL" "$ref": "#/definitions/URL"
}, },
"ServiceAccountDTO": {
"description": "swagger: model",
"type": "object",
"properties": {
"accessControl": {
"type": "object",
"additionalProperties": {
"type": "boolean"
},
"example": {
"serviceaccounts:delete": true,
"serviceaccounts:read": true,
"serviceaccounts:write": true
}
},
"avatarUrl": {
"type": "string",
"example": "/avatar/85ec38023d90823d3e5b43ef35646af9"
},
"id": {
"type": "integer",
"format": "int64"
},
"isDisabled": {
"type": "boolean",
"example": false
},
"login": {
"type": "string",
"example": "sa-grafana"
},
"name": {
"type": "string",
"example": "grafana"
},
"orgId": {
"type": "integer",
"format": "int64",
"example": 1
},
"role": {
"type": "string",
"example": "Viewer"
},
"tokens": {
"type": "integer",
"format": "int64",
"example": 0
}
}
},
"ServiceAccountProfileDTO": {
"type": "object",
"properties": {
"accessControl": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
},
"avatarUrl": {
"type": "string",
"example": "/avatar/8ea890a677d6a223c591a1beea6ea9d2"
},
"createdAt": {
"type": "string",
"format": "date-time",
"example": "2022-03-21T14:35:33Z"
},
"id": {
"type": "integer",
"format": "int64",
"example": 2
},
"isDisabled": {
"type": "boolean",
"example": false
},
"login": {
"type": "string",
"example": "sa-grafana"
},
"name": {
"type": "string",
"example": "test"
},
"orgId": {
"type": "integer",
"format": "int64",
"example": 1
},
"role": {
"type": "string",
"example": "Editor"
},
"teams": {
"type": "array",
"items": {
"type": "string"
},
"example": []
},
"tokens": {
"type": "integer",
"format": "int64"
},
"updatedAt": {
"type": "string",
"format": "date-time",
"example": "2022-03-21T14:35:33Z"
}
}
},
"SetUserRolesCommand": { "SetUserRolesCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -15485,6 +16074,44 @@
} }
} }
}, },
"TokenDTO": {
"type": "object",
"properties": {
"created": {
"type": "string",
"format": "date-time",
"example": "2022-03-23T10:31:02Z"
},
"expiration": {
"type": "string",
"format": "date-time",
"example": "2022-03-23T10:31:02Z"
},
"hasExpired": {
"type": "boolean",
"example": false
},
"id": {
"type": "integer",
"format": "int64",
"example": 1
},
"lastUsedAt": {
"type": "string",
"format": "date-time",
"example": "2022-03-23T10:31:02Z"
},
"name": {
"type": "string",
"example": "grafana"
},
"secondsUntilExpiration": {
"type": "number",
"format": "double",
"example": 0
}
}
},
"TokenStatus": { "TokenStatus": {
"type": "integer", "type": "integer",
"format": "int64" "format": "int64"
@ -15515,8 +16142,9 @@
"type": "string" "type": "string"
}, },
"URL": { "URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"type": "object", "type": "object",
"title": "URL is a custom URL type that allows validation at configuration load time.", "title": "A URL represents a parsed URL (technically, a URI reference).",
"properties": { "properties": {
"ForceQuery": { "ForceQuery": {
"type": "boolean" "type": "boolean"
@ -15870,6 +16498,21 @@
} }
} }
}, },
"UpdateServiceAccountForm": {
"type": "object",
"properties": {
"isDisabled": {
"type": "boolean"
},
"name": {
"type": "string"
},
"role": {
"type": "string",
"enum": ["Viewer", "Editor", "Admin"]
}
}
},
"UpdateTeamCommand": { "UpdateTeamCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -16650,6 +17293,7 @@
} }
}, },
"receiver": { "receiver": {
"description": "Receiver receiver",
"type": "object", "type": "object",
"required": ["name"], "required": ["name"],
"properties": { "properties": {
@ -16859,7 +17503,22 @@
"createReportResponse": { "createReportResponse": {
"description": "", "description": "",
"schema": { "schema": {
"type": "object" "type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"message": {
"type": "string"
}
}
}
},
"createServiceAccountResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/ServiceAccountDTO"
} }
}, },
"createSnapshotResponse": { "createSnapshotResponse": {
@ -16904,6 +17563,12 @@
} }
} }
}, },
"createTokenResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/NewApiKeyResult"
}
},
"createUserResponse": { "createUserResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -17273,7 +17938,7 @@
"getPermissionseResponse": { "getPermissionseResponse": {
"description": "", "description": "",
"schema": { "schema": {
"$ref": "#/definitions/AddPermissionDTO" "$ref": "#/definitions/DataSourcePermissionsDTO"
} }
}, },
"getPlaylistDashboardsResponse": { "getPlaylistDashboardsResponse": {
@ -17491,6 +18156,12 @@
} }
} }
}, },
"listTokensResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/TokenDTO"
}
},
"lookupAlertNotificationChannelsResponse": { "lookupAlertNotificationChannelsResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -17641,6 +18312,12 @@
"$ref": "#/definitions/ActiveUserStats" "$ref": "#/definitions/ActiveUserStats"
} }
}, },
"retrieveServiceAccountResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/ServiceAccountDTO"
}
},
"searchOrgResponse": { "searchOrgResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -17650,6 +18327,12 @@
} }
} }
}, },
"searchOrgServiceAccountsWithPagingResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/SearchServiceAccountsResult"
}
},
"searchPlaylistsResponse": { "searchPlaylistsResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -17727,6 +18410,27 @@
"$ref": "#/definitions/PlaylistDTO" "$ref": "#/definitions/PlaylistDTO"
} }
}, },
"updateServiceAccountResponse": {
"description": "",
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"message": {
"type": "string"
},
"name": {
"type": "string"
},
"serviceaccount": {
"$ref": "#/definitions/ServiceAccountProfileDTO"
}
}
}
},
"userResponse": { "userResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -17836,6 +18540,10 @@
{ {
"description": "Grafana Alerting Prometheus-compatible endpoints", "description": "Grafana Alerting Prometheus-compatible endpoints",
"name": "prometheus" "name": "prometheus"
},
{
"description": "If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information.",
"name": "service_accounts"
} }
] ]
} }

View File

@ -119,6 +119,13 @@
"tags": ["access_control", "enterprise"], "tags": ["access_control", "enterprise"],
"summary": "Get all roles.", "summary": "Get all roles.",
"operationId": "getAllRoles", "operationId": "getAllRoles",
"parameters": [
{
"type": "boolean",
"name": "delegatable",
"in": "query"
}
],
"responses": { "responses": {
"200": { "200": {
"$ref": "#/responses/getAllRolesResponse" "$ref": "#/responses/getAllRolesResponse"
@ -142,7 +149,7 @@
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/CreateRoleWithPermissionsCommand" "$ref": "#/definitions/CreateRoleForm"
} }
} }
], ],
@ -233,6 +240,16 @@
"summary": "Delete a custom role.", "summary": "Delete a custom role.",
"operationId": "deleteCustomRole", "operationId": "deleteCustomRole",
"parameters": [ "parameters": [
{
"type": "boolean",
"name": "force",
"in": "query"
},
{
"type": "boolean",
"name": "global",
"in": "query"
},
{ {
"type": "string", "type": "string",
"name": "roleUID", "name": "roleUID",
@ -7073,6 +7090,328 @@
} }
} }
}, },
"/serviceaccounts": {
"post": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:*`\n\nRequires basic authentication and that the authenticated user is a Grafana Admin.",
"tags": ["service_accounts"],
"summary": "Create service account",
"operationId": "createServiceAccount",
"parameters": [
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/CreateServiceAccountForm"
}
}
],
"responses": {
"201": {
"$ref": "#/responses/createServiceAccountResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/search": {
"get": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:read` scope: `serviceaccounts:*`",
"tags": ["service_accounts"],
"summary": "Search service accounts with Paging",
"operationId": "searchOrgServiceAccountsWithPaging",
"parameters": [
{
"type": "boolean",
"name": "Disabled",
"in": "query"
},
{
"type": "boolean",
"name": "expiredTokens",
"in": "query"
},
{
"type": "string",
"description": "It will return results where the query value is contained in one of the name.\nQuery values with spaces need to be URL encoded.",
"name": "query",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "The default value is 1000.",
"name": "perpage",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "The default value is 1.",
"name": "page",
"in": "query"
}
],
"responses": {
"200": {
"$ref": "#/responses/searchOrgServiceAccountsWithPagingResponse"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/{serviceAccountId}": {
"get": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:read` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Get single serviceaccount by Id",
"operationId": "retrieveServiceAccount",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/retrieveServiceAccountResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
},
"delete": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:delete` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Delete service account",
"operationId": "deleteServiceAccount",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/okResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
},
"patch": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Update service account",
"operationId": "updateServiceAccount",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
},
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/UpdateServiceAccountForm"
}
}
],
"responses": {
"200": {
"$ref": "#/responses/updateServiceAccountResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/{serviceAccountId}/tokens": {
"get": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:read` scope: `global:serviceaccounts:id:1` (single service account)\n\nRequires basic authentication and that the authenticated user is a Grafana Admin.",
"tags": ["service_accounts"],
"summary": "Get service account tokens",
"operationId": "listTokens",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/listTokensResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
},
"post": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)",
"tags": ["service_accounts"],
"summary": "Create service account tokens",
"operationId": "createToken",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
},
{
"name": "Body",
"in": "body",
"schema": {
"$ref": "#/definitions/AddServiceAccountTokenCommand"
}
}
],
"responses": {
"200": {
"$ref": "#/responses/createTokenResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"409": {
"$ref": "#/responses/conflictError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/serviceaccounts/{serviceAccountId}/tokens/{tokenId}": {
"delete": {
"description": "Required permissions (See note in the [introduction](https://grafana.com/docs/grafana/latest/developers/http_api/serviceaccount/#service-account-api) for an explanation):\naction: `serviceaccounts:write` scope: `serviceaccounts:id:1` (single service account)\n\nRequires basic authentication and that the authenticated user is a Grafana Admin.",
"tags": ["service_accounts"],
"summary": "Delete service account tokens",
"operationId": "deleteToken",
"parameters": [
{
"type": "integer",
"format": "int64",
"name": "tokenId",
"in": "path",
"required": true
},
{
"type": "integer",
"format": "int64",
"name": "serviceAccountId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/okResponse"
},
"400": {
"$ref": "#/responses/badRequestError"
},
"401": {
"$ref": "#/responses/unauthorisedError"
},
"403": {
"$ref": "#/responses/forbiddenError"
},
"404": {
"$ref": "#/responses/notFoundError"
},
"500": {
"$ref": "#/responses/internalServerError"
}
}
}
},
"/snapshot/shared-options": { "/snapshot/shared-options": {
"get": { "get": {
"tags": ["snapshots"], "tags": ["snapshots"],
@ -7374,16 +7713,15 @@
"operationId": "removeTeamGroupApi", "operationId": "removeTeamGroupApi",
"parameters": [ "parameters": [
{ {
"type": "integer", "type": "string",
"format": "int64", "name": "groupId",
"name": "teamId",
"in": "path", "in": "path",
"required": true "required": true
}, },
{ {
"type": "integer", "type": "integer",
"format": "int64", "format": "int64",
"name": "groupId", "name": "teamId",
"in": "path", "in": "path",
"required": true "required": true
} }
@ -8585,6 +8923,18 @@
} }
} }
}, },
"AddServiceAccountTokenCommand": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"secondsToLive": {
"type": "integer",
"format": "int64"
}
}
},
"AddTeamMemberCommand": { "AddTeamMemberCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -9427,7 +9777,7 @@
} }
} }
}, },
"CreateRoleWithPermissionsCommand": { "CreateRoleForm": {
"type": "object", "type": "object",
"properties": { "properties": {
"description": { "description": {
@ -9436,6 +9786,9 @@
"displayName": { "displayName": {
"type": "string" "type": "string"
}, },
"global": {
"type": "boolean"
},
"group": { "group": {
"type": "string" "type": "string"
}, },
@ -9460,6 +9813,24 @@
} }
} }
}, },
"CreateServiceAccountForm": {
"type": "object",
"properties": {
"isDisabled": {
"type": "boolean",
"example": false
},
"name": {
"type": "string",
"example": "grafana"
},
"role": {
"type": "string",
"enum": ["Viewer", "Editor", "Admin"],
"example": "Admin"
}
}
},
"CreateTeamCommand": { "CreateTeamCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10099,6 +10470,83 @@
} }
} }
}, },
"DataSourcePermissionRuleDTO": {
"type": "object",
"properties": {
"builtInRole": {
"type": "string"
},
"created": {
"type": "string",
"format": "date-time"
},
"datasourceId": {
"type": "integer",
"format": "int64"
},
"id": {
"type": "integer",
"format": "int64"
},
"isManaged": {
"type": "boolean"
},
"permission": {
"$ref": "#/definitions/DsPermissionType"
},
"permissionName": {
"type": "string"
},
"team": {
"type": "string"
},
"teamAvatarUrl": {
"type": "string"
},
"teamEmail": {
"type": "string"
},
"teamId": {
"type": "integer",
"format": "int64"
},
"updated": {
"type": "string",
"format": "date-time"
},
"userAvatarUrl": {
"type": "string"
},
"userEmail": {
"type": "string"
},
"userId": {
"type": "integer",
"format": "int64"
},
"userLogin": {
"type": "string"
}
}
},
"DataSourcePermissionsDTO": {
"type": "object",
"properties": {
"datasourceId": {
"type": "integer",
"format": "int64"
},
"enabled": {
"type": "boolean"
},
"permissions": {
"type": "array",
"items": {
"$ref": "#/definitions/DataSourcePermissionRuleDTO"
}
}
}
},
"DeleteTokenCommand": { "DeleteTokenCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -11024,13 +11472,16 @@
"properties": { "properties": {
"id": { "id": {
"type": "integer", "type": "integer",
"format": "int64" "format": "int64",
"example": 1
}, },
"key": { "key": {
"type": "string" "type": "string",
"example": "glsa_yscW25imSKJIuav8zF37RZmnbiDvB05G_fcaaf58a"
}, },
"name": { "name": {
"type": "string" "type": "string",
"example": "grafana"
} }
} }
}, },
@ -11963,6 +12414,31 @@
} }
} }
}, },
"SearchServiceAccountsResult": {
"description": "swagger: model",
"type": "object",
"properties": {
"page": {
"type": "integer",
"format": "int64"
},
"perPage": {
"type": "integer",
"format": "int64"
},
"serviceAccounts": {
"type": "array",
"items": {
"$ref": "#/definitions/ServiceAccountDTO"
}
},
"totalCount": {
"description": "It can be used for pagination of the user list\nE.g. if totalCount is equal to 100 users and\nthe perpage parameter is set to 10 then there are 10 pages of users.",
"type": "integer",
"format": "int64"
}
}
},
"SearchTeamQueryResult": { "SearchTeamQueryResult": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -12009,6 +12485,119 @@
} }
} }
}, },
"ServiceAccountDTO": {
"description": "swagger: model",
"type": "object",
"properties": {
"accessControl": {
"type": "object",
"additionalProperties": {
"type": "boolean"
},
"example": {
"serviceaccounts:delete": true,
"serviceaccounts:read": true,
"serviceaccounts:write": true
}
},
"avatarUrl": {
"type": "string",
"example": "/avatar/85ec38023d90823d3e5b43ef35646af9"
},
"id": {
"type": "integer",
"format": "int64"
},
"isDisabled": {
"type": "boolean",
"example": false
},
"login": {
"type": "string",
"example": "sa-grafana"
},
"name": {
"type": "string",
"example": "grafana"
},
"orgId": {
"type": "integer",
"format": "int64",
"example": 1
},
"role": {
"type": "string",
"example": "Viewer"
},
"tokens": {
"type": "integer",
"format": "int64",
"example": 0
}
}
},
"ServiceAccountProfileDTO": {
"type": "object",
"properties": {
"accessControl": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
},
"avatarUrl": {
"type": "string",
"example": "/avatar/8ea890a677d6a223c591a1beea6ea9d2"
},
"createdAt": {
"type": "string",
"format": "date-time",
"example": "2022-03-21T14:35:33Z"
},
"id": {
"type": "integer",
"format": "int64",
"example": 2
},
"isDisabled": {
"type": "boolean",
"example": false
},
"login": {
"type": "string",
"example": "sa-grafana"
},
"name": {
"type": "string",
"example": "test"
},
"orgId": {
"type": "integer",
"format": "int64",
"example": 1
},
"role": {
"type": "string",
"example": "Editor"
},
"teams": {
"type": "array",
"items": {
"type": "string"
},
"example": []
},
"tokens": {
"type": "integer",
"format": "int64"
},
"updatedAt": {
"type": "string",
"format": "date-time",
"example": "2022-03-21T14:35:33Z"
}
}
},
"SetUserRolesCommand": { "SetUserRolesCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -12408,6 +12997,44 @@
} }
} }
}, },
"TokenDTO": {
"type": "object",
"properties": {
"created": {
"type": "string",
"format": "date-time",
"example": "2022-03-23T10:31:02Z"
},
"expiration": {
"type": "string",
"format": "date-time",
"example": "2022-03-23T10:31:02Z"
},
"hasExpired": {
"type": "boolean",
"example": false
},
"id": {
"type": "integer",
"format": "int64",
"example": 1
},
"lastUsedAt": {
"type": "string",
"format": "date-time",
"example": "2022-03-23T10:31:02Z"
},
"name": {
"type": "string",
"example": "grafana"
},
"secondsUntilExpiration": {
"type": "number",
"format": "double",
"example": 0
}
}
},
"TokenStatus": { "TokenStatus": {
"type": "integer", "type": "integer",
"format": "int64" "format": "int64"
@ -12757,6 +13384,21 @@
} }
} }
}, },
"UpdateServiceAccountForm": {
"type": "object",
"properties": {
"isDisabled": {
"type": "boolean"
},
"name": {
"type": "string"
},
"role": {
"type": "string",
"enum": ["Viewer", "Editor", "Admin"]
}
}
},
"UpdateTeamCommand": { "UpdateTeamCommand": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -13164,7 +13806,22 @@
"createReportResponse": { "createReportResponse": {
"description": "", "description": "",
"schema": { "schema": {
"type": "object" "type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"message": {
"type": "string"
}
}
}
},
"createServiceAccountResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/ServiceAccountDTO"
} }
}, },
"createSnapshotResponse": { "createSnapshotResponse": {
@ -13209,6 +13866,12 @@
} }
} }
}, },
"createTokenResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/NewApiKeyResult"
}
},
"createUserResponse": { "createUserResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -13578,7 +14241,7 @@
"getPermissionseResponse": { "getPermissionseResponse": {
"description": "", "description": "",
"schema": { "schema": {
"$ref": "#/definitions/AddPermissionDTO" "$ref": "#/definitions/DataSourcePermissionsDTO"
} }
}, },
"getPlaylistDashboardsResponse": { "getPlaylistDashboardsResponse": {
@ -13796,6 +14459,12 @@
} }
} }
}, },
"listTokensResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/TokenDTO"
}
},
"lookupAlertNotificationChannelsResponse": { "lookupAlertNotificationChannelsResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -13946,6 +14615,12 @@
"$ref": "#/definitions/ActiveUserStats" "$ref": "#/definitions/ActiveUserStats"
} }
}, },
"retrieveServiceAccountResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/ServiceAccountDTO"
}
},
"searchOrgResponse": { "searchOrgResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -13955,6 +14630,12 @@
} }
} }
}, },
"searchOrgServiceAccountsWithPagingResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/SearchServiceAccountsResult"
}
},
"searchPlaylistsResponse": { "searchPlaylistsResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -14032,6 +14713,27 @@
"$ref": "#/definitions/PlaylistDTO" "$ref": "#/definitions/PlaylistDTO"
} }
}, },
"updateServiceAccountResponse": {
"description": "",
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"message": {
"type": "string"
},
"name": {
"type": "string"
},
"serviceaccount": {
"$ref": "#/definitions/ServiceAccountProfileDTO"
}
}
}
},
"userResponse": { "userResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -14141,6 +14843,10 @@
{ {
"description": "Grafana Alerting Prometheus-compatible endpoints", "description": "Grafana Alerting Prometheus-compatible endpoints",
"name": "prometheus" "name": "prometheus"
},
{
"description": "If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information.",
"name": "service_accounts"
} }
] ]
} }