Skip to content

Commit

Permalink
add a craned webserver
Browse files Browse the repository at this point in the history
  • Loading branch information
kitianFresh committed Feb 11, 2022
1 parent 8229ddd commit f797603
Show file tree
Hide file tree
Showing 26 changed files with 1,926 additions and 163 deletions.
23 changes: 22 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,12 @@ manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and Cust
go mod vendor; \
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" rbac:roleName=manager-role crd webhook paths="./vendor/github.com/gocrane/api/..." output:crd:artifacts:config=deploy/manifests

.PHONY: mockgen
mockgen: ## Run go mockgen to gen mock code.
go generate ./...

.PHONY: generate
generate: manifests ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
generate: manifests mockgen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.

.PHONY: fmt
fmt: ## Run go fmt against code.
Expand Down Expand Up @@ -223,3 +227,20 @@ GO_IMPORTS=$(shell go env GOPATH)/bin/goimports
else
GO_IMPORTS=$(shell which goimports)
endif


mockgen:
ifeq (, $(shell which mockgen))
@{ \
set -e ;\
export GO111MODULE=on; \
GO_IMPORTS_TMP_DIR=$$(mktemp -d) ;\
cd $$GO_IMPORTS_TMP_DIR ;\
go mod init tmp ;\
go get github.com/golang/mock@v1.5.0 ;\
rm -rf $$GO_IMPORTS_TMP_DIR ;\
}
GO_IMPORTS=$(shell go env GOPATH)/bin/mockgen
else
GO_IMPORTS=$(shell which mockgen)
endif
42 changes: 36 additions & 6 deletions cmd/craned/app/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"os"
"strings"

"github.com/gocrane/crane/pkg/recommend"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature"
Expand Down Expand Up @@ -39,6 +39,9 @@ import (
"github.com/gocrane/crane/pkg/providers"
"github.com/gocrane/crane/pkg/providers/mock"
"github.com/gocrane/crane/pkg/providers/prom"
"github.com/gocrane/crane/pkg/recommend"
"github.com/gocrane/crane/pkg/server"
serverconfig "github.com/gocrane/crane/pkg/server/config"
"github.com/gocrane/crane/pkg/webhooks"
)

Expand All @@ -65,9 +68,10 @@ func NewManagerCommand(ctx context.Context) *cobra.Command {
if err := opts.Complete(); err != nil {
klog.Exit(err)
}
if err := opts.Validate(); err != nil {
klog.Exit(err)
if errs := opts.Validate(); len(errs) != 0 {
klog.Exit(errs)
}

if err := Run(ctx, opts); err != nil {
klog.Exit(err)
}
Expand Down Expand Up @@ -115,9 +119,35 @@ func Run(ctx context.Context, opts *options.Options) error {
// initialization custom collector metrics
initializationMetricCollector(mgr)

if err := mgr.Start(ctx); err != nil {
klog.Error(err, "problem running crane manager")
return err
var eg errgroup.Group

eg.Go(func() error {
if err := mgr.Start(ctx); err != nil {
klog.Error(err, "problem running crane manager")
klog.Exit(err)
}
return nil
})

eg.Go(func() error {
// Start the craned web server
serverConfig := serverconfig.NewServerConfig()
if err := opts.ApplyTo(serverConfig); err != nil {
klog.Exit(err)
}
// use controller runtime rest config, we can not refer kubeconfig option directly because it is unexported variable in vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go
serverConfig.KubeRestConfig = mgr.GetConfig()
craneServer, err := server.NewServer(serverConfig)
if err != nil {
klog.Exit(err)
}
craneServer.Run(ctx)
return nil
})

// wait for all components exit
if err := eg.Wait(); err != nil {
klog.Fatal(err)
}

return nil
Expand Down
22 changes: 17 additions & 5 deletions cmd/craned/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import (

"github.com/gocrane/crane/pkg/prediction/config"
"github.com/gocrane/crane/pkg/providers"
serverconfig "github.com/gocrane/crane/pkg/server/config"
"github.com/gocrane/crane/pkg/webhooks"
)

// Options hold the command-line options about crane manager
// Options hold the command-line options about craned
type Options struct {
// ApiQps for rest client
ApiQps int
Expand Down Expand Up @@ -41,25 +42,36 @@ type Options struct {
// RecommendationConfigFile is the configuration file for resource/HPA recommendations.
// If unspecified, a default is provided.
RecommendationConfigFile string

// ServerOptions hold the craned web server options
ServerOptions *ServerOptions
}

// NewOptions builds an empty options.
func NewOptions() *Options {
return &Options{}
return &Options{
ServerOptions: NewServerOptions(),
}
}

// Complete completes all the required options.
func (o *Options) Complete() error {
return nil
return o.ServerOptions.Complete()
}

// Validate all required options.
func (o *Options) Validate() error {
return nil
func (o *Options) Validate() []error {
return o.ServerOptions.Validate()
}

func (o *Options) ApplyTo(cfg *serverconfig.Config) error {
return o.ServerOptions.ApplyTo(cfg)
}

// AddFlags adds flags to the specified FlagSet.
func (o *Options) AddFlags(flags *pflag.FlagSet) {
o.ServerOptions.AddFlags(flags)

flags.IntVar(&o.ApiQps, "api-qps", 300, "QPS of rest config.")
flags.IntVar(&o.ApiBurst, "api-burst", 400, "Burst of rest config.")
flags.StringVar(&o.MetricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
Expand Down
124 changes: 124 additions & 0 deletions cmd/craned/app/options/server_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package options

import (
"fmt"
"os"
"strings"

"github.com/gin-gonic/gin"
"github.com/spf13/pflag"
"gopkg.in/gcfg.v1"

serverconfig "github.com/gocrane/crane/pkg/server/config"
"github.com/gocrane/crane/pkg/server/service/dashboard"
"github.com/gocrane/crane/pkg/server/store/secret"
)

// ServerOptions used for craned web server
type ServerOptions struct {
BindAddress string
BindPort int

EnableProfiling bool
EnableMetrics bool
Mode string

EnableGrafana bool
GrafanaConfigFile string
dashboard.GrafanaConfig

StoreType string
}

func NewServerOptions() *ServerOptions {
return &ServerOptions{}
}

func (o *ServerOptions) Complete() error {
if o.EnableGrafana {
var gconfig dashboard.GrafanaConfig
grafanaConfig, err := os.Open(o.GrafanaConfigFile)
if err != nil {
return err
}
defer grafanaConfig.Close()

if err := gcfg.FatalOnly(gcfg.ReadInto(&gconfig, grafanaConfig)); err != nil {
return err
}
o.GrafanaConfig = gconfig
}
return nil
}

func (o *ServerOptions) ApplyTo(cfg *serverconfig.Config) error {
cfg.BindAddress = o.BindAddress
cfg.BindPort = o.BindPort

cfg.Mode = o.Mode
cfg.EnableMetrics = o.EnableMetrics
cfg.EnableProfiling = o.EnableProfiling

cfg.EnableGrafana = o.EnableGrafana
cfg.GrafanaConfig = &o.GrafanaConfig
cfg.StoreType = o.StoreType
return nil
}

func (o *ServerOptions) Validate() []error {
var errors []error

if o.EnableGrafana {
if o.APIKey == "" && o.Username == "" && o.Password == "" {
errors = append(errors, fmt.Errorf("no apikey or username&password specified"))
}
}

if o.BindPort < 0 || o.BindPort > 65535 {
errors = append(
errors,
fmt.Errorf(
"--server-bind-port %v must be between 0 and 65535, inclusive. 0 for turning off insecure (HTTP) port",
o.BindPort,
),
)
}

if strings.ToLower(o.StoreType) != secret.StoreType {
errors = append(errors, fmt.Errorf("--server-store only support secret now"))
}

return errors
}

// AddFlags adds flags related to features for a specific server option to the
// specified FlagSet.
func (o *ServerOptions) AddFlags(fs *pflag.FlagSet) {
if fs == nil {
return
}

fs.StringVar(&o.BindAddress, "server-bind-address", "0.0.0.0", ""+
"The IP address on which to serve the --server-bind-port "+
"(set to 0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).")
fs.IntVar(&o.BindPort, "server-bind-port", 8082,
"The port on which to serve unsecured, unauthenticated access")

fs.BoolVar(&o.EnableProfiling, "server-enable-profiling", o.EnableProfiling,
"Enable profiling via web interface host:port/debug/pprof/")

fs.BoolVar(&o.EnableMetrics, "server-enable-metrics", o.EnableMetrics,
"Enables metrics on the server at /metrics")

fs.StringVar(&o.Mode, "server-mode", gin.ReleaseMode,
"Debug mode of the gin server, support release,debug,test")

fs.BoolVar(&o.EnableGrafana, "server-enable-grafana", o.EnableGrafana,
"Enable grafana will read grafana config file to requests grafana dashboard")

fs.StringVar(&o.GrafanaConfigFile, "server-grafana-config", o.GrafanaConfigFile,
"Grafana config file, file contents is grafana config")

fs.StringVar(&o.StoreType, "server-store", secret.StoreType, "Server storage type, support secret now")

}
7 changes: 7 additions & 0 deletions examples/grafana.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[service]
Scheme=
Host=127.0.0.1:3000
[auth]
APIKey=
Username=admin
Password=admin
Loading

0 comments on commit f797603

Please sign in to comment.