API: Add service account routes to the swagger (#52398)
* API: Add service account routes to the swagger
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,10 @@
|
||||
{
|
||||
"name": "prometheus",
|
||||
"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."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,10 +7,14 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
)
|
||||
|
||||
// swagger:model
|
||||
type NewApiKeyResult struct {
|
||||
ID int64 `json:"id"`
|
||||
// example: 1
|
||||
ID int64 `json:"id"`
|
||||
// example: grafana
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
// example: glsa_yscW25imSKJIuav8zF37RZmnbiDvB05G_fcaaf58a
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
type ApiKeyDTO struct {
|
||||
|
||||
@@ -20,14 +20,22 @@ const (
|
||||
ServiceID = "sa"
|
||||
)
|
||||
|
||||
// swagger:model
|
||||
type TokenDTO struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Created *time.Time `json:"created"`
|
||||
LastUsedAt *time.Time `json:"lastUsedAt"`
|
||||
Expiration *time.Time `json:"expiration"`
|
||||
SecondsUntilExpiration *float64 `json:"secondsUntilExpiration"`
|
||||
HasExpired bool `json:"hasExpired"`
|
||||
// example: 1
|
||||
Id int64 `json:"id"`
|
||||
// example: grafana
|
||||
Name string `json:"name"`
|
||||
// example: 2022-03-23T10:31:02Z
|
||||
Created *time.Time `json:"created"`
|
||||
// example: 2022-03-23T10:31:02Z
|
||||
LastUsedAt *time.Time `json:"lastUsedAt"`
|
||||
// example: 2022-03-23T10:31:02Z
|
||||
Expiration *time.Time `json:"expiration"`
|
||||
// example: 0
|
||||
SecondsUntilExpiration *float64 `json:"secondsUntilExpiration"`
|
||||
// example: false
|
||||
HasExpired bool `json:"hasExpired"`
|
||||
}
|
||||
|
||||
func hasExpired(expiration *int64) bool {
|
||||
|
||||
@@ -25,27 +25,41 @@ type ServiceAccount struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
// swagger:model
|
||||
type CreateServiceAccountForm struct {
|
||||
Name string `json:"name" binding:"Required"`
|
||||
Role *models.RoleType `json:"role"`
|
||||
IsDisabled *bool `json:"isDisabled"`
|
||||
// example: grafana
|
||||
Name string `json:"name" binding:"Required"`
|
||||
// example: Admin
|
||||
Role *models.RoleType `json:"role"`
|
||||
// example: false
|
||||
IsDisabled *bool `json:"isDisabled"`
|
||||
}
|
||||
|
||||
// swagger:model
|
||||
type UpdateServiceAccountForm struct {
|
||||
Name *string `json:"name"`
|
||||
Role *models.RoleType `json:"role"`
|
||||
IsDisabled *bool `json:"isDisabled"`
|
||||
}
|
||||
|
||||
// swagger: model
|
||||
type ServiceAccountDTO struct {
|
||||
Id int64 `json:"id" xorm:"user_id"`
|
||||
Name string `json:"name" xorm:"name"`
|
||||
Login string `json:"login" xorm:"login"`
|
||||
OrgId int64 `json:"orgId" xorm:"org_id"`
|
||||
IsDisabled bool `json:"isDisabled" xorm:"is_disabled"`
|
||||
Role string `json:"role" xorm:"role"`
|
||||
Tokens int64 `json:"tokens"`
|
||||
AvatarUrl string `json:"avatarUrl"`
|
||||
Id int64 `json:"id" xorm:"user_id"`
|
||||
// example: grafana
|
||||
Name string `json:"name" xorm:"name"`
|
||||
// example: sa-grafana
|
||||
Login string `json:"login" xorm:"login"`
|
||||
// example: 1
|
||||
OrgId int64 `json:"orgId" xorm:"org_id"`
|
||||
// example: false
|
||||
IsDisabled bool `json:"isDisabled" xorm:"is_disabled"`
|
||||
// example: Viewer
|
||||
Role string `json:"role" xorm:"role"`
|
||||
// example: 0
|
||||
Tokens int64 `json:"tokens"`
|
||||
// example: /avatar/85ec38023d90823d3e5b43ef35646af9
|
||||
AvatarUrl string `json:"avatarUrl"`
|
||||
// example: {"serviceaccounts:delete": true, "serviceaccounts:read": true, "serviceaccounts:write": true}
|
||||
AccessControl map[string]bool `json:"accessControl,omitempty"`
|
||||
}
|
||||
|
||||
@@ -57,23 +71,38 @@ type AddServiceAccountTokenCommand struct {
|
||||
Result *models.ApiKey `json:"-"`
|
||||
}
|
||||
|
||||
// swagger: model
|
||||
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"`
|
||||
ServiceAccounts []*ServiceAccountDTO `json:"serviceAccounts"`
|
||||
Page int `json:"page"`
|
||||
PerPage int `json:"perPage"`
|
||||
}
|
||||
|
||||
// swagger:model
|
||||
type ServiceAccountProfileDTO struct {
|
||||
Id int64 `json:"id" xorm:"user_id"`
|
||||
Name string `json:"name" xorm:"name"`
|
||||
Login string `json:"login" xorm:"login"`
|
||||
OrgId int64 `json:"orgId" xorm:"org_id"`
|
||||
IsDisabled bool `json:"isDisabled" xorm:"is_disabled"`
|
||||
Created time.Time `json:"createdAt" xorm:"created"`
|
||||
Updated time.Time `json:"updatedAt" xorm:"updated"`
|
||||
AvatarUrl string `json:"avatarUrl" xorm:"-"`
|
||||
Role string `json:"role" xorm:"role"`
|
||||
// example: 2
|
||||
Id int64 `json:"id" xorm:"user_id"`
|
||||
// example: test
|
||||
Name string `json:"name" xorm:"name"`
|
||||
// example: sa-grafana
|
||||
Login string `json:"login" xorm:"login"`
|
||||
// example: 1
|
||||
OrgId int64 `json:"orgId" xorm:"org_id"`
|
||||
// example: false
|
||||
IsDisabled bool `json:"isDisabled" xorm:"is_disabled"`
|
||||
// example: 2022-03-21T14:35:33Z
|
||||
Created time.Time `json:"createdAt" xorm:"created"`
|
||||
// example: 2022-03-21T14:35:33Z
|
||||
Updated time.Time `json:"updatedAt" xorm:"updated"`
|
||||
// example: /avatar/8ea890a677d6a223c591a1beea6ea9d2
|
||||
AvatarUrl string `json:"avatarUrl" xorm:"-"`
|
||||
// example: Editor
|
||||
Role string `json:"role" xorm:"role"`
|
||||
// example: []
|
||||
Teams []string `json:"teams" xorm:"-"`
|
||||
Tokens int64 `json:"tokens,omitempty"`
|
||||
AccessControl map[string]bool `json:"accessControl,omitempty" xorm:"-"`
|
||||
|
||||
Reference in New Issue
Block a user