diff --git a/docs/sources/developers/kinds/core/serviceaccount/schema-reference.md b/docs/sources/developers/kinds/core/serviceaccount/schema-reference.md new file mode 100644 index 00000000000..e668f64aa2f --- /dev/null +++ b/docs/sources/developers/kinds/core/serviceaccount/schema-reference.md @@ -0,0 +1,38 @@ +--- +keywords: + - grafana + - schema +title: Serviceaccount kind +--- +> Both documentation generation and kinds schemas are in active development and subject to change without prior notice. + +# Serviceaccount kind + +## Maturity: merged +## Version: 0.0 + +## Properties + +| Property | Type | Required | Description | +|-----------------|--------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------| +| `avatarUrl` | string | **Yes** | AvatarUrl is the service account's avatar URL. It allows the frontend to display a picture in front
of the service account. | +| `id` | integer | **Yes** | ID is the unique identifier of the service account in the database. | +| `isDisabled` | boolean | **Yes** | IsDisabled indicates if the service account is disabled. | +| `login` | string | **Yes** | Login of the service account. | +| `name` | string | **Yes** | Name of the service account. | +| `orgId` | integer | **Yes** | OrgId is the ID of an organisation the service account belongs to. | +| `role` | string | **Yes** | OrgRole is a Grafana Organization Role which can be 'Viewer', 'Editor', 'Admin'. Possible values are: `Admin`, `Editor`, `Viewer`. | +| `tokens` | integer | **Yes** | Tokens is the number of active tokens for the service account.
Tokens are used to authenticate the service account against Grafana. | +| `accessControl` | [object](#accesscontrol) | No | AccessControl metadata associated with a given resource. | +| `created` | integer | No | Created indicates when the service account was created. | +| `teams` | string[] | No | Teams is a list of teams the service account belongs to. | +| `updated` | integer | No | Updated indicates when the service account was updated. | + +## accessControl + +AccessControl metadata associated with a given resource. + +| Property | Type | Required | Description | +|----------|------|----------|-------------| + + diff --git a/kinds/serviceaccount/serviceaccount_kind.cue b/kinds/serviceaccount/serviceaccount_kind.cue new file mode 100644 index 00000000000..befc567bc9a --- /dev/null +++ b/kinds/serviceaccount/serviceaccount_kind.cue @@ -0,0 +1,46 @@ +package kind + +name: "Serviceaccount" +maturity: "merged" + +lineage: seqs: [ + { + schemas: [ + // v0.0 + { + // ID is the unique identifier of the service account in the database. + id: int64 @grafanamaturity(ToMetadata="sys") + // OrgId is the ID of an organisation the service account belongs to. + orgId: int64 @grafanamaturity(ToMetadata="sys") + // Name of the service account. + name: string + // Login of the service account. + login: string + // IsDisabled indicates if the service account is disabled. + isDisabled: bool + // Role is the Grafana organization role of the service account which can be 'Viewer', 'Editor', 'Admin'. + role: #OrgRole @grafanamaturity(ToMetadata="kind") + // Tokens is the number of active tokens for the service account. + // Tokens are used to authenticate the service account against Grafana. + tokens: int64 @grafanamaturity(ToMetadata="kind") + // AvatarUrl is the service account's avatar URL. It allows the frontend to display a picture in front + // of the service account. + avatarUrl: string @grafanamaturity(ToMetadata="kind") + // AccessControl metadata associated with a given resource. + accessControl?: { + [string]: bool @grafanamaturity(ToMetadata="sys") + } + + // Teams is a list of teams the service account belongs to. + teams?: [...string] @grafanamaturity(ToMetadata="sys") + // Created indicates when the service account was created. + created?: int64 @grafanamaturity(ToMetadata="sys") + // Updated indicates when the service account was updated. + updated?: int64 @grafanamaturity(ToMetadata="sys") + + // OrgRole is a Grafana Organization Role which can be 'Viewer', 'Editor', 'Admin'. + #OrgRole: "Admin" | "Editor" | "Viewer" @cuetsy(kind="type") + }, + ] + }, +] diff --git a/packages/grafana-schema/src/index.gen.ts b/packages/grafana-schema/src/index.gen.ts index 9fdf476a0e4..6e9378c10c7 100644 --- a/packages/grafana-schema/src/index.gen.ts +++ b/packages/grafana-schema/src/index.gen.ts @@ -95,6 +95,15 @@ export type { // Raw generated enums and default consts from playlist kind. export { defaultPlaylist } from './raw/playlist/x/playlist_types.gen'; +// Raw generated types from Serviceaccount kind. +export type { + Serviceaccount, + OrgRole +} from './raw/serviceaccount/x/serviceaccount_types.gen'; + +// Raw generated enums and default consts from serviceaccount kind. +export { defaultServiceaccount } from './raw/serviceaccount/x/serviceaccount_types.gen'; + // Raw generated types from Team kind. export type { Team } from './raw/team/x/team_types.gen'; diff --git a/packages/grafana-schema/src/raw/serviceaccount/x/serviceaccount_types.gen.ts b/packages/grafana-schema/src/raw/serviceaccount/x/serviceaccount_types.gen.ts new file mode 100644 index 00000000000..4abfa4f7cbc --- /dev/null +++ b/packages/grafana-schema/src/raw/serviceaccount/x/serviceaccount_types.gen.ts @@ -0,0 +1,71 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// TSTypesJenny +// LatestMajorsOrXJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +/** + * OrgRole is a Grafana Organization Role which can be 'Viewer', 'Editor', 'Admin'. + */ +export type OrgRole = ('Admin' | 'Editor' | 'Viewer'); + +export interface Serviceaccount { + /** + * AccessControl metadata associated with a given resource. + */ + accessControl?: Record; + /** + * AvatarUrl is the service account's avatar URL. It allows the frontend to display a picture in front + * of the service account. + */ + avatarUrl: string; + /** + * Created indicates when the service account was created. + */ + created?: number; + /** + * ID is the unique identifier of the service account in the database. + */ + id: number; + /** + * IsDisabled indicates if the service account is disabled. + */ + isDisabled: boolean; + /** + * Login of the service account. + */ + login: string; + /** + * Name of the service account. + */ + name: string; + /** + * OrgId is the ID of an organisation the service account belongs to. + */ + orgId: number; + /** + * Role is the Grafana organization role of the service account which can be 'Viewer', 'Editor', 'Admin'. + */ + role: OrgRole; + /** + * Teams is a list of teams the service account belongs to. + */ + teams?: Array; + /** + * Tokens is the number of active tokens for the service account. + * Tokens are used to authenticate the service account against Grafana. + */ + tokens: number; + /** + * Updated indicates when the service account was updated. + */ + updated?: number; +} + +export const defaultServiceaccount: Partial = { + teams: [], +}; diff --git a/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go b/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go new file mode 100644 index 00000000000..097d21c12c1 --- /dev/null +++ b/pkg/kinds/serviceaccount/serviceaccount_kind_gen.go @@ -0,0 +1,113 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// CoreKindJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +package serviceaccount + +import ( + "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/thema" + "github.com/grafana/thema/vmux" +) + +// rootrel is the relative path from the grafana repository root to the +// directory containing the .cue files in which this kind is declared. Necessary +// for runtime errors related to the declaration and/or lineage to provide +// a real path to the correct .cue file. +const rootrel string = "kinds/serviceaccount" + +// TODO standard generated docs +type Kind struct { + lin thema.ConvergentLineage[*Serviceaccount] + jcodec vmux.Codec + valmux vmux.ValueMux[*Serviceaccount] + decl kindsys.Decl[kindsys.CoreProperties] +} + +// type guard +var _ kindsys.Core = &Kind{} + +// TODO standard generated docs +func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { + decl, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) + if err != nil { + return nil, err + } + k := &Kind{ + decl: decl, + } + + lin, err := decl.Some().BindKindLineage(rt, opts...) + if err != nil { + return nil, err + } + + // Get the thema.Schema that the meta says is in the current version (which + // codegen ensures is always the latest) + cursch := thema.SchemaP(lin, k.decl.Properties.CurrentVersion) + tsch, err := thema.BindType[*Serviceaccount](cursch, &Serviceaccount{}) + if err != nil { + // Should be unreachable, modulo bugs in the Thema->Go code generator + return nil, err + } + + k.jcodec = vmux.NewJSONCodec("serviceaccount.json") + k.lin = tsch.ConvergentLineage() + k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec) + return k, nil +} + +// TODO standard generated docs +func (k *Kind) Name() string { + return "serviceaccount" +} + +// TODO standard generated docs +func (k *Kind) MachineName() string { + return "serviceaccount" +} + +// TODO standard generated docs +func (k *Kind) Lineage() thema.Lineage { + return k.lin +} + +// TODO standard generated docs +func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Serviceaccount] { + return k.lin +} + +// JSONValueMux is a version multiplexer that maps a []byte containing JSON data +// at any schematized dashboard version to an instance of Serviceaccount. +// +// Validation and translation errors emitted from this func will identify the +// input bytes as "dashboard.json". +// +// This is a thin wrapper around Thema's [vmux.ValueMux]. +func (k *Kind) JSONValueMux(b []byte) (*Serviceaccount, thema.TranslationLacunas, error) { + return k.valmux(b) +} + +// TODO standard generated docs +func (k *Kind) Maturity() kindsys.Maturity { + return k.decl.Properties.Maturity +} + +// Decl returns the [kindsys.Decl] containing both CUE and Go representations of the +// serviceaccount declaration in .cue files. +func (k *Kind) Decl() kindsys.Decl[kindsys.CoreProperties] { + return k.decl +} + +// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], +// representing the static properties declared in the serviceaccount kind. +// +// This method is identical to calling Decl().Props. It is provided to satisfy [kindsys.Interface]. +func (k *Kind) Props() kindsys.SomeKindProperties { + return k.decl.Properties +} diff --git a/pkg/kinds/serviceaccount/serviceaccount_types_gen.go b/pkg/kinds/serviceaccount/serviceaccount_types_gen.go new file mode 100644 index 00000000000..c539cf24d1b --- /dev/null +++ b/pkg/kinds/serviceaccount/serviceaccount_types_gen.go @@ -0,0 +1,64 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// GoTypesJenny +// LatestJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +package serviceaccount + +// Defines values for OrgRole. +const ( + OrgRoleAdmin OrgRole = "Admin" + + OrgRoleEditor OrgRole = "Editor" + + OrgRoleViewer OrgRole = "Viewer" +) + +// OrgRole is a Grafana Organization Role which can be 'Viewer', 'Editor', 'Admin'. +type OrgRole string + +// Serviceaccount defines model for serviceaccount. +type Serviceaccount struct { + // AccessControl metadata associated with a given resource. + AccessControl map[string]bool `json:"accessControl,omitempty"` + + // AvatarUrl is the service account's avatar URL. It allows the frontend to display a picture in front + // of the service account. + AvatarUrl string `json:"avatarUrl"` + + // Created indicates when the service account was created. + Created *int64 `json:"created,omitempty"` + + // ID is the unique identifier of the service account in the database. + Id int64 `json:"id"` + + // IsDisabled indicates if the service account is disabled. + IsDisabled bool `json:"isDisabled"` + + // Login of the service account. + Login string `json:"login"` + + // Name of the service account. + Name string `json:"name"` + + // OrgId is the ID of an organisation the service account belongs to. + OrgId int64 `json:"orgId"` + + // OrgRole is a Grafana Organization Role which can be 'Viewer', 'Editor', 'Admin'. + Role OrgRole `json:"role"` + + // Teams is a list of teams the service account belongs to. + Teams *[]string `json:"teams,omitempty"` + + // Tokens is the number of active tokens for the service account. + // Tokens are used to authenticate the service account against Grafana. + Tokens int64 `json:"tokens"` + + // Updated indicates when the service account was updated. + Updated *int64 `json:"updated,omitempty"` +} diff --git a/pkg/kindsys/report.go b/pkg/kindsys/report.go index b853abbe97d..97f12d894fd 100644 --- a/pkg/kindsys/report.go +++ b/pkg/kindsys/report.go @@ -71,7 +71,7 @@ var plannedCoreKinds = []string{ "Folder", "DataSource", "APIKey", - "ServiceAccount", + "Serviceaccount", "Thumb", "Query", "QueryHistory", diff --git a/pkg/kindsys/report.json b/pkg/kindsys/report.json index 7ed9ccdc6b4..35d314c27c9 100644 --- a/pkg/kindsys/report.json +++ b/pkg/kindsys/report.json @@ -1299,24 +1299,29 @@ }, "serviceaccount": { "category": "core", - "codeowners": [], + "codeowners": [ + "grafana/grafana-as-code", + "grafana/grafana-bi-squad", + "grafana/plugins-platform-frontend", + "grafana/user-essentials" + ], "currentVersion": [ 0, 0 ], - "grafanaMaturityCount": 0, + "grafanaMaturityCount": 9, "lineageIsGroup": false, "links": { - "docs": "n/a", - "go": "n/a", - "schema": "n/a", - "ts": "n/a" + "docs": "https://grafana.com/docs/grafana/next/developers/kinds/core/serviceaccount/schema-reference", + "go": "https://github.com/grafana/grafana/tree/main/pkg/kinds/serviceaccount", + "schema": "https://github.com/grafana/grafana/tree/main/kinds/serviceaccount/serviceaccount_kind.cue", + "ts": "https://github.com/grafana/grafana/tree/main/packages/grafana-schema/src/raw/serviceaccount/x/serviceaccount_types.gen.ts" }, "machineName": "serviceaccount", - "maturity": "planned", - "name": "ServiceAccount", + "maturity": "merged", + "name": "Serviceaccount", "pluralMachineName": "serviceaccounts", - "pluralName": "ServiceAccounts" + "pluralName": "Serviceaccounts" }, "statpanelcfg": { "category": "composable", @@ -1772,9 +1777,10 @@ "items": [ "alertgroupspanelcfg", "playlist", + "serviceaccount", "team" ], - "count": 3 + "count": 4 }, "planned": { "name": "planned", @@ -1826,7 +1832,6 @@ "prometheusdatasourcecfg", "query", "queryhistory", - "serviceaccount", "tableoldpanelcfg", "tempodataquery", "tempodatasourcecfg", @@ -1840,7 +1845,7 @@ "zipkindataquery", "zipkindatasourcecfg" ], - "count": 60 + "count": 59 }, "stable": { "name": "stable", diff --git a/pkg/registry/corekind/base_gen.go b/pkg/registry/corekind/base_gen.go index 2e9753ed1a6..f3e52a08564 100644 --- a/pkg/registry/corekind/base_gen.go +++ b/pkg/registry/corekind/base_gen.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/kinds/dashboard" "github.com/grafana/grafana/pkg/kinds/playlist" + "github.com/grafana/grafana/pkg/kinds/serviceaccount" "github.com/grafana/grafana/pkg/kinds/team" "github.com/grafana/grafana/pkg/kindsys" "github.com/grafana/thema" @@ -30,16 +31,18 @@ import ( // Prefer All*() methods when performing operations generically across all kinds. // For example, a validation HTTP middleware for any kind-schematized object type. type Base struct { - all []kindsys.Core - dashboard *dashboard.Kind - playlist *playlist.Kind - team *team.Kind + all []kindsys.Core + dashboard *dashboard.Kind + playlist *playlist.Kind + serviceaccount *serviceaccount.Kind + team *team.Kind } // type guards var ( _ kindsys.Core = &dashboard.Kind{} _ kindsys.Core = &playlist.Kind{} + _ kindsys.Core = &serviceaccount.Kind{} _ kindsys.Core = &team.Kind{} ) @@ -53,6 +56,11 @@ func (b *Base) Playlist() *playlist.Kind { return b.playlist } +// Serviceaccount returns the [kindsys.Interface] implementation for the serviceaccount kind. +func (b *Base) Serviceaccount() *serviceaccount.Kind { + return b.serviceaccount +} + // Team returns the [kindsys.Interface] implementation for the team kind. func (b *Base) Team() *team.Kind { return b.team @@ -74,6 +82,12 @@ func doNewBase(rt *thema.Runtime) *Base { } reg.all = append(reg.all, reg.playlist) + reg.serviceaccount, err = serviceaccount.NewKind(rt) + if err != nil { + panic(fmt.Sprintf("error while initializing the serviceaccount Kind: %s", err)) + } + reg.all = append(reg.all, reg.serviceaccount) + reg.team, err = team.NewKind(rt) if err != nil { panic(fmt.Sprintf("error while initializing the team Kind: %s", err))