From 16fec646906a63164457f86022db670a2fd274aa Mon Sep 17 00:00:00 2001 From: Tania Date: Thu, 1 Dec 2022 17:08:54 +0100 Subject: [PATCH] Schema: Add `Team` structured core kind (#59242) * Add Team kind * Minor changes * Use ToMedatata annotation Co-authored-by: sam boyer * Use ToMedatata annotation Co-authored-by: sam boyer * Use ToMedatata annotation Co-authored-by: sam boyer * Use ToMedatata annotation Co-authored-by: sam boyer * Update comments * Add created and updated fields * Make orgId required * Use int64 for datetime Co-authored-by: sam boyer --- kinds/structured/team/team_kind.cue | 34 ++++++ packages/grafana-schema/src/index.gen.ts | 6 + .../src/raw/team/x/team_types.gen.ts | 54 +++++++++ pkg/kinds/team/team_kind_gen.go | 105 ++++++++++++++++++ pkg/kinds/team/team_types_gen.go | 53 +++++++++ pkg/registry/corekind/base_gen.go | 16 ++- 6 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 kinds/structured/team/team_kind.cue create mode 100644 packages/grafana-schema/src/raw/team/x/team_types.gen.ts create mode 100644 pkg/kinds/team/team_kind_gen.go create mode 100644 pkg/kinds/team/team_types_gen.go diff --git a/kinds/structured/team/team_kind.cue b/kinds/structured/team/team_kind.cue new file mode 100644 index 00000000000..6b1d9da1f2e --- /dev/null +++ b/kinds/structured/team/team_kind.cue @@ -0,0 +1,34 @@ +package kind + +name: "Team" +maturity: "merged" + +lineage: seqs: [ + { + schemas: [ + // v0.0 + { + // OrgId is the ID of an organisation the team belongs to. + orgId: int64 @grafanamaturity(ToMetadata="sys") + // Name of the team. + name: string + // Email of the team. + email?: string + // AvatarUrl is the team's avatar URL. + avatarUrl?: string @grafanamaturity(MaybeRemove) + // MemberCount is the number of the team members. + memberCount: int64 @grafanamaturity(ToMetadata="kind") + // TODO - it seems it's a team_member.permission, unlikely it should belong to the team kind + permission: #Permission @grafanamaturity(ToMetadata="kind", MaybeRemove) + // AccessControl metadata associated with a given resource. + accessControl: [string]: bool @grafanamaturity(ToMetadata="sys") + // Created indicates when the team was created. + created: int64 @grafanamaturity(ToMetadata="sys") + // Updated indicates when the team was updated. + updated: int64 @grafanamaturity(ToMetadata="sys") + + #Permission: 1 | 2 | 4 @cuetsy(kind="enum",memberNames="viewer|editor|admin") + }, + ] + }, +] diff --git a/packages/grafana-schema/src/index.gen.ts b/packages/grafana-schema/src/index.gen.ts index 459c68aa6d7..f875870120a 100644 --- a/packages/grafana-schema/src/index.gen.ts +++ b/packages/grafana-schema/src/index.gen.ts @@ -88,3 +88,9 @@ export type { // Raw generated default consts from playlist kind. export { defaultPlaylist } from './raw/playlist/x/playlist_types.gen'; + +// Raw generated types from Team kind. +export type { + Team, + Permission +} from './raw/team/x/team_types.gen'; diff --git a/packages/grafana-schema/src/raw/team/x/team_types.gen.ts b/packages/grafana-schema/src/raw/team/x/team_types.gen.ts new file mode 100644 index 00000000000..f76ca40bbd2 --- /dev/null +++ b/packages/grafana-schema/src/raw/team/x/team_types.gen.ts @@ -0,0 +1,54 @@ +// THIS FILE IS GENERATED. EDITING IS FUTILE. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// TSTypesJenny +// LatestMajorsOrXJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +export enum Permission { + Admin = 4, + Editor = 2, + Viewer = 1, +} + +export interface Team { + /** + * AccessControl metadata associated with a given resource. + */ + accessControl: Record; + /** + * AvatarUrl is the team's avatar URL. + */ + avatarUrl?: string; + /** + * Created indicates when the team was created. + */ + created: number; + /** + * Email of the team. + */ + email?: string; + /** + * MemberCount is the number of the team members. + */ + memberCount: number; + /** + * Name of the team. + */ + name: string; + /** + * OrgId is the ID of an organisation the team belongs to. + */ + orgId: number; + /** + * TODO - it seems it's a team_member.permission, unlikely it should belong to the team kind + */ + permission: Permission; + /** + * Updated indicates when the team was updated. + */ + updated: number; +} diff --git a/pkg/kinds/team/team_kind_gen.go b/pkg/kinds/team/team_kind_gen.go new file mode 100644 index 00000000000..0401069ee17 --- /dev/null +++ b/pkg/kinds/team/team_kind_gen.go @@ -0,0 +1,105 @@ +// THIS FILE IS GENERATED. EDITING IS FUTILE. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// CoreStructuredKindJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +package team + +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/structured/team" + +// TODO standard generated docs +type Kind struct { + lin thema.ConvergentLineage[*Team] + jcodec vmux.Codec + valmux vmux.ValueMux[*Team] + decl kindsys.Decl[kindsys.CoreStructuredMeta] +} + +// type guard +var _ kindsys.Structured = &Kind{} + +// TODO standard generated docs +func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { + decl, err := kindsys.LoadCoreKind[kindsys.CoreStructuredMeta](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.Meta.CurrentVersion) + tsch, err := thema.BindType[*Team](cursch, &Team{}) + if err != nil { + // Should be unreachable, modulo bugs in the Thema->Go code generator + return nil, err + } + + k.jcodec = vmux.NewJSONCodec("team.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 "team" +} + +// TODO standard generated docs +func (k *Kind) MachineName() string { + return "team" +} + +// TODO standard generated docs +func (k *Kind) Lineage() thema.Lineage { + return k.lin +} + +// TODO standard generated docs +func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*Team] { + return k.lin +} + +// JSONValueMux is a version multiplexer that maps a []byte containing JSON data +// at any schematized dashboard version to an instance of Team. +// +// 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) (*Team, thema.TranslationLacunas, error) { + return k.valmux(b) +} + +// TODO standard generated docs +func (k *Kind) Maturity() kindsys.Maturity { + return k.decl.Meta.Maturity +} + +// TODO standard generated docs +func (k *Kind) Decl() *kindsys.Decl[kindsys.CoreStructuredMeta] { + d := k.decl + return &d +} diff --git a/pkg/kinds/team/team_types_gen.go b/pkg/kinds/team/team_types_gen.go new file mode 100644 index 00000000000..9fb8d67d534 --- /dev/null +++ b/pkg/kinds/team/team_types_gen.go @@ -0,0 +1,53 @@ +// THIS FILE IS GENERATED. EDITING IS FUTILE. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// GoTypesJenny +// LatestJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +package team + +// Defines values for Permission. +const ( + PermissionN1 Permission = 1 + + PermissionN2 Permission = 2 + + PermissionN4 Permission = 4 +) + +// Team defines model for team. +type Team struct { + // AccessControl metadata associated with a given resource. + AccessControl map[string]interface{} `json:"accessControl"` + + // AvatarUrl is the team's avatar URL. + AvatarUrl *string `json:"avatarUrl,omitempty"` + + // Created indicates when the team was created. + Created int64 `json:"created"` + + // Email of the team. + Email *string `json:"email,omitempty"` + + // MemberCount is the number of the team members. + MemberCount int64 `json:"memberCount"` + + // Name of the team. + Name string `json:"name"` + + // OrgId is the ID of an organisation the team belongs to. + OrgId int64 `json:"orgId"` + + // TODO - it seems it's a team_member.permission, unlikely it should belong to the team kind + Permission Permission `json:"permission"` + + // Updated indicates when the team was updated. + Updated int64 `json:"updated"` +} + +// TODO - it seems it's a team_member.permission, unlikely it should belong to the team kind +type Permission int diff --git a/pkg/registry/corekind/base_gen.go b/pkg/registry/corekind/base_gen.go index b6064eaf1e1..962ee196ec3 100644 --- a/pkg/registry/corekind/base_gen.go +++ b/pkg/registry/corekind/base_gen.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/kinds/dashboard" "github.com/grafana/grafana/pkg/kinds/playlist" "github.com/grafana/grafana/pkg/kinds/svg" + "github.com/grafana/grafana/pkg/kinds/team" "github.com/grafana/grafana/pkg/kindsys" "github.com/grafana/thema" ) @@ -35,6 +36,7 @@ type Base struct { dashboard *dashboard.Kind playlist *playlist.Kind svg *svg.Kind + team *team.Kind } // type guards @@ -42,6 +44,7 @@ var ( _ kindsys.Structured = &dashboard.Kind{} _ kindsys.Structured = &playlist.Kind{} _ kindsys.Raw = &svg.Kind{} + _ kindsys.Structured = &team.Kind{} ) // Dashboard returns the [kindsys.Interface] implementation for the dashboard kind. @@ -59,11 +62,16 @@ func (b *Base) SVG() *svg.Kind { return b.svg } +// Team returns the [kindsys.Interface] implementation for the team kind. +func (b *Base) Team() *team.Kind { + return b.team +} + func doNewBase(rt *thema.Runtime) *Base { var err error reg := &Base{ numRaw: 1, - numStructured: 2, + numStructured: 3, } reg.dashboard, err = dashboard.NewKind(rt) @@ -84,5 +92,11 @@ func doNewBase(rt *thema.Runtime) *Base { } reg.all = append(reg.all, reg.svg) + reg.team, err = team.NewKind(rt) + if err != nil { + panic(fmt.Sprintf("error while initializing the team Kind: %s", err)) + } + reg.all = append(reg.all, reg.team) + return reg }