Playlist: Add internal API version (#77318)

This commit is contained in:
Todd Treece
2023-11-01 09:44:04 -04:00
committed by GitHub
parent e8f0f6b7c8
commit 384f5ccdc6
17 changed files with 553 additions and 68 deletions

View File

@@ -12,7 +12,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/apis/playlist/v0alpha1" internalplaylist "github.com/grafana/grafana/pkg/apis/playlist"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/featuremgmt"
@@ -49,8 +49,8 @@ func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
if hs.Features.IsEnabled(featuremgmt.FlagKubernetesPlaylistsAPI) { if hs.Features.IsEnabled(featuremgmt.FlagKubernetesPlaylistsAPI) {
namespacer := request.GetNamespaceMapper(hs.Cfg) namespacer := request.GetNamespaceMapper(hs.Cfg)
gvr := schema.GroupVersionResource{ gvr := schema.GroupVersionResource{
Group: v0alpha1.GroupName, Group: internalplaylist.GroupName,
Version: v0alpha1.VersionID, Version: internalplaylist.VersionID,
Resource: "playlists", Resource: "playlists",
} }
@@ -88,7 +88,7 @@ func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
query := strings.ToUpper(c.Query("query")) query := strings.ToUpper(c.Query("query"))
playlists := []playlist.Playlist{} playlists := []playlist.Playlist{}
for _, item := range out.Items { for _, item := range out.Items {
p := v0alpha1.UnstructuredToLegacyPlaylist(item) p := internalplaylist.UnstructuredToLegacyPlaylist(item)
if p == nil { if p == nil {
continue continue
} }
@@ -111,7 +111,7 @@ func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
errorWriter(c, err) errorWriter(c, err)
return return
} }
c.JSON(http.StatusOK, v0alpha1.UnstructuredToLegacyPlaylistDTO(*out)) c.JSON(http.StatusOK, internalplaylist.UnstructuredToLegacyPlaylistDTO(*out))
}} }}
handler.GetPlaylistItems = []web.Handler{func(c *contextmodel.ReqContext) { handler.GetPlaylistItems = []web.Handler{func(c *contextmodel.ReqContext) {
@@ -125,7 +125,7 @@ func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
errorWriter(c, err) errorWriter(c, err)
return return
} }
c.JSON(http.StatusOK, v0alpha1.UnstructuredToLegacyPlaylistDTO(*out).Items) c.JSON(http.StatusOK, internalplaylist.UnstructuredToLegacyPlaylistDTO(*out).Items)
}} }}
} }

View File

@@ -1,4 +1,4 @@
package v0alpha1 package playlist
import ( import (
"encoding/json" "encoding/json"

View File

@@ -1,4 +1,4 @@
package v0alpha1 package playlist
import ( import (
"encoding/json" "encoding/json"

4
pkg/apis/playlist/doc.go Normal file
View File

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

View File

@@ -1,4 +1,4 @@
package v0alpha1 package playlist
import ( import (
"context" "context"

View File

@@ -0,0 +1,118 @@
package playlist
import (
"fmt"
"time"
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"
"k8s.io/apiserver/pkg/registry/rest"
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"
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"
"github.com/grafana/grafana/pkg/setting"
)
// GroupName is the group name for this API.
const GroupName = "playlist.grafana.app"
const VersionID = runtime.APIVersionInternal
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{},
)
return nil
}
func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(GroupName, scheme, metav1.ParameterCodec, codecs)
storage := map[string]rest.Storage{}
legacyStore := &legacyStorage{
service: b.service,
namespacer: b.namespacer,
DefaultQualifiedResource: b.gv.WithResource("playlists").GroupResource(),
SingularQualifiedResource: b.gv.WithResource("playlist").GroupResource(),
}
legacyStore.tableConverter = utils.NewTableConverter(
legacyStore.DefaultQualifiedResource,
[]metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name"},
{Name: "Title", Type: "string", Format: "string", Description: "The playlist name"},
{Name: "Interval", Type: "string", Format: "string", Description: "How often the playlist will update"},
{Name: "Created At", Type: "date"},
},
func(obj runtime.Object) ([]interface{}, error) {
m, ok := obj.(*Playlist)
if !ok {
return nil, fmt.Errorf("expected playlist")
}
return []interface{}{
m.Name,
m.Spec.Title,
m.Spec.Interval,
m.CreationTimestamp.UTC().Format(time.RFC3339),
}, nil
},
)
storage["playlists"] = legacyStore
// enable dual writes if a RESTOptionsGetter is provided
if optsGetter != nil {
store, err := newStorage(scheme, optsGetter, legacyStore)
if err != nil {
return nil, err
}
storage["playlists"] = grafanarest.NewDualWriter(legacyStore, store)
}
apiGroupInfo.VersionedResourcesStorageMap["v0alpha1"] = storage
return &apiGroupInfo, nil
}
func (b *PlaylistAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
return nil // no custom OpenAPI definitions
}
func (b *PlaylistAPIBuilder) GetAPIRoutes() *grafanaapiserver.APIRoutes {
return nil // no custom API routes
}

View File

@@ -1,4 +1,4 @@
package v0alpha1 package playlist
import ( import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"

View File

@@ -0,0 +1,65 @@
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

View File

@@ -1,22 +1,16 @@
package v0alpha1 package v0alpha1
import ( import (
"fmt"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
common "k8s.io/kube-openapi/pkg/common" common "k8s.io/kube-openapi/pkg/common"
grafanaapiserver "github.com/grafana/grafana/pkg/services/grafana-apiserver" 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/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" "github.com/grafana/grafana/pkg/services/playlist"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
@@ -56,6 +50,9 @@ func (b *PlaylistAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
&Playlist{}, &Playlist{},
&PlaylistList{}, &PlaylistList{},
) )
if err := RegisterConversions(scheme); err != nil {
return err
}
metav1.AddToGroupVersion(scheme, b.gv) metav1.AddToGroupVersion(scheme, b.gv)
return scheme.SetVersionPriority(b.gv) return scheme.SetVersionPriority(b.gv)
} }
@@ -65,49 +62,7 @@ func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
codecs serializer.CodecFactory, // pointer? codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter, optsGetter generic.RESTOptionsGetter,
) (*genericapiserver.APIGroupInfo, error) { ) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(GroupName, scheme, metav1.ParameterCodec, codecs) return nil, nil
storage := map[string]rest.Storage{}
legacyStore := &legacyStorage{
service: b.service,
namespacer: b.namespacer,
DefaultQualifiedResource: b.gv.WithResource("playlists").GroupResource(),
SingularQualifiedResource: b.gv.WithResource("playlist").GroupResource(),
}
legacyStore.tableConverter = utils.NewTableConverter(
legacyStore.DefaultQualifiedResource,
[]metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name"},
{Name: "Title", Type: "string", Format: "string", Description: "The playlist name"},
{Name: "Interval", Type: "string", Format: "string", Description: "How often the playlist will update"},
{Name: "Created At", Type: "date"},
},
func(obj runtime.Object) ([]interface{}, error) {
m, ok := obj.(*Playlist)
if !ok {
return nil, fmt.Errorf("expected playlist")
}
return []interface{}{
m.Name,
m.Spec.Title,
m.Spec.Interval,
m.CreationTimestamp.UTC().Format(time.RFC3339),
}, nil
},
)
storage["playlists"] = legacyStore
// enable dual writes if a RESTOptionsGetter is provided
if optsGetter != nil {
store, err := newStorage(scheme, optsGetter, legacyStore)
if err != nil {
return nil, err
}
storage["playlists"] = grafanarest.NewDualWriter(legacyStore, store)
}
apiGroupInfo.VersionedResourcesStorageMap[VersionID] = storage
return &apiGroupInfo, nil
} }
func (b *PlaylistAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions { func (b *PlaylistAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@@ -0,0 +1,170 @@
//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)
}

View File

@@ -1,7 +1,21 @@
//go:build !ignore_autogenerated //go:build !ignore_autogenerated
// +build !ignore_autogenerated // +build !ignore_autogenerated
// SPDX-License-Identifier: AGPL-3.0-only /*
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. // Code generated by deepcopy-gen. DO NOT EDIT.

View File

@@ -0,0 +1,33 @@
//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 defaulter-gen. DO NOT EDIT.
package v0alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
return nil
}

View File

@@ -0,0 +1,123 @@
//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
}

View File

@@ -4,12 +4,14 @@ import (
"github.com/google/wire" "github.com/google/wire"
examplev0alpha1 "github.com/grafana/grafana/pkg/apis/example/v0alpha1" 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" playlistsv0alpha1 "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
) )
// WireSet is the list of all services // WireSet is the list of all services
// NOTE: you must also register the service in: pkg/registry/apis/apis.go // NOTE: you must also register the service in: pkg/registry/apis/apis.go
var WireSet = wire.NewSet( var WireSet = wire.NewSet(
playlist.RegisterAPIService,
playlistsv0alpha1.RegisterAPIService, playlistsv0alpha1.RegisterAPIService,
examplev0alpha1.RegisterAPIService, examplev0alpha1.RegisterAPIService,
) )

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
examplev0alpha1 "github.com/grafana/grafana/pkg/apis/example/v0alpha1" 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" playlistsv0alpha1 "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
"github.com/grafana/grafana/pkg/registry" "github.com/grafana/grafana/pkg/registry"
) )
@@ -17,6 +18,7 @@ type Service struct{}
// ProvideService is an entry point for each service that will force initialization // ProvideService is an entry point for each service that will force initialization
// and give each builder the chance to register itself with the main server // and give each builder the chance to register itself with the main server
func ProvideService( func ProvideService(
_ *playlist.PlaylistAPIBuilder,
_ *playlistsv0alpha1.PlaylistAPIBuilder, _ *playlistsv0alpha1.PlaylistAPIBuilder,
_ *examplev0alpha1.TestingAPIBuilder, _ *examplev0alpha1.TestingAPIBuilder,
) *Service { ) *Service {

View File

@@ -307,6 +307,9 @@ func (s *service) start(ctx context.Context) error {
if err != nil { if err != nil {
return err return err
} }
if g == nil {
continue
}
err = server.InstallAPIGroup(g) err = server.InstallAPIGroup(g)
if err != nil { if err != nil {
return err return err

View File

@@ -287,7 +287,10 @@ func (s *Storage) Watch(ctx context.Context, key string, opts storage.ListOption
// match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. // match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'.
func (s *Storage) Get(ctx context.Context, key string, opts storage.GetOptions, objPtr runtime.Object) error { func (s *Storage) Get(ctx context.Context, key string, opts storage.GetOptions, objPtr runtime.Object) error {
filename := s.filePath(key) filename := s.filePath(key)
if !exists(filename) { obj, err := readFile(s.codec, filename, func() runtime.Object {
return objPtr
})
if err != nil {
if opts.IgnoreNotFound { if opts.IgnoreNotFound {
return runtime.SetZeroValue(objPtr) return runtime.SetZeroValue(objPtr)
} }
@@ -298,13 +301,6 @@ func (s *Storage) Get(ctx context.Context, key string, opts storage.GetOptions,
return storage.NewKeyNotFoundError(key, int64(rv)) return storage.NewKeyNotFoundError(key, int64(rv))
} }
obj, err := readFile(s.codec, filename, func() runtime.Object {
return objPtr
})
if err != nil {
return err
}
currentVersion, err := s.Versioner().ObjectResourceVersion(obj) currentVersion, err := s.Versioner().ObjectResourceVersion(obj)
if err != nil { if err != nil {
return err return err