K8s/Playlist: Refactor apis packages so the types and registry are in different packages (#77586)

pull/77571/head
Ryan McKinley 2 years ago committed by GitHub
parent 72ed6434ca
commit dd654fdc87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      pkg/api/playlist.go
  2. 2
      pkg/apis/example/v0alpha1/zz_generated.openapi..go
  3. 4
      pkg/apis/playlist/doc.go
  4. 65
      pkg/apis/playlist/types.go
  5. 74
      pkg/apis/playlist/v0alpha1/register.go
  6. 170
      pkg/apis/playlist/v0alpha1/zz_generated.conversion.go
  7. 2
      pkg/apis/playlist/v0alpha1/zz_generated.openapi.go
  8. 123
      pkg/apis/playlist/zz_generated.deepcopy.go
  9. 17
      pkg/apis/wireset.go
  10. 12
      pkg/registry/apis/apis.go
  11. 12
      pkg/registry/apis/example/register.go
  12. 11
      pkg/registry/apis/example/storage.go
  13. 29
      pkg/registry/apis/playlist/conversions.go
  14. 0
      pkg/registry/apis/playlist/conversions_test.go
  15. 29
      pkg/registry/apis/playlist/legacy_storage.go
  16. 38
      pkg/registry/apis/playlist/register.go
  17. 5
      pkg/registry/apis/playlist/storage.go
  18. 11
      pkg/registry/apis/wireset.go
  19. 2
      pkg/services/grafana-apiserver/service.go

@ -12,8 +12,8 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
internalplaylist "github.com/grafana/grafana/pkg/apis/playlist"
"github.com/grafana/grafana/pkg/middleware"
internalplaylist "github.com/grafana/grafana/pkg/registry/apis/playlist"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"

@ -8,7 +8,7 @@ import (
// NOTE: this must match the golang fully qualified name!
const kindKey = "github.com/grafana/grafana/pkg/apis/example/v0alpha1.RuntimeInfo"
func getOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
kindKey: schema_pkg_apis_example_v0alpha1_RuntimeInfo(ref),
}

@ -1,4 +0,0 @@
// +k8s:deepcopy-gen=package
// +groupName=playlist.grafana.app
package playlist // import "github.com/grafana/grafana/pkg/apis/playlist"

@ -1,65 +0,0 @@
package playlist
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Playlist struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec Spec `json:"spec,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PlaylistList struct {
metav1.TypeMeta `json:",inline"`
// +optional
metav1.ListMeta `json:"metadata,omitempty"`
Items []Playlist `json:"items,omitempty"`
}
// Spec defines model for Spec.
type Spec struct {
// Name of the playlist.
Title string `json:"title"`
// Interval sets the time between switching views in a playlist.
Interval string `json:"interval"`
// The ordered list of items that the playlist will iterate over.
Items []Item `json:"items,omitempty"`
}
// Defines values for ItemType.
const (
ItemTypeDashboardByTag ItemType = "dashboard_by_tag"
ItemTypeDashboardByUid ItemType = "dashboard_by_uid"
// deprecated -- should use UID
ItemTypeDashboardById ItemType = "dashboard_by_id"
)
// Item defines model for Item.
type Item struct {
// Type of the item.
Type ItemType `json:"type"`
// Value depends on type and describes the playlist item.
//
// - dashboard_by_id: The value is an internal numerical identifier set by Grafana. This
// is not portable as the numerical identifier is non-deterministic between different instances.
// Will be replaced by dashboard_by_uid in the future. (deprecated)
// - dashboard_by_tag: The value is a tag which is set on any number of dashboards. All
// dashboards behind the tag will be added to the playlist.
// - dashboard_by_uid: The value is the dashboard UID
Value string `json:"value"`
}
// Type of the item.
type ItemType string

@ -1,74 +0,0 @@
package v0alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/registry/generic"
genericapiserver "k8s.io/apiserver/pkg/server"
common "k8s.io/kube-openapi/pkg/common"
grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/playlist"
"github.com/grafana/grafana/pkg/setting"
)
// GroupName is the group name for this API.
const GroupName = "playlist.grafana.app"
const VersionID = "v0alpha1"
var _ grafanaapiserver.APIGroupBuilder = (*PlaylistAPIBuilder)(nil)
// This is used just so wire has something unique to return
type PlaylistAPIBuilder struct {
service playlist.Service
namespacer request.NamespaceMapper
gv schema.GroupVersion
}
func RegisterAPIService(p playlist.Service,
apiregistration grafanaapiserver.APIRegistrar,
cfg *setting.Cfg,
) *PlaylistAPIBuilder {
builder := &PlaylistAPIBuilder{
service: p,
namespacer: request.GetNamespaceMapper(cfg),
gv: schema.GroupVersion{Group: GroupName, Version: VersionID},
}
apiregistration.RegisterAPI(builder)
return builder
}
func (b *PlaylistAPIBuilder) GetGroupVersion() schema.GroupVersion {
return b.gv
}
func (b *PlaylistAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(b.gv,
&Playlist{},
&PlaylistList{},
)
if err := RegisterConversions(scheme); err != nil {
return err
}
metav1.AddToGroupVersion(scheme, b.gv)
return scheme.SetVersionPriority(b.gv)
}
func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
) (*genericapiserver.APIGroupInfo, error) {
return nil, nil
}
func (b *PlaylistAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
return getOpenAPIDefinitions
}
func (b *PlaylistAPIBuilder) GetAPIRoutes() *grafanaapiserver.APIRoutes {
return nil // no custom API routes
}

@ -1,170 +0,0 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by conversion-gen. DO NOT EDIT.
package v0alpha1
import (
unsafe "unsafe"
playlist "github.com/grafana/grafana/pkg/apis/playlist"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
if err := s.AddGeneratedConversionFunc((*Item)(nil), (*playlist.Item)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v0alpha1_Item_To_playlist_Item(a.(*Item), b.(*playlist.Item), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*playlist.Item)(nil), (*Item)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_playlist_Item_To_v0alpha1_Item(a.(*playlist.Item), b.(*Item), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Playlist)(nil), (*playlist.Playlist)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v0alpha1_Playlist_To_playlist_Playlist(a.(*Playlist), b.(*playlist.Playlist), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*playlist.Playlist)(nil), (*Playlist)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_playlist_Playlist_To_v0alpha1_Playlist(a.(*playlist.Playlist), b.(*Playlist), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*PlaylistList)(nil), (*playlist.PlaylistList)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v0alpha1_PlaylistList_To_playlist_PlaylistList(a.(*PlaylistList), b.(*playlist.PlaylistList), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*playlist.PlaylistList)(nil), (*PlaylistList)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_playlist_PlaylistList_To_v0alpha1_PlaylistList(a.(*playlist.PlaylistList), b.(*PlaylistList), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Spec)(nil), (*playlist.Spec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v0alpha1_Spec_To_playlist_Spec(a.(*Spec), b.(*playlist.Spec), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*playlist.Spec)(nil), (*Spec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_playlist_Spec_To_v0alpha1_Spec(a.(*playlist.Spec), b.(*Spec), scope)
}); err != nil {
return err
}
return nil
}
func autoConvert_v0alpha1_Item_To_playlist_Item(in *Item, out *playlist.Item, s conversion.Scope) error {
out.Type = playlist.ItemType(in.Type)
out.Value = in.Value
return nil
}
// Convert_v0alpha1_Item_To_playlist_Item is an autogenerated conversion function.
func Convert_v0alpha1_Item_To_playlist_Item(in *Item, out *playlist.Item, s conversion.Scope) error {
return autoConvert_v0alpha1_Item_To_playlist_Item(in, out, s)
}
func autoConvert_playlist_Item_To_v0alpha1_Item(in *playlist.Item, out *Item, s conversion.Scope) error {
out.Type = ItemType(in.Type)
out.Value = in.Value
return nil
}
// Convert_playlist_Item_To_v0alpha1_Item is an autogenerated conversion function.
func Convert_playlist_Item_To_v0alpha1_Item(in *playlist.Item, out *Item, s conversion.Scope) error {
return autoConvert_playlist_Item_To_v0alpha1_Item(in, out, s)
}
func autoConvert_v0alpha1_Playlist_To_playlist_Playlist(in *Playlist, out *playlist.Playlist, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v0alpha1_Spec_To_playlist_Spec(&in.Spec, &out.Spec, s); err != nil {
return err
}
return nil
}
// Convert_v0alpha1_Playlist_To_playlist_Playlist is an autogenerated conversion function.
func Convert_v0alpha1_Playlist_To_playlist_Playlist(in *Playlist, out *playlist.Playlist, s conversion.Scope) error {
return autoConvert_v0alpha1_Playlist_To_playlist_Playlist(in, out, s)
}
func autoConvert_playlist_Playlist_To_v0alpha1_Playlist(in *playlist.Playlist, out *Playlist, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_playlist_Spec_To_v0alpha1_Spec(&in.Spec, &out.Spec, s); err != nil {
return err
}
return nil
}
// Convert_playlist_Playlist_To_v0alpha1_Playlist is an autogenerated conversion function.
func Convert_playlist_Playlist_To_v0alpha1_Playlist(in *playlist.Playlist, out *Playlist, s conversion.Scope) error {
return autoConvert_playlist_Playlist_To_v0alpha1_Playlist(in, out, s)
}
func autoConvert_v0alpha1_PlaylistList_To_playlist_PlaylistList(in *PlaylistList, out *playlist.PlaylistList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]playlist.Playlist)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_v0alpha1_PlaylistList_To_playlist_PlaylistList is an autogenerated conversion function.
func Convert_v0alpha1_PlaylistList_To_playlist_PlaylistList(in *PlaylistList, out *playlist.PlaylistList, s conversion.Scope) error {
return autoConvert_v0alpha1_PlaylistList_To_playlist_PlaylistList(in, out, s)
}
func autoConvert_playlist_PlaylistList_To_v0alpha1_PlaylistList(in *playlist.PlaylistList, out *PlaylistList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]Playlist)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_playlist_PlaylistList_To_v0alpha1_PlaylistList is an autogenerated conversion function.
func Convert_playlist_PlaylistList_To_v0alpha1_PlaylistList(in *playlist.PlaylistList, out *PlaylistList, s conversion.Scope) error {
return autoConvert_playlist_PlaylistList_To_v0alpha1_PlaylistList(in, out, s)
}
func autoConvert_v0alpha1_Spec_To_playlist_Spec(in *Spec, out *playlist.Spec, s conversion.Scope) error {
out.Title = in.Title
out.Interval = in.Interval
out.Items = *(*[]playlist.Item)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_v0alpha1_Spec_To_playlist_Spec is an autogenerated conversion function.
func Convert_v0alpha1_Spec_To_playlist_Spec(in *Spec, out *playlist.Spec, s conversion.Scope) error {
return autoConvert_v0alpha1_Spec_To_playlist_Spec(in, out, s)
}
func autoConvert_playlist_Spec_To_v0alpha1_Spec(in *playlist.Spec, out *Spec, s conversion.Scope) error {
out.Title = in.Title
out.Interval = in.Interval
out.Items = *(*[]Item)(unsafe.Pointer(&in.Items))
return nil
}
// Convert_playlist_Spec_To_v0alpha1_Spec is an autogenerated conversion function.
func Convert_playlist_Spec_To_v0alpha1_Spec(in *playlist.Spec, out *Spec, s conversion.Scope) error {
return autoConvert_playlist_Spec_To_v0alpha1_Spec(in, out, s)
}

@ -14,7 +14,7 @@ import (
spec "k8s.io/kube-openapi/pkg/validation/spec"
)
func getOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
return map[string]common.OpenAPIDefinition{
"github.com/grafana/grafana/pkg/apis/playlist/v0alpha1.Item": schema_pkg_apis_playlist_v0alpha1_Item(ref),
"github.com/grafana/grafana/pkg/apis/playlist/v0alpha1.Playlist": schema_pkg_apis_playlist_v0alpha1_Playlist(ref),

@ -1,123 +0,0 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package playlist
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Item) DeepCopyInto(out *Item) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Item.
func (in *Item) DeepCopy() *Item {
if in == nil {
return nil
}
out := new(Item)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Playlist) DeepCopyInto(out *Playlist) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Playlist.
func (in *Playlist) DeepCopy() *Playlist {
if in == nil {
return nil
}
out := new(Playlist)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Playlist) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PlaylistList) DeepCopyInto(out *PlaylistList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Playlist, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlaylistList.
func (in *PlaylistList) DeepCopy() *PlaylistList {
if in == nil {
return nil
}
out := new(PlaylistList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PlaylistList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Spec) DeepCopyInto(out *Spec) {
*out = *in
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Item, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Spec.
func (in *Spec) DeepCopy() *Spec {
if in == nil {
return nil
}
out := new(Spec)
in.DeepCopyInto(out)
return out
}

@ -1,17 +0,0 @@
package apis
import (
"github.com/google/wire"
examplev0alpha1 "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
"github.com/grafana/grafana/pkg/apis/playlist"
playlistsv0alpha1 "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
)
// WireSet is the list of all services
// NOTE: you must also register the service in: pkg/registry/apis/apis.go
var WireSet = wire.NewSet(
playlist.RegisterAPIService,
playlistsv0alpha1.RegisterAPIService,
examplev0alpha1.RegisterAPIService,
)

@ -3,10 +3,9 @@ package apiregistry
import (
"context"
examplev0alpha1 "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
"github.com/grafana/grafana/pkg/apis/playlist"
playlistsv0alpha1 "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/registry/apis/example"
"github.com/grafana/grafana/pkg/registry/apis/playlist"
)
var (
@ -15,12 +14,11 @@ var (
type Service struct{}
// ProvideService is an entry point for each service that will force initialization
// ProvideRegistryServiceSink is an entry point for each service that will force initialization
// and give each builder the chance to register itself with the main server
func ProvideService(
func ProvideRegistryServiceSink(
_ *playlist.PlaylistAPIBuilder,
_ *playlistsv0alpha1.PlaylistAPIBuilder,
_ *examplev0alpha1.TestingAPIBuilder,
_ *example.TestingAPIBuilder,
) *Service {
return &Service{}
}

@ -1,11 +1,9 @@
package v0alpha1
package example
import (
"fmt"
"net/http"
"github.com/grafana/grafana/pkg/services/featuremgmt"
grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@ -19,6 +17,10 @@ import (
common "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/spec3"
"k8s.io/kube-openapi/pkg/validation/spec"
example "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
"github.com/grafana/grafana/pkg/services/featuremgmt"
grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver"
)
// GroupName is the group name for this API.
@ -68,7 +70,7 @@ func (b *TestingAPIBuilder) GetAPIGroupInfo(
}
func (b *TestingAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
return getOpenAPIDefinitions
return example.GetOpenAPIDefinitions
}
// Register additional routes with the server
@ -188,7 +190,7 @@ var (
// Adds the list of known types to the given scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&RuntimeInfo{},
&example.RuntimeInfo{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

@ -1,4 +1,4 @@
package v0alpha1
package example
import (
"context"
@ -9,6 +9,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
example "github.com/grafana/grafana/pkg/apis/example/v0alpha1"
"github.com/grafana/grafana/pkg/setting"
)
@ -20,12 +21,12 @@ var (
)
type staticStorage struct {
info RuntimeInfo
info example.RuntimeInfo
}
func newDeploymentInfoStorage() *staticStorage {
return &staticStorage{
info: RuntimeInfo{
info: example.RuntimeInfo{
TypeMeta: metav1.TypeMeta{
APIVersion: APIVersion,
Kind: "DeploymentInfo",
@ -43,7 +44,7 @@ func newDeploymentInfoStorage() *staticStorage {
}
func (s *staticStorage) New() runtime.Object {
return &RuntimeInfo{}
return &example.RuntimeInfo{}
}
func (s *staticStorage) Destroy() {}
@ -57,7 +58,7 @@ func (s *staticStorage) GetSingularName() string {
}
func (s *staticStorage) NewList() runtime.Object {
return &RuntimeInfo{}
return &example.RuntimeInfo{}
}
func (s *staticStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {

@ -10,14 +10,15 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
playlist "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
"github.com/grafana/grafana/pkg/kinds"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/playlist"
playlistsvc "github.com/grafana/grafana/pkg/services/playlist"
)
func UnstructuredToLegacyPlaylist(item unstructured.Unstructured) *playlist.Playlist {
func UnstructuredToLegacyPlaylist(item unstructured.Unstructured) *playlistsvc.Playlist {
spec := item.Object["spec"].(map[string]any)
return &playlist.Playlist{
return &playlistsvc.Playlist{
UID: item.GetName(),
Name: spec["title"].(string),
Interval: spec["interval"].(string),
@ -25,9 +26,9 @@ func UnstructuredToLegacyPlaylist(item unstructured.Unstructured) *playlist.Play
}
}
func UnstructuredToLegacyPlaylistDTO(item unstructured.Unstructured) *playlist.PlaylistDTO {
func UnstructuredToLegacyPlaylistDTO(item unstructured.Unstructured) *playlistsvc.PlaylistDTO {
spec := item.Object["spec"].(map[string]any)
dto := &playlist.PlaylistDTO{
dto := &playlistsvc.PlaylistDTO{
Uid: item.GetName(),
Name: spec["title"].(string),
Interval: spec["interval"].(string),
@ -43,14 +44,14 @@ func UnstructuredToLegacyPlaylistDTO(item unstructured.Unstructured) *playlist.P
return dto
}
func convertToK8sResource(v *playlist.PlaylistDTO, namespacer request.NamespaceMapper) *Playlist {
spec := Spec{
func convertToK8sResource(v *playlistsvc.PlaylistDTO, namespacer request.NamespaceMapper) *playlist.Playlist {
spec := playlist.Spec{
Title: v.Name,
Interval: v.Interval,
}
for _, item := range v.Items {
spec.Items = append(spec.Items, Item{
Type: ItemType(item.Type),
spec.Items = append(spec.Items, playlist.Item{
Type: playlist.ItemType(item.Type),
Value: item.Value,
})
}
@ -63,7 +64,7 @@ func convertToK8sResource(v *playlist.PlaylistDTO, namespacer request.NamespaceM
Key: fmt.Sprintf("%d", v.Id),
})
}
return &Playlist{
return &playlist.Playlist{
ObjectMeta: metav1.ObjectMeta{
Name: v.Uid,
UID: types.UID(v.Uid),
@ -76,19 +77,19 @@ func convertToK8sResource(v *playlist.PlaylistDTO, namespacer request.NamespaceM
}
}
func convertToLegacyUpdateCommand(p *Playlist, orgId int64) (*playlist.UpdatePlaylistCommand, error) {
func convertToLegacyUpdateCommand(p *playlist.Playlist, orgId int64) (*playlistsvc.UpdatePlaylistCommand, error) {
spec := p.Spec
cmd := &playlist.UpdatePlaylistCommand{
cmd := &playlistsvc.UpdatePlaylistCommand{
UID: p.Name,
Name: spec.Title,
Interval: spec.Interval,
OrgId: orgId,
}
for _, item := range spec.Items {
if item.Type == ItemTypeDashboardById {
if item.Type == playlist.ItemTypeDashboardById {
return nil, fmt.Errorf("unsupported item type: %s", item.Type)
}
cmd.Items = append(cmd.Items, playlist.PlaylistItem{
cmd.Items = append(cmd.Items, playlistsvc.PlaylistItem{
Type: string(item.Type),
Value: item.Value,
})

@ -12,8 +12,9 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/registry/rest"
playlist "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/playlist"
playlistsvc "github.com/grafana/grafana/pkg/services/playlist"
)
var (
@ -28,7 +29,7 @@ var (
)
type legacyStorage struct {
service playlist.Service
service playlistsvc.Service
namespacer request.NamespaceMapper
tableConverter rest.TableConvertor
@ -37,7 +38,7 @@ type legacyStorage struct {
}
func (s *legacyStorage) New() runtime.Object {
return &Playlist{}
return &playlist.Playlist{}
}
func (s *legacyStorage) Destroy() {}
@ -51,7 +52,7 @@ func (s *legacyStorage) GetSingularName() string {
}
func (s *legacyStorage) NewList() runtime.Object {
return &PlaylistList{}
return &playlist.PlaylistList{}
}
func (s *legacyStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
@ -70,7 +71,7 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
if options.Limit > 0 {
limit = int(options.Limit)
}
res, err := s.service.Search(ctx, &playlist.GetPlaylistsQuery{
res, err := s.service.Search(ctx, &playlistsvc.GetPlaylistsQuery{
OrgId: info.OrgID,
Limit: limit,
})
@ -78,9 +79,9 @@ func (s *legacyStorage) List(ctx context.Context, options *internalversion.ListO
return nil, err
}
list := &PlaylistList{}
list := &playlist.PlaylistList{}
for _, v := range res {
p, err := s.service.Get(ctx, &playlist.GetPlaylistByUidQuery{
p, err := s.service.Get(ctx, &playlistsvc.GetPlaylistByUidQuery{
UID: v.UID,
OrgId: info.OrgID,
})
@ -101,12 +102,12 @@ func (s *legacyStorage) Get(ctx context.Context, name string, options *metav1.Ge
return nil, err
}
dto, err := s.service.Get(ctx, &playlist.GetPlaylistByUidQuery{
dto, err := s.service.Get(ctx, &playlistsvc.GetPlaylistByUidQuery{
UID: name,
OrgId: info.OrgID,
})
if err != nil || dto == nil {
if errors.Is(err, playlist.ErrPlaylistNotFound) || err == nil {
if errors.Is(err, playlistsvc.ErrPlaylistNotFound) || err == nil {
err = k8serrors.NewNotFound(s.SingularQualifiedResource, name)
}
return nil, err
@ -125,7 +126,7 @@ func (s *legacyStorage) Create(ctx context.Context,
return nil, err
}
p, ok := obj.(*Playlist)
p, ok := obj.(*playlist.Playlist)
if !ok {
return nil, fmt.Errorf("expected playlist?")
}
@ -133,7 +134,7 @@ func (s *legacyStorage) Create(ctx context.Context,
if err != nil {
return nil, err
}
out, err := s.service.Create(ctx, &playlist.CreatePlaylistCommand{
out, err := s.service.Create(ctx, &playlistsvc.CreatePlaylistCommand{
UID: p.Name,
Name: cmd.Name,
Interval: cmd.Interval,
@ -169,7 +170,7 @@ func (s *legacyStorage) Update(ctx context.Context,
if err != nil {
return old, created, err
}
p, ok := obj.(*Playlist)
p, ok := obj.(*playlist.Playlist)
if !ok {
return nil, created, fmt.Errorf("expected playlist after update")
}
@ -197,11 +198,11 @@ func (s *legacyStorage) Delete(ctx context.Context, name string, deleteValidatio
if err != nil {
return nil, false, err
}
p, ok := v.(*Playlist)
p, ok := v.(*playlist.Playlist)
if !ok {
return v, false, fmt.Errorf("expected a playlist response from Get")
}
err = s.service.Delete(ctx, &playlist.DeletePlaylistCommand{
err = s.service.Delete(ctx, &playlistsvc.DeletePlaylistCommand{
UID: name,
OrgId: info.OrgID,
})

@ -13,28 +13,29 @@ import (
genericapiserver "k8s.io/apiserver/pkg/server"
common "k8s.io/kube-openapi/pkg/common"
playlist "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
grafanarest "github.com/grafana/grafana/pkg/services/grafana-apiserver/rest"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/utils"
"github.com/grafana/grafana/pkg/services/playlist"
playlistsvc "github.com/grafana/grafana/pkg/services/playlist"
"github.com/grafana/grafana/pkg/setting"
)
// GroupName is the group name for this API.
const GroupName = "playlist.grafana.app"
const VersionID = runtime.APIVersionInternal
const VersionID = "v0alpha1"
var _ grafanaapiserver.APIGroupBuilder = (*PlaylistAPIBuilder)(nil)
// This is used just so wire has something unique to return
type PlaylistAPIBuilder struct {
service playlist.Service
service playlistsvc.Service
namespacer request.NamespaceMapper
gv schema.GroupVersion
}
func RegisterAPIService(p playlist.Service,
func RegisterAPIService(p playlistsvc.Service,
apiregistration grafanaapiserver.APIRegistrar,
cfg *setting.Cfg,
) *PlaylistAPIBuilder {
@ -53,10 +54,27 @@ func (b *PlaylistAPIBuilder) GetGroupVersion() schema.GroupVersion {
func (b *PlaylistAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(b.gv,
&Playlist{},
&PlaylistList{},
&playlist.Playlist{},
&playlist.PlaylistList{},
)
return nil
// Link this version to the internal representation.
// This is used for server-side-apply (PATCH), and avoids the error:
// "no kind is registered for the type"
scheme.AddKnownTypes(schema.GroupVersion{
Group: b.gv.Group,
Version: runtime.APIVersionInternal,
},
&playlist.Playlist{},
&playlist.PlaylistList{},
)
// If multiple versions exist, then register conversions from zz_generated.conversion.go
// if err := playlist.RegisterConversions(scheme); err != nil {
// return err
// }
metav1.AddToGroupVersion(scheme, b.gv)
return scheme.SetVersionPriority(b.gv)
}
func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
@ -82,7 +100,7 @@ func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
{Name: "Created At", Type: "date"},
},
func(obj runtime.Object) ([]interface{}, error) {
m, ok := obj.(*Playlist)
m, ok := obj.(*playlist.Playlist)
if !ok {
return nil, fmt.Errorf("expected playlist")
}
@ -105,12 +123,12 @@ func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
storage["playlists"] = grafanarest.NewDualWriter(legacyStore, store)
}
apiGroupInfo.VersionedResourcesStorageMap["v0alpha1"] = storage
apiGroupInfo.VersionedResourcesStorageMap[VersionID] = storage
return &apiGroupInfo, nil
}
func (b *PlaylistAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
return nil // no custom OpenAPI definitions
return playlist.GetOpenAPIDefinitions
}
func (b *PlaylistAPIBuilder) GetAPIRoutes() *grafanaapiserver.APIRoutes {

@ -5,6 +5,7 @@ import (
"k8s.io/apiserver/pkg/registry/generic"
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
playlist "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
grafanaregistry "github.com/grafana/grafana/pkg/services/grafana-apiserver/registry/generic"
grafanarest "github.com/grafana/grafana/pkg/services/grafana-apiserver/rest"
)
@ -19,8 +20,8 @@ func newStorage(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, le
strategy := grafanaregistry.NewStrategy(scheme)
store := &genericregistry.Store{
NewFunc: func() runtime.Object { return &Playlist{} },
NewListFunc: func() runtime.Object { return &PlaylistList{} },
NewFunc: func() runtime.Object { return &playlist.Playlist{} },
NewListFunc: func() runtime.Object { return &playlist.PlaylistList{} },
PredicateFunc: grafanaregistry.Matcher,
DefaultQualifiedResource: legacy.DefaultQualifiedResource,
SingularQualifiedResource: legacy.SingularQualifiedResource,

@ -3,10 +3,15 @@ package apiregistry
import (
"github.com/google/wire"
"github.com/grafana/grafana/pkg/apis"
"github.com/grafana/grafana/pkg/registry/apis/example"
"github.com/grafana/grafana/pkg/registry/apis/playlist"
)
var WireSet = wire.NewSet(
ProvideService,
apis.WireSet,
ProvideRegistryServiceSink, // dummy background service that forces registration
// Each must be added here *and* in the ServiceSink above
// playlistV0.RegisterAPIService,
playlist.RegisterAPIService,
example.RegisterAPIService,
)

@ -307,7 +307,7 @@ func (s *service) start(ctx context.Context) error {
if err != nil {
return err
}
if g == nil {
if g == nil || len(g.PrioritizedVersions) < 1 {
continue
}
err = server.InstallAPIGroup(g)

Loading…
Cancel
Save