mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
K8s: Use grafana executable for standalone api service (#77904)
Co-authored-by: Dan Cech <dcech@grafana.com>
This commit is contained in:
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -69,7 +69,7 @@
|
|||||||
/pkg/apis/ @grafana/grafana-app-platform-squad
|
/pkg/apis/ @grafana/grafana-app-platform-squad
|
||||||
/pkg/bus/ @grafana/backend-platform
|
/pkg/bus/ @grafana/backend-platform
|
||||||
/pkg/cmd/ @grafana/backend-platform
|
/pkg/cmd/ @grafana/backend-platform
|
||||||
/pkg/cmd/grafana-example-apiserver @grafana/grafana-app-platform-squad
|
/pkg/cmd/grafana/apiserver @grafana/grafana-app-platform-squad
|
||||||
/pkg/components/apikeygen/ @grafana/identity-access-team
|
/pkg/components/apikeygen/ @grafana/identity-access-team
|
||||||
/pkg/components/satokengen/ @grafana/identity-access-team
|
/pkg/components/satokengen/ @grafana/identity-access-team
|
||||||
/pkg/components/dashdiffs/ @grafana/backend-platform
|
/pkg/components/dashdiffs/ @grafana/backend-platform
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -78,7 +78,7 @@ public/css/*.min.css
|
|||||||
/data/*
|
/data/*
|
||||||
/bin/*
|
/bin/*
|
||||||
|
|
||||||
# any certificates generated by grafana-example-apiserver
|
# any certificates generated by grafana apiserver
|
||||||
apiserver.local.config/
|
apiserver.local.config/
|
||||||
|
|
||||||
# devenv
|
# devenv
|
||||||
|
|||||||
6
Makefile
6
Makefile
@@ -7,7 +7,7 @@ WIRE_TAGS = "oss"
|
|||||||
-include local/Makefile
|
-include local/Makefile
|
||||||
include .bingo/Variables.mk
|
include .bingo/Variables.mk
|
||||||
|
|
||||||
.PHONY: all deps-go deps-js deps build-go build-backend build-example-apiserver build-server build-cli build-js build build-docker-full build-docker-full-ubuntu lint-go golangci-lint test-go test-js gen-ts test run run-frontend clean devenv devenv-down protobuf drone help gen-go gen-cue fix-cue
|
.PHONY: all deps-go deps-js deps build-go build-backend build-server build-cli build-js build build-docker-full build-docker-full-ubuntu lint-go golangci-lint test-go test-js gen-ts test run run-frontend clean devenv devenv-down protobuf drone help gen-go gen-cue fix-cue
|
||||||
|
|
||||||
GO = go
|
GO = go
|
||||||
GO_FILES ?= ./pkg/...
|
GO_FILES ?= ./pkg/...
|
||||||
@@ -132,10 +132,6 @@ build-server: ## Build Grafana server.
|
|||||||
@echo "build server"
|
@echo "build server"
|
||||||
$(GO) run build.go $(GO_BUILD_FLAGS) build-server
|
$(GO) run build.go $(GO_BUILD_FLAGS) build-server
|
||||||
|
|
||||||
build-example-apiserver: ## Build Grafana example-apiserver application.
|
|
||||||
@echo "build grafana-cli"
|
|
||||||
$(GO) run build.go $(GO_BUILD_FLAGS) build-example-apiserver
|
|
||||||
|
|
||||||
build-cli: ## Build Grafana CLI application.
|
build-cli: ## Build Grafana CLI application.
|
||||||
@echo "build grafana-cli"
|
@echo "build grafana-cli"
|
||||||
$(GO) run build.go $(GO_BUILD_FLAGS) build-cli
|
$(GO) run build.go $(GO_BUILD_FLAGS) build-cli
|
||||||
|
|||||||
@@ -17,13 +17,12 @@ const (
|
|||||||
GoOSWindows = "windows"
|
GoOSWindows = "windows"
|
||||||
GoOSLinux = "linux"
|
GoOSLinux = "linux"
|
||||||
|
|
||||||
BackendBinary = "grafana"
|
BackendBinary = "grafana"
|
||||||
ExampleAPIServerBinary = "grafana-example-apiserver"
|
ServerBinary = "grafana-server"
|
||||||
ServerBinary = "grafana-server"
|
CLIBinary = "grafana-cli"
|
||||||
CLIBinary = "grafana-cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var binaries = []string{BackendBinary, ExampleAPIServerBinary, ServerBinary, CLIBinary}
|
var binaries = []string{BackendBinary, ServerBinary, CLIBinary}
|
||||||
|
|
||||||
func logError(message string, err error) int {
|
func logError(message string, err error) int {
|
||||||
log.Println(message, err)
|
log.Println(message, err)
|
||||||
@@ -86,13 +85,6 @@ func RunCmd() int {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
case "build-example-apiserver":
|
|
||||||
clean(opts)
|
|
||||||
if err := doBuild("grafana-example-apiserver", "./pkg/cmd/grafana-example-apiserver", opts); err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
case "build-cli":
|
case "build-cli":
|
||||||
clean(opts)
|
clean(opts)
|
||||||
if err := doBuild("grafana-cli", "./pkg/cmd/grafana-cli", opts); err != nil {
|
if err := doBuild("grafana-cli", "./pkg/cmd/grafana-cli", opts); err != nil {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/build/golangutils"
|
"github.com/grafana/grafana/pkg/build/golangutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var binaries = []string{"grafana", "grafana-example-apiserver", "grafana-server", "grafana-cli"}
|
var binaries = []string{"grafana", "grafana-server", "grafana-cli"}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SuffixEnterprise2 = "-enterprise2"
|
SuffixEnterprise2 = "-enterprise2"
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
|
||||||
"k8s.io/component-base/cli"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCommandStartExampleAPIServer(defaults *ExampleServerOptions, stopCh <-chan struct{}) *cobra.Command {
|
|
||||||
o := *defaults
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Short: "Launch the example API server",
|
|
||||||
Long: "Launch the example API server",
|
|
||||||
RunE: func(c *cobra.Command, args []string) error {
|
|
||||||
if err := o.Complete(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
config, err := o.Config()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := o.RunExampleServer(config, stopCh); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
flags := cmd.Flags()
|
|
||||||
o.RecommendedOptions.AddFlags(flags)
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
stopCh := genericapiserver.SetupSignalHandler()
|
|
||||||
options, err := NewExampleServerOptions(os.Stdout, os.Stderr)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := NewCommandStartExampleAPIServer(options, stopCh)
|
|
||||||
|
|
||||||
code := cli.Run(cmd)
|
|
||||||
os.Exit(code)
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# grafana-example-apiserver
|
# grafana apiserver (standalone)
|
||||||
|
|
||||||
The example-apiserver closely resembles the
|
The example-apiserver closely resembles the
|
||||||
[sample-apiserver](https://github.com/kubernetes/sample-apiserver/tree/master) project in code and thus
|
[sample-apiserver](https://github.com/kubernetes/sample-apiserver/tree/master) project in code and thus
|
||||||
@@ -19,7 +19,7 @@ can be used as a root server for this example-apiserver (in aggregated mode). He
|
|||||||
kind cluster and that you can provide its kubeconfig in the parameters to the example-apiserver.
|
kind cluster and that you can provide its kubeconfig in the parameters to the example-apiserver.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
go run ./pkg/cmd/grafana-example-apiserver \
|
go run ./pkg/cmd/grafana apiserver example.grafana.app\
|
||||||
--authentication-kubeconfig ~/.kube/config \
|
--authentication-kubeconfig ~/.kube/config \
|
||||||
--authorization-kubeconfig ~/.kube/config \
|
--authorization-kubeconfig ~/.kube/config \
|
||||||
--kubeconfig ~/.kube/config \
|
--kubeconfig ~/.kube/config \
|
||||||
75
pkg/cmd/grafana/apiserver/cmd.go
Normal file
75
pkg/cmd/grafana/apiserver/cmd.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package apiserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
|
"k8s.io/apiserver/pkg/server/options"
|
||||||
|
"k8s.io/component-base/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCommandStartExampleAPIServer(o *ExampleServerOptions, stopCh <-chan struct{}) *cobra.Command {
|
||||||
|
// While this exists as an experimental feature, we require adding the scarry looking command line
|
||||||
|
devAcknowledgementFlag := "grafana-enable-experimental-apiserver"
|
||||||
|
devAcknowledgementNotice := "The apiserver command is in heavy development. The entire setup is subject to change without notice"
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "apiserver [api group(s)]",
|
||||||
|
Short: "Run the grafana apiserver",
|
||||||
|
Long: "Run a standalone kubernetes based apiserver that can be aggregated by a root apiserver. " +
|
||||||
|
devAcknowledgementNotice,
|
||||||
|
Example: fmt.Sprintf("grafana apiserver example.grafana.app --%s", devAcknowledgementFlag),
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
ok, err := cmd.Flags().GetBool(devAcknowledgementFlag)
|
||||||
|
if !ok || err != nil {
|
||||||
|
fmt.Printf("requires running with the flag: --%s\n\n%s\n\n",
|
||||||
|
devAcknowledgementFlag, devAcknowledgementNotice)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RunE: func(c *cobra.Command, args []string) error {
|
||||||
|
// Load each group from the args
|
||||||
|
if err := o.LoadAPIGroupBuilders(args[1:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish the config (applies all defaults)
|
||||||
|
if err := o.Complete(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := o.Config()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.RunExampleServer(config, stopCh); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register grafana flags
|
||||||
|
cmd.PersistentFlags().Bool(devAcknowledgementFlag, false, devAcknowledgementNotice)
|
||||||
|
|
||||||
|
// Register standard k8s flags with the command line
|
||||||
|
o.RecommendedOptions = options.NewRecommendedOptions(
|
||||||
|
defaultEtcdPathPrefix,
|
||||||
|
Codecs.LegacyCodec(), // the codec is passed to etcd and not used
|
||||||
|
)
|
||||||
|
o.RecommendedOptions.AddFlags(cmd.Flags())
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunCLI() int {
|
||||||
|
stopCh := genericapiserver.SetupSignalHandler()
|
||||||
|
|
||||||
|
options := newExampleServerOptions(os.Stdout, os.Stderr)
|
||||||
|
cmd := newCommandStartExampleAPIServer(options, stopCh)
|
||||||
|
|
||||||
|
return cli.Run(cmd)
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package main
|
package apiserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
exampleAPI "github.com/grafana/grafana/pkg/registry/apis/example"
|
"github.com/grafana/grafana/pkg/registry/apis/example"
|
||||||
grafanaAPIServer "github.com/grafana/grafana/pkg/services/grafana-apiserver"
|
grafanaAPIServer "github.com/grafana/grafana/pkg/services/grafana-apiserver"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -43,34 +43,47 @@ func init() {
|
|||||||
|
|
||||||
// ExampleServerOptions contains the state for the apiserver
|
// ExampleServerOptions contains the state for the apiserver
|
||||||
type ExampleServerOptions struct {
|
type ExampleServerOptions struct {
|
||||||
|
builders []grafanaAPIServer.APIGroupBuilder
|
||||||
RecommendedOptions *options.RecommendedOptions
|
RecommendedOptions *options.RecommendedOptions
|
||||||
Builders []grafanaAPIServer.APIGroupBuilder
|
|
||||||
AlternateDNS []string
|
AlternateDNS []string
|
||||||
|
|
||||||
StdOut io.Writer
|
StdOut io.Writer
|
||||||
StdErr io.Writer
|
StdErr io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExampleServerOptions(out, errOut io.Writer) (*ExampleServerOptions, error) {
|
func newExampleServerOptions(out, errOut io.Writer) *ExampleServerOptions {
|
||||||
builder := &exampleAPI.TestingAPIBuilder{}
|
|
||||||
|
|
||||||
// Install schema
|
|
||||||
if err := builder.InstallSchema(Scheme); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ExampleServerOptions{
|
return &ExampleServerOptions{
|
||||||
Builders: []grafanaAPIServer.APIGroupBuilder{builder},
|
|
||||||
RecommendedOptions: options.NewRecommendedOptions(
|
|
||||||
defaultEtcdPathPrefix,
|
|
||||||
Codecs.LegacyCodec(builder.GetGroupVersion()),
|
|
||||||
),
|
|
||||||
StdOut: out,
|
StdOut: out,
|
||||||
StdErr: errOut,
|
StdErr: errOut,
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o ExampleServerOptions) Config() (*genericapiserver.RecommendedConfig, error) {
|
func (o *ExampleServerOptions) LoadAPIGroupBuilders(args []string) error {
|
||||||
|
o.builders = []grafanaAPIServer.APIGroupBuilder{}
|
||||||
|
for _, g := range args {
|
||||||
|
switch g {
|
||||||
|
// No dependencies for testing
|
||||||
|
case "example.grafana.app":
|
||||||
|
o.builders = append(o.builders, &example.TestingAPIBuilder{})
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown group: %s", g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(o.builders) < 1 {
|
||||||
|
return fmt.Errorf("expected group name(s) in the command line arguments")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install schemas
|
||||||
|
for _, b := range o.builders {
|
||||||
|
if err := b.InstallSchema(Scheme); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ExampleServerOptions) Config() (*genericapiserver.RecommendedConfig, error) {
|
||||||
if err := o.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", o.AlternateDNS, []net.IP{netutils.ParseIPSloppy("127.0.0.1")}); err != nil {
|
if err := o.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", o.AlternateDNS, []net.IP{netutils.ParseIPSloppy("127.0.0.1")}); err != nil {
|
||||||
return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
|
return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
|
||||||
}
|
}
|
||||||
@@ -94,18 +107,18 @@ func (o ExampleServerOptions) Config() (*genericapiserver.RecommendedConfig, err
|
|||||||
// Validate validates ExampleServerOptions
|
// Validate validates ExampleServerOptions
|
||||||
// NOTE: we don't call validate on the top level recommended options as it doesn't like skipping etcd-servers
|
// NOTE: we don't call validate on the top level recommended options as it doesn't like skipping etcd-servers
|
||||||
// the function is left here for troubleshooting any other config issues
|
// the function is left here for troubleshooting any other config issues
|
||||||
func (o ExampleServerOptions) Validate(args []string) error {
|
func (o *ExampleServerOptions) Validate(args []string) error {
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
errors = append(errors, o.RecommendedOptions.Validate()...)
|
errors = append(errors, o.RecommendedOptions.Validate()...)
|
||||||
return utilerrors.NewAggregate(errors)
|
return utilerrors.NewAggregate(errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete fills in fields required to have valid data
|
// Complete fills in fields required to have valid data
|
||||||
func (o ExampleServerOptions) Complete() error {
|
func (o *ExampleServerOptions) Complete() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o ExampleServerOptions) RunExampleServer(config *genericapiserver.RecommendedConfig, stopCh <-chan struct{}) error {
|
func (o *ExampleServerOptions) RunExampleServer(config *genericapiserver.RecommendedConfig, stopCh <-chan struct{}) error {
|
||||||
delegationTarget := genericapiserver.NewEmptyDelegate()
|
delegationTarget := genericapiserver.NewEmptyDelegate()
|
||||||
completedConfig := config.Complete()
|
completedConfig := config.Complete()
|
||||||
server, err := completedConfig.New("example-apiserver", delegationTarget)
|
server, err := completedConfig.New("example-apiserver", delegationTarget)
|
||||||
@@ -114,7 +127,7 @@ func (o ExampleServerOptions) RunExampleServer(config *genericapiserver.Recommen
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install the API Group+version
|
// Install the API Group+version
|
||||||
for _, b := range o.Builders {
|
for _, b := range o.builders {
|
||||||
g, err := b.GetAPIGroupInfo(Scheme, Codecs, completedConfig.RESTOptionsGetter)
|
g, err := b.GetAPIGroupInfo(Scheme, Codecs, completedConfig.RESTOptionsGetter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
gcli "github.com/grafana/grafana/pkg/cmd/grafana-cli/commands"
|
gcli "github.com/grafana/grafana/pkg/cmd/grafana-cli/commands"
|
||||||
gsrv "github.com/grafana/grafana/pkg/cmd/grafana-server/commands"
|
gsrv "github.com/grafana/grafana/pkg/cmd/grafana-server/commands"
|
||||||
|
"github.com/grafana/grafana/pkg/cmd/grafana/apiserver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The following variables cannot be constants, since they can be overridden through the -X link flag
|
// The following variables cannot be constants, since they can be overridden through the -X link flag
|
||||||
@@ -32,6 +33,18 @@ func main() {
|
|||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
gcli.CLICommand(version),
|
gcli.CLICommand(version),
|
||||||
gsrv.ServerCommand(version, commit, enterpriseCommit, buildBranch, buildstamp),
|
gsrv.ServerCommand(version, commit, enterpriseCommit, buildBranch, buildstamp),
|
||||||
|
{
|
||||||
|
// The kubernetes standalone apiserver service runner
|
||||||
|
Name: "apiserver",
|
||||||
|
Usage: "run a standalone api service (experimental)",
|
||||||
|
// Skip parsing flags because the command line is actually managed by cobra
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
// exit here because apiserver handles its own error output
|
||||||
|
os.Exit(apiserver.RunCLI())
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
CommandNotFound: cmdNotFound,
|
CommandNotFound: cmdNotFound,
|
||||||
EnableBashCompletion: true,
|
EnableBashCompletion: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user