mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 09:33:34 -06:00
parent
aadd5bacfa
commit
0f398e940d
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -67,6 +67,7 @@
|
||||
/scripts/modowners/ @grafana/backend-platform
|
||||
|
||||
/pkg/api/ @grafana/backend-platform
|
||||
/pkg/apis/ @grafana/grafana-app-platform-squad
|
||||
/pkg/bus/ @grafana/backend-platform
|
||||
/pkg/cmd/ @grafana/backend-platform
|
||||
/pkg/components/apikeygen/ @grafana/grafana-authnz-team
|
||||
|
14
pkg/apis/install/install.go
Normal file
14
pkg/apis/install/install.go
Normal file
@ -0,0 +1,14 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
||||
playlistv1 "github.com/grafana/grafana/pkg/apis/playlist/v1"
|
||||
)
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(scheme *runtime.Scheme) {
|
||||
utilruntime.Must(playlistv1.AddToScheme(scheme))
|
||||
utilruntime.Must(scheme.SetVersionPriority(playlistv1.SchemeGroupVersion))
|
||||
}
|
5
pkg/apis/playlist/v1/doc.go
Normal file
5
pkg/apis/playlist/v1/doc.go
Normal file
@ -0,0 +1,5 @@
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +groupName=playlist.grafana.io
|
||||
|
||||
package v1 // import "github.com/grafana/grafana/pkg/apis/playlist/v1"
|
76
pkg/apis/playlist/v1/handler.go
Normal file
76
pkg/apis/playlist/v1/handler.go
Normal file
@ -0,0 +1,76 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
)
|
||||
|
||||
var _ rest.Scoper = (*Handler)(nil)
|
||||
var _ rest.SingularNameProvider = (*Handler)(nil)
|
||||
var _ rest.Getter = (*Handler)(nil)
|
||||
var _ rest.Lister = (*Handler)(nil)
|
||||
var _ rest.Storage = (*Handler)(nil)
|
||||
|
||||
type Handler struct{}
|
||||
|
||||
func (r *Handler) New() runtime.Object {
|
||||
return &Playlist{}
|
||||
}
|
||||
|
||||
func (r *Handler) Destroy() {}
|
||||
|
||||
func (r *Handler) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *Handler) GetSingularName() string {
|
||||
return "playlist"
|
||||
}
|
||||
|
||||
func (r *Handler) NewList() runtime.Object {
|
||||
return &PlaylistList{}
|
||||
}
|
||||
|
||||
func (r *Handler) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
||||
return rest.NewDefaultTableConvertor(Resource("playlists")).ConvertToTable(ctx, object, tableOptions)
|
||||
}
|
||||
|
||||
func (r *Handler) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
||||
// TODO: replace
|
||||
return &PlaylistList{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "PlaylistList",
|
||||
APIVersion: "playlist.grafana.io/v1",
|
||||
},
|
||||
Items: []Playlist{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Playlist",
|
||||
APIVersion: "playlist.grafana.io/v1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
},
|
||||
Name: "test",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Handler) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
// TODO: replace
|
||||
return &Playlist{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Playlist",
|
||||
APIVersion: "playlist.grafana.io/v1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Name: "test",
|
||||
}, nil
|
||||
}
|
36
pkg/apis/playlist/v1/register.go
Normal file
36
pkg/apis/playlist/v1/register.go
Normal file
@ -0,0 +1,36 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name for this API.
|
||||
const GroupName = "playlist.grafana.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// SchemeBuilder points to a list of functions added to Scheme.
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
// AddToScheme is a common registration function for mapping packaged scoped group & version keys to a scheme.
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to the given scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Playlist{},
|
||||
&PlaylistList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
27
pkg/apis/playlist/v1/types.go
Normal file
27
pkg/apis/playlist/v1/types.go
Normal file
@ -0,0 +1,27 @@
|
||||
package v1
|
||||
|
||||
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"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type PlaylistList 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"`
|
||||
|
||||
Items []Playlist `json:"playlists,omitempty"`
|
||||
}
|
87
pkg/apis/playlist/v1/zz_generated.deepcopy.go
Normal file
87
pkg/apis/playlist/v1/zz_generated.deepcopy.go
Normal file
@ -0,0 +1,87 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// generated by scripts/k8s/update-codegen.sh
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
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 *Playlist) DeepCopyInto(out *Playlist) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
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.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
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 *Handler) DeepCopyInto(out *Handler) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Storage.
|
||||
func (in *Handler) DeepCopy() *Handler {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Handler)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -4,27 +4,29 @@ import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/grafana/dskit/services"
|
||||
kindsv1 "github.com/grafana/grafana-apiserver/pkg/apis/kinds/v1"
|
||||
grafanaapiserver "github.com/grafana/grafana-apiserver/pkg/apiserver"
|
||||
"github.com/grafana/grafana-apiserver/pkg/certgenerator"
|
||||
grafanaapiserveroptions "github.com/grafana/grafana-apiserver/pkg/cmd/server/options"
|
||||
"github.com/grafana/grafana-apiserver/pkg/storage/filepath"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/client-go/rest"
|
||||
clientrest "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apis/install"
|
||||
playlistv1 "github.com/grafana/grafana/pkg/apis/playlist/v1"
|
||||
"github.com/grafana/grafana/pkg/modules"
|
||||
)
|
||||
|
||||
@ -37,18 +39,41 @@ var (
|
||||
_ RestConfigProvider = (*service)(nil)
|
||||
)
|
||||
|
||||
var (
|
||||
Scheme = runtime.NewScheme()
|
||||
Codecs = serializer.NewCodecFactory(Scheme)
|
||||
|
||||
// if you modify this, make sure you update the crEncoder
|
||||
unversionedVersion = schema.GroupVersion{Group: "", Version: "v1"}
|
||||
unversionedTypes = []runtime.Object{
|
||||
&metav1.Status{},
|
||||
&metav1.WatchEvent{},
|
||||
&metav1.APIVersions{},
|
||||
&metav1.APIGroupList{},
|
||||
&metav1.APIGroup{},
|
||||
&metav1.APIResourceList{},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
install.Install(Scheme)
|
||||
// we need to add the options to empty v1
|
||||
metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Group: "", Version: "v1"})
|
||||
Scheme.AddUnversionedTypes(unversionedVersion, unversionedTypes...)
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
services.NamedService
|
||||
}
|
||||
|
||||
type RestConfigProvider interface {
|
||||
GetRestConfig() *rest.Config
|
||||
GetRestConfig() *clientrest.Config
|
||||
}
|
||||
|
||||
type service struct {
|
||||
*services.BasicService
|
||||
|
||||
restConfig *rest.Config
|
||||
restConfig *clientrest.Config
|
||||
|
||||
dataPath string
|
||||
stopCh chan struct{}
|
||||
@ -66,7 +91,7 @@ func New(dataPath string) (*service, error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *service) GetRestConfig() *rest.Config {
|
||||
func (s *service) GetRestConfig() *clientrest.Config {
|
||||
return s.restConfig
|
||||
}
|
||||
|
||||
@ -75,15 +100,15 @@ func (s *service) start(ctx context.Context) error {
|
||||
logger.V(9)
|
||||
klog.SetLoggerWithOptions(logger, klog.ContextualLogger(true))
|
||||
|
||||
o := grafanaapiserveroptions.NewGrafanaAPIServerOptions(os.Stdout, os.Stderr)
|
||||
o.RecommendedOptions.SecureServing.BindPort = 6443
|
||||
o.RecommendedOptions.Authentication.RemoteKubeConfigFileOptional = true
|
||||
o.RecommendedOptions.Authorization.RemoteKubeConfigFileOptional = true
|
||||
o.RecommendedOptions.Authorization.AlwaysAllowPaths = []string{"*"}
|
||||
o.RecommendedOptions.Authorization.AlwaysAllowGroups = []string{user.SystemPrivilegedGroup, "grafana"}
|
||||
o.RecommendedOptions.Etcd = nil
|
||||
o.RecommendedOptions.Admission = nil
|
||||
o.RecommendedOptions.CoreAPI = nil
|
||||
o := options.NewRecommendedOptions("", unstructured.UnstructuredJSONScheme)
|
||||
o.SecureServing.BindPort = 6443
|
||||
o.Authentication.RemoteKubeConfigFileOptional = true
|
||||
o.Authorization.RemoteKubeConfigFileOptional = true
|
||||
o.Authorization.AlwaysAllowPaths = []string{"*"}
|
||||
o.Authorization.AlwaysAllowGroups = []string{user.SystemPrivilegedGroup, "grafana"}
|
||||
o.Etcd = nil
|
||||
o.Admission = nil
|
||||
o.CoreAPI = nil
|
||||
|
||||
// Get the util to get the paths to pre-generated certs
|
||||
certUtil := certgenerator.CertUtil{
|
||||
@ -98,21 +123,18 @@ func (s *service) start(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
o.RecommendedOptions.SecureServing.BindAddress = net.ParseIP(certgenerator.DefaultAPIServerIp)
|
||||
o.RecommendedOptions.SecureServing.ServerCert.CertKey = options.CertKey{
|
||||
o.SecureServing.BindAddress = net.ParseIP(certgenerator.DefaultAPIServerIp)
|
||||
o.SecureServing.ServerCert.CertKey = options.CertKey{
|
||||
CertFile: certUtil.APIServerCertFile(),
|
||||
KeyFile: certUtil.APIServerKeyFile(),
|
||||
}
|
||||
|
||||
if err := o.Complete(); err != nil {
|
||||
return err
|
||||
if err := o.Validate(); len(err) > 0 {
|
||||
return err[0]
|
||||
}
|
||||
|
||||
if err := o.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serverConfig, err := o.Config()
|
||||
serverConfig := genericapiserver.NewRecommendedConfig(Codecs)
|
||||
err := o.ApplyTo(serverConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -122,29 +144,34 @@ func (s *service) start(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
serverConfig.ExtraConfig.RESTOptionsGetter = filepath.NewRESTOptionsGetter(s.dataPath, unstructured.UnstructuredJSONScheme)
|
||||
serverConfig.GenericConfig.RESTOptionsGetter = filepath.NewRESTOptionsGetter(s.dataPath, grafanaapiserver.Codecs.LegacyCodec(kindsv1.SchemeGroupVersion))
|
||||
serverConfig.GenericConfig.Config.RESTOptionsGetter = filepath.NewRESTOptionsGetter(s.dataPath, grafanaapiserver.Codecs.LegacyCodec(kindsv1.SchemeGroupVersion))
|
||||
|
||||
authenticator, err := newAuthenticator(rootCert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serverConfig.GenericConfig.Authentication.Authenticator = authenticator
|
||||
serverConfig.Authentication.Authenticator = authenticator
|
||||
|
||||
server, err := serverConfig.Complete().New(genericapiserver.NewEmptyDelegate())
|
||||
server, err := serverConfig.Complete().New("grafana-apiserver", genericapiserver.NewEmptyDelegate())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.restConfig = server.GenericAPIServer.LoopbackClientConfig
|
||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(playlistv1.GroupName, Scheme, metav1.ParameterCodec, Codecs)
|
||||
playlistv1storage := map[string]rest.Storage{}
|
||||
playlistv1storage["playlists"] = &playlistv1.Handler{}
|
||||
|
||||
apiGroupInfo.VersionedResourcesStorageMap["v1"] = playlistv1storage
|
||||
if err := server.InstallAPIGroup(&apiGroupInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.restConfig = server.LoopbackClientConfig
|
||||
err = s.writeKubeConfiguration(s.restConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
prepared := server.GenericAPIServer.PrepareRun()
|
||||
prepared := server.PrepareRun()
|
||||
|
||||
// TODO: not sure if we can still inject RouteRegister with the new module server setup
|
||||
// Disabling the /k8s endpoint until we have a solution
|
||||
@ -192,7 +219,7 @@ func (s *service) running(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) writeKubeConfiguration(restConfig *rest.Config) error {
|
||||
func (s *service) writeKubeConfiguration(restConfig *clientrest.Config) error {
|
||||
clusters := make(map[string]*clientcmdapi.Cluster)
|
||||
clusters["default-cluster"] = &clientcmdapi.Cluster{
|
||||
Server: restConfig.Host,
|
||||
|
Loading…
Reference in New Issue
Block a user