Merge pull request #702 from zryfish/refactor_clientset

refactor dependent service client creation
This commit is contained in:
KubeSphere CI Bot
2019-09-11 20:27:49 +08:00
committed by GitHub
233 changed files with 26414 additions and 1927 deletions

View File

@@ -21,7 +21,12 @@ before_script:
- bash hack/install_kubebuilder.sh - bash hack/install_kubebuilder.sh
script: script:
- make all - diff -u <(echo -n) <(gofmt -d ./pkg ./cmd ./tools)
- make openapi
- make all
install:
- go get golang.org/x/lint/golint
deploy: deploy:
skip_cleanup: true skip_cleanup: true

View File

@@ -39,7 +39,7 @@ define ALL_HELP_INFO
# debugging tools like delve. # debugging tools like delve.
endef endef
.PHONY: all .PHONY: all
all: test ks-apiserver ks-apigateway ks-iam controller-manager all: hypersphere ks-apiserver ks-apigateway ks-iam controller-manager
# Build ks-apiserver binary # Build ks-apiserver binary
ks-apiserver: test ks-apiserver: test
@@ -57,9 +57,13 @@ ks-iam: test
controller-manager: test controller-manager: test
hack/gobuild.sh cmd/controller-manager hack/gobuild.sh cmd/controller-manager
# Build hypersphere binary
hypersphere: test
hack/gobuild.sh cmd/hypersphere
# Run go fmt against code # Run go fmt against code
fmt: generate fmt: generate
go fmt ./pkg/... ./cmd/... gofmt -w ./pkg ./cmd ./tools ./api
# Run go vet against code # Run go vet against code
vet: generate vet: generate

View File

@@ -0,0 +1,18 @@
# Copyright 2018 The KubeSphere Authors. All rights reserved.
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.
# Copyright 2018 The KubeSphere Authors. All rights reserved.
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.
FROM golang:1.12 as hypersphere-builder
COPY / /go/src/kubesphere.io/kubesphere
WORKDIR /go/src/kubesphere.io/kubesphere
RUN CGO_ENABLED=0 GO111MODULE=on GOOS=linux GOARCH=amd64 GOFLAGS=-mod=vendor go build -i -ldflags '-w -s' -o hypersphere cmd/hypersphere/hypersphere.go
FROM alpine:3.9
RUN apk add --update ca-certificates && update-ca-certificates
COPY --from=ks-apiserver-builder /go/src/kubesphere.io/kubesphere/hypersphere /usr/local/bin/
CMD ["sh"]

View File

@@ -25,7 +25,6 @@ import (
"kubesphere.io/kubesphere/pkg/controller/destinationrule" "kubesphere.io/kubesphere/pkg/controller/destinationrule"
"kubesphere.io/kubesphere/pkg/controller/job" "kubesphere.io/kubesphere/pkg/controller/job"
"kubesphere.io/kubesphere/pkg/controller/s2ibinary" "kubesphere.io/kubesphere/pkg/controller/s2ibinary"
"kubesphere.io/kubesphere/pkg/controller/s2irun" "kubesphere.io/kubesphere/pkg/controller/s2irun"
//"kubesphere.io/kubesphere/pkg/controller/job" //"kubesphere.io/kubesphere/pkg/controller/job"
@@ -112,7 +111,9 @@ func AddControllers(mgr manager.Manager, cfg *rest.Config, stopCh <-chan struct{
jobController := job.NewJobController(informerFactory.Batch().V1().Jobs(), kubeClient) jobController := job.NewJobController(informerFactory.Batch().V1().Jobs(), kubeClient)
s2iBinaryController := s2ibinary.NewController(kubesphereclient, kubeClient, kubesphereInformer.Devops().V1alpha1().S2iBinaries()) s2iBinaryController := s2ibinary.NewController(kubesphereclient,
kubeClient,
kubesphereInformer.Devops().V1alpha1().S2iBinaries())
s2iRunController := s2irun.NewController(kubesphereclient, s2iclient, kubeClient, s2iRunController := s2irun.NewController(kubesphereclient, s2iclient, kubeClient,
kubesphereInformer.Devops().V1alpha1().S2iBinaries(), kubesphereInformer.Devops().V1alpha1().S2iBinaries(),

View File

@@ -0,0 +1,63 @@
package options
import (
"flag"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
kubesphereconfig "kubesphere.io/kubesphere/pkg/server/config"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3"
"strings"
)
type KubeSphereControllerManagerOptions struct {
KubernetesOptions *k8s.KubernetesOptions
DevopsOptions *devops.DevopsOptions
S3Options *s2is3.S3Options
}
func NewKubeSphereControllerManagerOptions() *KubeSphereControllerManagerOptions {
s := &KubeSphereControllerManagerOptions{
KubernetesOptions: k8s.NewKubernetesOptions(),
DevopsOptions: devops.NewDevopsOptions(),
S3Options: s2is3.NewS3Options(),
}
return s
}
func (s *KubeSphereControllerManagerOptions) ApplyTo(conf *kubesphereconfig.Config) {
s.S3Options.ApplyTo(conf.S3Options)
s.KubernetesOptions.ApplyTo(conf.KubernetesOptions)
s.DevopsOptions.ApplyTo(conf.DevopsOptions)
}
func (s *KubeSphereControllerManagerOptions) Flags() cliflag.NamedFlagSets {
fss := cliflag.NamedFlagSets{}
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"))
s.DevopsOptions.AddFlags(fss.FlagSet("devops"))
s.S3Options.AddFlags(fss.FlagSet("s3"))
fs := fss.FlagSet("klog")
local := flag.NewFlagSet("klog", flag.ExitOnError)
klog.InitFlags(local)
local.VisitAll(func(fl *flag.Flag) {
fl.Name = strings.Replace(fl.Name, "_", "-", -1)
fs.AddGoFlag(fl)
})
return fss
}
func (s *KubeSphereControllerManagerOptions) Validate() []error {
var errs []error
errs = append(errs, s.DevopsOptions.Validate()...)
errs = append(errs, s.KubernetesOptions.Validate()...)
errs = append(errs, s.S3Options.Validate()...)
return errs
}

View File

@@ -0,0 +1,153 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package app
import (
"fmt"
"github.com/spf13/cobra"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
"kubesphere.io/kubesphere/cmd/controller-manager/app/options"
"kubesphere.io/kubesphere/pkg/apis"
"kubesphere.io/kubesphere/pkg/controller"
controllerconfig "kubesphere.io/kubesphere/pkg/server/config"
"kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/term"
"os"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
)
func NewControllerManagerCommand() *cobra.Command {
s := options.NewKubeSphereControllerManagerOptions()
cmd := &cobra.Command{
Use: "controller-manager",
Long: `KubeSphere controller manager is a daemon that`,
Run: func(cmd *cobra.Command, args []string) {
err := controllerconfig.Load()
if err != nil {
klog.Fatal(err)
os.Exit(1)
}
err = Complete(s)
if err != nil {
os.Exit(1)
}
if errs := s.Validate(); len(errs) != 0 {
klog.Error(utilerrors.NewAggregate(errs))
os.Exit(1)
}
if err = Run(s, signals.SetupSignalHandler()); err != nil {
os.Exit(1)
}
},
}
fs := cmd.Flags()
namedFlagSets := s.Flags()
for _, f := range namedFlagSets.FlagSets {
fs.AddFlagSet(f)
}
usageFmt := "Usage:\n %s\n"
cols, _, _ := term.TerminalSize(cmd.OutOrStdout())
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine())
cliflag.PrintSections(cmd.OutOrStdout(), namedFlagSets, cols)
})
return cmd
}
func Complete(s *options.KubeSphereControllerManagerOptions) error {
conf := controllerconfig.Get()
conf.Apply(&controllerconfig.Config{
DevopsOptions: s.DevopsOptions,
KubernetesOptions: s.KubernetesOptions,
S3Options: s.S3Options,
})
s = &options.KubeSphereControllerManagerOptions{
KubernetesOptions: conf.KubernetesOptions,
DevopsOptions: conf.DevopsOptions,
S3Options: conf.S3Options,
}
return nil
}
func CreateClientSet(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{}) error {
csop := &client.ClientSetOptions{}
csop.SetKubernetesOptions(s.KubernetesOptions).
SetDevopsOptions(s.DevopsOptions).
SetS3Options(s.S3Options)
client.NewClientSetFactory(csop, stopCh)
return nil
}
func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{}) error {
err := CreateClientSet(s, stopCh)
if err != nil {
klog.Error(err)
return err
}
config := client.ClientSets().K8s().Config()
klog.Info("setting up manager")
mgr, err := manager.New(config, manager.Options{})
if err != nil {
klog.Error(err, "unable to set up overall controller manager")
return err
}
klog.Info("setting up scheme")
if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
klog.Error(err, "unable add APIs to scheme")
return err
}
klog.Info("Setting up controllers")
if err := controller.AddToManager(mgr); err != nil {
klog.Error(err, "unable to register controllers to the manager")
return err
}
if err := AddControllers(mgr, config, stopCh); err != nil {
klog.Error(err, "unable to register controllers to the manager")
return err
}
klog.Info("Starting the Cmd.")
if err := mgr.Start(stopCh); err != nil {
klog.Error(err, "unable to run the manager")
return err
}
return nil
}

View File

@@ -1,83 +1,14 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package main package main
import ( import (
"flag"
"k8s.io/klog"
"kubesphere.io/kubesphere/cmd/controller-manager/app" "kubesphere.io/kubesphere/cmd/controller-manager/app"
"kubesphere.io/kubesphere/pkg/apis"
"kubesphere.io/kubesphere/pkg/controller"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"os" "os"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
) )
var (
masterURL string
metricsAddr string
)
func init() {
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
}
func main() { func main() {
flag.Parse() command := app.NewControllerManagerCommand()
cfg, err := k8s.Config() if err := command.Execute(); err != nil {
if err != nil {
klog.Error(err, "failed to build kubeconfig")
os.Exit(1) os.Exit(1)
} }
stopCh := signals.SetupSignalHandler()
klog.Info("setting up manager")
mgr, err := manager.New(cfg, manager.Options{})
if err != nil {
klog.Error(err, "unable to set up overall controller manager")
os.Exit(1)
}
klog.Info("setting up scheme")
if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
klog.Error(err, "unable add APIs to scheme")
os.Exit(1)
}
klog.Info("Setting up controllers")
if err := controller.AddToManager(mgr); err != nil {
klog.Error(err, "unable to register controllers to the manager")
os.Exit(1)
}
if err := app.AddControllers(mgr, cfg, stopCh); err != nil {
klog.Error(err, "unable to register controllers to the manager")
os.Exit(1)
}
klog.Info("Starting the Cmd.")
if err := mgr.Start(stopCh); err != nil {
klog.Error(err, "unable to run the manager")
os.Exit(1)
}
} }

View File

@@ -0,0 +1,72 @@
package main
import (
goflag "flag"
cliflag "k8s.io/component-base/cli/flag"
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
controllermanager "kubesphere.io/kubesphere/cmd/controller-manager/app"
ksapiserver "kubesphere.io/kubesphere/cmd/ks-apiserver/app"
ksaiam "kubesphere.io/kubesphere/cmd/ks-iam/app"
"os"
)
func main() {
hypersphereCommand, allCommandFns := NewHyperSphereCommand()
pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
basename := filepath.Base(os.Args[0])
if err := commandFor(basename, hypersphereCommand, allCommandFns).Execute(); err != nil {
os.Exit(1)
}
}
func commandFor(basename string, defaultCommand *cobra.Command, commands []func() *cobra.Command) *cobra.Command {
for _, commandFn := range commands {
command := commandFn()
if command.Name() == basename {
return command
}
for _, alias := range command.Aliases {
if alias == basename {
return command
}
}
}
return defaultCommand
}
func NewHyperSphereCommand() (*cobra.Command, []func() *cobra.Command) {
apiserver := func() *cobra.Command { return ksapiserver.NewAPIServerCommand() }
controllermanager := func() *cobra.Command { return controllermanager.NewControllerManagerCommand() }
iam := func() *cobra.Command { return ksaiam.NewAPIServerCommand() }
commandFns := []func() *cobra.Command{
apiserver,
controllermanager,
iam,
}
cmd := &cobra.Command{
Use: "hypersphere",
Short: "Request a new project",
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 0 {
cmd.Help()
os.Exit(0)
}
},
}
for i := range commandFns {
cmd.AddCommand(commandFns[i]())
}
return cmd, commandFns
}

View File

@@ -1,45 +1,66 @@
package options package options
import ( import (
"github.com/spf13/pflag" "flag"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
genericoptions "kubesphere.io/kubesphere/pkg/options" genericoptions "kubesphere.io/kubesphere/pkg/options"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/prometheus"
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"strings"
) )
type ServerRunOptions struct { type ServerRunOptions struct {
GenericServerRunOptions *genericoptions.ServerRunOptions GenericServerRunOptions *genericoptions.ServerRunOptions
// istio pilot discovery service url KubernetesOptions *k8s.KubernetesOptions
IstioPilotServiceURL string
// jaeger query service url DevopsOptions *devops.DevopsOptions
JaegerQueryServiceUrl string
// prometheus service url for servicemesh metrics SonarQubeOptions *sonarqube.SonarQubeOptions
ServicemeshPrometheusServiceUrl string
// openpitrix api gateway service url ServiceMeshOptions *servicemesh.ServiceMeshOptions
OpenPitrixServer string
// openpitrix service token MySQLOptions *mysql.MySQLOptions
OpenPitrixProxyToken string
MonitoringOptions *prometheus.PrometheusOptions
} }
func NewServerRunOptions() *ServerRunOptions { func NewServerRunOptions() *ServerRunOptions {
s := ServerRunOptions{ s := ServerRunOptions{
GenericServerRunOptions: genericoptions.NewServerRunOptions(), GenericServerRunOptions: genericoptions.NewServerRunOptions(),
IstioPilotServiceURL: "http://istio-pilot.istio-system.svc:8080/version", KubernetesOptions: k8s.NewKubernetesOptions(),
JaegerQueryServiceUrl: "http://jaeger-query.istio-system.svc:16686/jaeger", DevopsOptions: devops.NewDevopsOptions(),
SonarQubeOptions: sonarqube.NewSonarQubeOptions(),
ServiceMeshOptions: servicemesh.NewServiceMeshOptions(),
MySQLOptions: mysql.NewMySQLOptions(),
MonitoringOptions: prometheus.NewPrometheusOptions(),
} }
return &s return &s
} }
func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
s.GenericServerRunOptions.AddFlags(fs) s.GenericServerRunOptions.AddFlags(fss.FlagSet("generic"))
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"))
s.DevopsOptions.AddFlags(fss.FlagSet("devops"))
s.SonarQubeOptions.AddFlags(fss.FlagSet("sonarqube"))
s.ServiceMeshOptions.AddFlags(fss.FlagSet("servicemesh"))
s.MonitoringOptions.AddFlags(fss.FlagSet("monitoring"))
fs.StringVar(&s.IstioPilotServiceURL, "istio-pilot-service-url", "http://istio-pilot.istio-system.svc:8080/version", "istio pilot discovery service url") fs := fss.FlagSet("klog")
fs.StringVar(&s.JaegerQueryServiceUrl, "jaeger-query-service-url", "http://jaeger-query.istio-system.svc:16686/jaeger", "jaeger query service url") local := flag.NewFlagSet("klog", flag.ExitOnError)
fs.StringVar(&s.ServicemeshPrometheusServiceUrl, "servicemesh-prometheus-service-url", "http://prometheus-k8s-system.kubesphere-monitoring-system.svc:9090", "prometheus service for servicemesh") klog.InitFlags(local)
local.VisitAll(func(fl *flag.Flag) {
fl.Name = strings.Replace(fl.Name, "_", "-", -1)
fs.AddGoFlag(fl)
})
return fss
} }

View File

@@ -0,0 +1,14 @@
package options
func (s *ServerRunOptions) Validate() []error {
var errors []error
errors = append(errors, s.DevopsOptions.Validate()...)
errors = append(errors, s.KubernetesOptions.Validate()...)
errors = append(errors, s.MySQLOptions.Validate()...)
errors = append(errors, s.ServiceMeshOptions.Validate()...)
errors = append(errors, s.MonitoringOptions.Validate()...)
errors = append(errors, s.SonarQubeOptions.Validate()...)
return errors
}

View File

@@ -18,113 +18,110 @@
package app package app
import ( import (
goflag "flag"
"fmt" "fmt"
"github.com/golang/glog"
"github.com/json-iterator/go"
kconfig "github.com/kiali/kiali/config" kconfig "github.com/kiali/kiali/config"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
"kubesphere.io/kubesphere/cmd/ks-apiserver/app/options" "kubesphere.io/kubesphere/cmd/ks-apiserver/app/options"
"kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/apiserver/servicemesh/tracing" "kubesphere.io/kubesphere/pkg/apiserver/servicemesh/tracing"
"kubesphere.io/kubesphere/pkg/filter" "kubesphere.io/kubesphere/pkg/filter"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/devops"
logging "kubesphere.io/kubesphere/pkg/models/log" logging "kubesphere.io/kubesphere/pkg/models/log"
"kubesphere.io/kubesphere/pkg/server" "kubesphere.io/kubesphere/pkg/server"
"kubesphere.io/kubesphere/pkg/signals" apiserverconfig "kubesphere.io/kubesphere/pkg/server/config"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins" "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql" "kubesphere.io/kubesphere/pkg/utils/signals"
"log" "kubesphere.io/kubesphere/pkg/utils/term"
"net/http" "net/http"
) )
var jsonIter = jsoniter.ConfigCompatibleWithStandardLibrary
func NewAPIServerCommand() *cobra.Command { func NewAPIServerCommand() *cobra.Command {
s := options.NewServerRunOptions() s := options.NewServerRunOptions()
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "ks-apiserver", Use: "ks-apiserver",
Long: `The KubeSphere API server validates and configures data Long: `The KubeSphere API server validates and configures data for the api objects.
for the api objects. The API Server services REST operations and provides the frontend to the The API Server services REST operations and provides the frontend to the
cluster's shared state through which all other components interact.`, cluster's shared state through which all other components interact.`,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return Run(s) err := apiserverconfig.Load()
if err != nil {
return err
}
err = Complete(s)
if err != nil {
return err
}
if errs := s.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs)
}
return Run(s, signals.SetupSignalHandler())
}, },
} }
s.AddFlags(cmd.Flags()) fs := cmd.Flags()
cmd.Flags().AddGoFlagSet(goflag.CommandLine) namedFlagSets := s.Flags()
glog.CopyStandardLogTo("INFO")
for _, f := range namedFlagSets.FlagSets {
fs.AddFlagSet(f)
}
usageFmt := "Usage:\n %s\n"
cols, _, _ := term.TerminalSize(cmd.OutOrStdout())
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine())
cliflag.PrintSections(cmd.OutOrStdout(), namedFlagSets, cols)
})
return cmd return cmd
} }
func Run(s *options.ServerRunOptions) error { func Run(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
pflag.VisitAll(func(flag *pflag.Flag) { err := CreateClientSet(apiserverconfig.Get(), stopCh)
log.Printf("FLAG: --%s=%q", flag.Name, flag.Value) if err != nil {
}) return err
}
var err error
err = WaitForResourceSync(stopCh)
waitForResourceSync() if err != nil {
return err
container := runtime.Container
container.DoNotRecover(false)
container.Filter(filter.Logging)
container.RecoverHandler(server.LogStackOnRecover)
for _, webservice := range container.RegisteredWebServices() {
for _, route := range webservice.Routes() {
log.Println(route.Method, route.Path)
}
} }
initializeAdminJenkins()
initializeDevOpsDatabase()
initializeESClientConfig()
initializeServicemeshConfig(s) initializeServicemeshConfig(s)
if s.GenericServerRunOptions.InsecurePort != 0 { initializeESClientConfig()
log.Printf("Server listening on %d.", s.GenericServerRunOptions.InsecurePort)
err = http.ListenAndServe(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort), container) err = CreateAPIServer(s)
if err != nil {
return err
} }
if s.GenericServerRunOptions.SecurePort != 0 && len(s.GenericServerRunOptions.TlsCertFile) > 0 && len(s.GenericServerRunOptions.TlsPrivateKey) > 0 { return nil
log.Printf("Server listening on %d.", s.GenericServerRunOptions.SecurePort)
err = http.ListenAndServeTLS(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.SecurePort), s.GenericServerRunOptions.TlsCertFile, s.GenericServerRunOptions.TlsPrivateKey, container)
}
return err
}
func initializeAdminJenkins() {
devops.JenkinsInit()
admin_jenkins.Client()
}
func initializeDevOpsDatabase() {
devops_mysql.OpenDatabase()
} }
func initializeServicemeshConfig(s *options.ServerRunOptions) { func initializeServicemeshConfig(s *options.ServerRunOptions) {
// Initialize kiali config // Initialize kiali config
config := kconfig.NewConfig() config := kconfig.NewConfig()
tracing.JaegerQueryUrl = s.JaegerQueryServiceUrl tracing.JaegerQueryUrl = s.ServiceMeshOptions.JaegerQueryHost
// Exclude system namespaces // Exclude system namespaces
config.API.Namespaces.Exclude = []string{"istio-system", "kubesphere*", "kube*"} config.API.Namespaces.Exclude = []string{"istio-system", "kubesphere*", "kube*"}
config.InCluster = true config.InCluster = true
// Set default prometheus service url // Set default prometheus service url
config.ExternalServices.PrometheusServiceURL = s.ServicemeshPrometheusServiceUrl config.ExternalServices.PrometheusServiceURL = s.ServiceMeshOptions.ServicemeshPrometheusHost
config.ExternalServices.PrometheusCustomMetricsURL = config.ExternalServices.PrometheusServiceURL config.ExternalServices.PrometheusCustomMetricsURL = config.ExternalServices.PrometheusServiceURL
// Set istio pilot discovery service url // Set istio pilot discovery service url
config.ExternalServices.Istio.UrlServiceVersion = s.IstioPilotServiceURL config.ExternalServices.Istio.UrlServiceVersion = s.ServiceMeshOptions.IstioPilotHost
kconfig.Set(config) kconfig.Set(config)
} }
@@ -134,7 +131,7 @@ func initializeESClientConfig() {
// List all outputs // List all outputs
outputs, err := logging.GetFluentbitOutputFromConfigMap() outputs, err := logging.GetFluentbitOutputFromConfigMap()
if err != nil { if err != nil {
glog.Errorln(err) klog.Errorln(err)
return return
} }
@@ -147,54 +144,164 @@ func initializeESClientConfig() {
} }
} }
func waitForResourceSync() { //
stopChan := signals.SetupSignalHandler() func CreateAPIServer(s *options.ServerRunOptions) error {
var err error
container := runtime.Container
container.DoNotRecover(false)
container.Filter(filter.Logging)
container.RecoverHandler(server.LogStackOnRecover)
// install config api
apiserverconfig.InstallAPI(container)
for _, webservice := range container.RegisteredWebServices() {
for _, route := range webservice.Routes() {
klog.V(0).Info(route.Method, route.Path)
}
}
if s.GenericServerRunOptions.InsecurePort != 0 {
err = http.ListenAndServe(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort), container)
if err != nil {
klog.Infof("Server listening on %d.", s.GenericServerRunOptions.InsecurePort)
}
}
if s.GenericServerRunOptions.SecurePort != 0 && len(s.GenericServerRunOptions.TlsCertFile) > 0 && len(s.GenericServerRunOptions.TlsPrivateKey) > 0 {
klog.Infof("Server listening on %d.", s.GenericServerRunOptions.SecurePort)
err = http.ListenAndServeTLS(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.SecurePort), s.GenericServerRunOptions.TlsCertFile, s.GenericServerRunOptions.TlsPrivateKey, container)
}
return err
}
func CreateClientSet(conf *apiserverconfig.Config, stopCh <-chan struct{}) error {
csop := &client.ClientSetOptions{}
csop.SetDevopsOptions(conf.DevopsOptions).
SetKubernetesOptions(conf.KubernetesOptions).
SetMySQLOptions(conf.MySQLOptions)
client.NewClientSetFactory(csop, stopCh)
return nil
}
func WaitForResourceSync(stopCh <-chan struct{}) error {
//apis.AddToScheme(scheme.Scheme)
informerFactory := informers.SharedInformerFactory() informerFactory := informers.SharedInformerFactory()
informerFactory.Rbac().V1().Roles().Lister()
informerFactory.Rbac().V1().RoleBindings().Lister()
informerFactory.Rbac().V1().ClusterRoles().Lister()
informerFactory.Rbac().V1().ClusterRoleBindings().Lister()
informerFactory.Storage().V1().StorageClasses().Lister() // resources we have to create informer first
k8sGVRs := []schema.GroupVersionResource{
{Group: "", Version: "v1", Resource: "namespaces"},
{Group: "", Version: "v1", Resource: "nodes"},
{Group: "", Version: "v1", Resource: "resourcequotas"},
{Group: "", Version: "v1", Resource: "pods"},
{Group: "", Version: "v1", Resource: "services"},
{Group: "", Version: "v1", Resource: "persistentvolumeclaims"},
{Group: "", Version: "v1", Resource: "secrets"},
{Group: "", Version: "v1", Resource: "configmaps"},
informerFactory.Core().V1().Namespaces().Lister() {Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"},
informerFactory.Core().V1().Nodes().Lister() {Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings"},
informerFactory.Core().V1().ResourceQuotas().Lister() {Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"},
informerFactory.Core().V1().Pods().Lister() {Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"},
informerFactory.Core().V1().Services().Lister()
informerFactory.Core().V1().PersistentVolumeClaims().Lister()
informerFactory.Core().V1().Secrets().Lister()
informerFactory.Core().V1().ConfigMaps().Lister()
informerFactory.Apps().V1().ControllerRevisions().Lister() {Group: "apps", Version: "v1", Resource: "deployments"},
informerFactory.Apps().V1().StatefulSets().Lister() {Group: "apps", Version: "v1", Resource: "daemonsets"},
informerFactory.Apps().V1().Deployments().Lister() {Group: "apps", Version: "v1", Resource: "replicasets"},
informerFactory.Apps().V1().DaemonSets().Lister() {Group: "apps", Version: "v1", Resource: "statefulsets"},
informerFactory.Apps().V1().ReplicaSets().Lister() {Group: "apps", Version: "v1", Resource: "controllerrevisions"},
informerFactory.Batch().V1().Jobs().Lister() {Group: "batch", Version: "v1", Resource: "jobs"},
informerFactory.Batch().V1beta1().CronJobs().Lister() {Group: "batch", Version: "v1beta1", Resource: "cronjobs"},
informerFactory.Extensions().V1beta1().Ingresses().Lister()
informerFactory.Autoscaling().V2beta2().HorizontalPodAutoscalers().Lister()
informerFactory.Start(stopChan) {Group: "extensions", Version: "v1beta1", Resource: "ingresses"},
informerFactory.WaitForCacheSync(stopChan)
{Group: "autoscaling", Version: "v2beta2", Resource: "horizontalpodautoscalers"},
}
for _, gvr := range k8sGVRs {
_, err := informerFactory.ForResource(gvr)
if err != nil {
klog.Errorf("cannot create informer for %s", gvr)
return err
}
}
informerFactory.Start(stopCh)
informerFactory.WaitForCacheSync(stopCh)
s2iInformerFactory := informers.S2iSharedInformerFactory() s2iInformerFactory := informers.S2iSharedInformerFactory()
s2iInformerFactory.Devops().V1alpha1().S2iBuilderTemplates().Lister()
s2iInformerFactory.Devops().V1alpha1().S2iRuns().Lister()
s2iInformerFactory.Devops().V1alpha1().S2iBuilders().Lister()
s2iInformerFactory.Start(stopChan) s2iGVRs := []schema.GroupVersionResource{
s2iInformerFactory.WaitForCacheSync(stopChan) {Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuildertemplates"},
{Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2iruns"},
{Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuilders"},
}
for _, gvr := range s2iGVRs {
_, err := s2iInformerFactory.ForResource(gvr)
if err != nil {
return err
}
}
s2iInformerFactory.Start(stopCh)
s2iInformerFactory.WaitForCacheSync(stopCh)
ksInformerFactory := informers.KsSharedInformerFactory() ksInformerFactory := informers.KsSharedInformerFactory()
ksInformerFactory.Tenant().V1alpha1().Workspaces().Lister()
ksInformerFactory.Devops().V1alpha1().S2iBinaries().Lister()
ksInformerFactory.Start(stopChan) ksGVRs := []schema.GroupVersionResource{
ksInformerFactory.WaitForCacheSync(stopChan) {Group: "tenant.kubesphere.io", Version: "v1alpha1", Resource: "workspaces"},
{Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibinaries"},
{Group: "servicemesh.kubesphere.io", Version: "v1alpha2", Resource: "strategies"},
{Group: "servicemesh.kubesphere.io", Version: "v1alpha2", Resource: "servicepolicies"},
}
for _, gvr := range ksGVRs {
_, err := ksInformerFactory.ForResource(gvr)
if err != nil {
return err
}
}
ksInformerFactory.Start(stopCh)
ksInformerFactory.WaitForCacheSync(stopCh)
return nil
log.Println("resources sync success") }
// apply server run options to configuration
func Complete(s *options.ServerRunOptions) error {
// loading configuration file
conf := apiserverconfig.Get()
conf.Apply(&apiserverconfig.Config{
MySQLOptions: s.MySQLOptions,
DevopsOptions: s.DevopsOptions,
SonarQubeOptions: s.SonarQubeOptions,
KubernetesOptions: s.KubernetesOptions,
ServiceMeshOptions: s.ServiceMeshOptions,
MonitoringOptions: s.MonitoringOptions,
})
s = &options.ServerRunOptions{
GenericServerRunOptions: s.GenericServerRunOptions,
KubernetesOptions: conf.KubernetesOptions,
DevopsOptions: conf.DevopsOptions,
SonarQubeOptions: conf.SonarQubeOptions,
ServiceMeshOptions: conf.ServiceMeshOptions,
MySQLOptions: conf.MySQLOptions,
MonitoringOptions: conf.MonitoringOptions,
}
return nil
} }

View File

@@ -29,10 +29,8 @@ import (
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/iam" "kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/server" "kubesphere.io/kubesphere/pkg/server"
"kubesphere.io/kubesphere/pkg/signals"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
"kubesphere.io/kubesphere/pkg/utils/jwtutil" "kubesphere.io/kubesphere/pkg/utils/jwtutil"
"kubesphere.io/kubesphere/pkg/utils/signals"
"log" "log"
"net/http" "net/http"
"time" "time"
@@ -72,9 +70,6 @@ func Run(s *options.ServerRunOptions) error {
waitForResourceSync() waitForResourceSync()
initializeAdminJenkins()
initializeDevOpsDatabase()
err = iam.Init(s.AdminEmail, s.AdminPassword, expireTime, s.AuthRateLimit) err = iam.Init(s.AdminEmail, s.AdminPassword, expireTime, s.AuthRateLimit)
jwtutil.Setup(s.JWTSecret) jwtutil.Setup(s.JWTSecret)
@@ -127,11 +122,3 @@ func waitForResourceSync() {
ksInformerFactory.WaitForCacheSync(stopChan) ksInformerFactory.WaitForCacheSync(stopChan)
log.Println("resources sync success") log.Println("resources sync success")
} }
func initializeAdminJenkins() {
admin_jenkins.Client()
}
func initializeDevOpsDatabase() {
devops_mysql.OpenDatabase()
}

36
go.mod
View File

@@ -24,7 +24,6 @@ require (
github.com/coreos/etcd v3.3.13+incompatible // indirect github.com/coreos/etcd v3.3.13+incompatible // indirect
github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/deckarep/golang-set v1.7.1 // indirect github.com/deckarep/golang-set v1.7.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/docker/distribution v2.7.1+incompatible github.com/docker/distribution v2.7.1+incompatible
@@ -59,8 +58,6 @@ require (
github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6 github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6
github.com/golang/example v0.0.0-20170904185048-46695d81d1fa github.com/golang/example v0.0.0-20170904185048-46695d81d1fa
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef // indirect
github.com/google/btree v1.0.0 // indirect
github.com/google/go-querystring v1.0.0 // indirect github.com/google/go-querystring v1.0.0 // indirect
github.com/google/gofuzz v1.0.0 // indirect github.com/google/gofuzz v1.0.0 // indirect
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
@@ -68,15 +65,12 @@ require (
github.com/gophercloud/gophercloud v0.3.0 // indirect github.com/gophercloud/gophercloud v0.3.0 // indirect
github.com/gorilla/mux v1.7.1 // indirect github.com/gorilla/mux v1.7.1 // indirect
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.9.5 // indirect github.com/grpc-ecosystem/grpc-gateway v1.9.5 // indirect
github.com/hashicorp/go-version v1.2.0 // indirect github.com/hashicorp/go-version v1.2.0 // indirect
github.com/hashicorp/golang-lru v0.5.1 // indirect github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/igm/sockjs-go v2.0.1+incompatible // indirect github.com/igm/sockjs-go v2.0.1+incompatible // indirect
github.com/imdario/mergo v0.3.7 // indirect github.com/imdario/mergo v0.3.7 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/json-iterator/go v1.1.6 github.com/json-iterator/go v1.1.6
github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect
github.com/kiali/kiali v0.15.1-0.20190407071308-6b5b818211c3 github.com/kiali/kiali v0.15.1-0.20190407071308-6b5b818211c3
@@ -114,22 +108,16 @@ require (
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 // indirect github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 // indirect
github.com/russross/blackfriday v1.5.2 // indirect github.com/russross/blackfriday v1.5.2 // indirect
github.com/satori/go.uuid v1.2.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009 github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
github.com/speps/go-hashids v2.0.0+incompatible github.com/speps/go-hashids v2.0.0+incompatible
github.com/spf13/cobra v0.0.3 github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 github.com/spf13/pflag v1.0.3
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.3.0 github.com/stretchr/testify v1.3.0
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
github.com/xanzy/ssh-agent v0.2.1 // indirect github.com/xanzy/ssh-agent v0.2.1 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.etcd.io/bbolt v1.3.3 // indirect go.etcd.io/bbolt v1.3.3 // indirect
go.uber.org/atomic v1.4.0 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.10.0 // indirect
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 golang.org/x/net v0.0.0-20190620200207-3b0461eec859
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a // indirect golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
golang.org/x/tools v0.0.0-20190710153321-831012c29e42 // indirect golang.org/x/tools v0.0.0-20190710153321-831012c29e42 // indirect
google.golang.org/appengine v1.5.0 // indirect google.golang.org/appengine v1.5.0 // indirect
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 // indirect google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 // indirect
@@ -145,15 +133,15 @@ require (
gotest.tools v2.2.0+incompatible // indirect gotest.tools v2.2.0+incompatible // indirect
k8s.io/api v0.0.0-20181213150558-05914d821849 k8s.io/api v0.0.0-20181213150558-05914d821849
k8s.io/apiextensions-apiserver v0.0.0-20181213153335-0fe22c71c476 k8s.io/apiextensions-apiserver v0.0.0-20181213153335-0fe22c71c476
k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628 k8s.io/apimachinery v0.0.0-20190831074630-461753078381
k8s.io/apiserver v0.0.0-20190507070644-e9c02aff496d k8s.io/apiserver v0.0.0-20190507070644-e9c02aff496d
k8s.io/client-go v0.0.0-20181213151034-8d9ed539ba31 k8s.io/client-go v0.0.0-20190831074946-3fe2abece89e
k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b
k8s.io/component-base v0.0.0-20190831075413-37a093468564
k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a // indirect k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a // indirect
k8s.io/klog v0.3.1 k8s.io/klog v0.4.0
k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5 k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5
k8s.io/kubernetes v1.13.6 k8s.io/kubernetes v1.13.6
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 // indirect
sigs.k8s.io/application v0.0.0-20190404151855-67ae7f915d4e sigs.k8s.io/application v0.0.0-20190404151855-67ae7f915d4e
sigs.k8s.io/controller-runtime v0.1.10 sigs.k8s.io/controller-runtime v0.1.10
sigs.k8s.io/controller-tools v0.1.12 sigs.k8s.io/controller-tools v0.1.12
@@ -188,10 +176,12 @@ replace (
github.com/anmitsu/go-shlex => github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 github.com/anmitsu/go-shlex => github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239
github.com/apache/thrift => github.com/apache/thrift v0.12.0 github.com/apache/thrift => github.com/apache/thrift v0.12.0
github.com/appscode/jsonpatch => github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30 github.com/appscode/jsonpatch => github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30
github.com/armon/consul-api => github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6
github.com/asaskevich/govalidator => github.com/asaskevich/govalidator v0.0.0-20180315120708-ccb8e960c48f github.com/asaskevich/govalidator => github.com/asaskevich/govalidator v0.0.0-20180315120708-ccb8e960c48f
github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.22.2 github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.22.2
github.com/beevik/etree => github.com/beevik/etree v1.1.0 github.com/beevik/etree => github.com/beevik/etree v1.1.0
github.com/beorn7/perks => github.com/beorn7/perks v1.0.0 github.com/beorn7/perks => github.com/beorn7/perks v1.0.0
github.com/blang/semver => github.com/blang/semver v3.5.0+incompatible
github.com/cenkalti/backoff => github.com/cenkalti/backoff v2.2.1+incompatible github.com/cenkalti/backoff => github.com/cenkalti/backoff v2.2.1+incompatible
github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.0 github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.0
github.com/cheekybits/genny => github.com/cheekybits/genny v1.0.0 github.com/cheekybits/genny => github.com/cheekybits/genny v1.0.0
@@ -270,6 +260,7 @@ replace (
github.com/hashicorp/go-syslog => github.com/hashicorp/go-syslog v1.0.0 github.com/hashicorp/go-syslog => github.com/hashicorp/go-syslog v1.0.0
github.com/hashicorp/go-version => github.com/hashicorp/go-version v1.2.0 github.com/hashicorp/go-version => github.com/hashicorp/go-version v1.2.0
github.com/hashicorp/golang-lru => github.com/hashicorp/golang-lru v0.5.1 github.com/hashicorp/golang-lru => github.com/hashicorp/golang-lru v0.5.1
github.com/hashicorp/hcl => github.com/hashicorp/hcl v1.0.0
github.com/hpcloud/tail => github.com/hpcloud/tail v1.0.0 github.com/hpcloud/tail => github.com/hpcloud/tail v1.0.0
github.com/igm/sockjs-go => github.com/igm/sockjs-go v2.0.1+incompatible github.com/igm/sockjs-go => github.com/igm/sockjs-go v2.0.1+incompatible
github.com/imdario/mergo => github.com/imdario/mergo v0.3.7 github.com/imdario/mergo => github.com/imdario/mergo v0.3.7
@@ -298,6 +289,7 @@ replace (
github.com/leodido/go-urn => github.com/leodido/go-urn v1.1.0 github.com/leodido/go-urn => github.com/leodido/go-urn v1.1.0
github.com/lib/pq => github.com/lib/pq v1.2.0 github.com/lib/pq => github.com/lib/pq v1.2.0
github.com/lucas-clemente/quic-go => github.com/lucas-clemente/quic-go v0.11.1 github.com/lucas-clemente/quic-go => github.com/lucas-clemente/quic-go v0.11.1
github.com/magiconair/properties => github.com/magiconair/properties v1.8.0
github.com/mailru/easyjson => github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 github.com/mailru/easyjson => github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329
github.com/marten-seemann/qtls => github.com/marten-seemann/qtls v0.2.3 github.com/marten-seemann/qtls => github.com/marten-seemann/qtls v0.2.3
github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.11.0 github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.11.0
@@ -306,6 +298,7 @@ replace (
github.com/mholt/certmagic => github.com/mholt/certmagic v0.5.1 github.com/mholt/certmagic => github.com/mholt/certmagic v0.5.1
github.com/miekg/dns => github.com/miekg/dns v1.1.9 github.com/miekg/dns => github.com/miekg/dns v1.1.9
github.com/mitchellh/go-homedir => github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir => github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure => github.com/mitchellh/mapstructure v1.1.2
github.com/modern-go/concurrent => github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/concurrent => github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
github.com/modern-go/reflect2 => github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 github.com/modern-go/reflect2 => github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742
github.com/morikuni/aec => github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c github.com/morikuni/aec => github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c
@@ -320,6 +313,7 @@ replace (
github.com/openzipkin/zipkin-go => github.com/openzipkin/zipkin-go v0.1.6 github.com/openzipkin/zipkin-go => github.com/openzipkin/zipkin-go v0.1.6
github.com/pborman/uuid => github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709 github.com/pborman/uuid => github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709
github.com/pelletier/go-buffruneio => github.com/pelletier/go-buffruneio v0.2.0 github.com/pelletier/go-buffruneio => github.com/pelletier/go-buffruneio v0.2.0
github.com/pelletier/go-toml => github.com/pelletier/go-toml v1.2.0
github.com/peterbourgon/diskv => github.com/peterbourgon/diskv v2.0.1+incompatible github.com/peterbourgon/diskv => github.com/peterbourgon/diskv v2.0.1+incompatible
github.com/pierrec/lz4 => github.com/pierrec/lz4 v2.0.5+incompatible github.com/pierrec/lz4 => github.com/pierrec/lz4 v2.0.5+incompatible
github.com/pkg/errors => github.com/pkg/errors v0.8.1 github.com/pkg/errors => github.com/pkg/errors v0.8.1
@@ -343,14 +337,19 @@ replace (
github.com/sony/sonyflake => github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009 github.com/sony/sonyflake => github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
github.com/speps/go-hashids => github.com/speps/go-hashids v2.0.0+incompatible github.com/speps/go-hashids => github.com/speps/go-hashids v2.0.0+incompatible
github.com/spf13/afero => github.com/spf13/afero v1.2.2 github.com/spf13/afero => github.com/spf13/afero v1.2.2
github.com/spf13/cast => github.com/spf13/cast v1.3.0
github.com/spf13/cobra => github.com/spf13/cobra v0.0.3 github.com/spf13/cobra => github.com/spf13/cobra v0.0.3
github.com/spf13/jwalterweatherman => github.com/spf13/jwalterweatherman v1.0.0
github.com/spf13/pflag => github.com/spf13/pflag v1.0.3 github.com/spf13/pflag => github.com/spf13/pflag v1.0.3
github.com/spf13/viper => github.com/spf13/viper v1.4.0
github.com/src-d/gcfg => github.com/src-d/gcfg v1.4.0 github.com/src-d/gcfg => github.com/src-d/gcfg v1.4.0
github.com/stretchr/objx => github.com/stretchr/objx v0.1.1 github.com/stretchr/objx => github.com/stretchr/objx v0.1.1
github.com/stretchr/testify => github.com/stretchr/testify v1.3.0 github.com/stretchr/testify => github.com/stretchr/testify v1.3.0
github.com/tmc/grpc-websocket-proxy => github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 github.com/tmc/grpc-websocket-proxy => github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5
github.com/ugorji/go => github.com/ugorji/go v1.1.4
github.com/xanzy/ssh-agent => github.com/xanzy/ssh-agent v0.2.1 github.com/xanzy/ssh-agent => github.com/xanzy/ssh-agent v0.2.1
github.com/xiang90/probing => github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 github.com/xiang90/probing => github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2
github.com/xordataexchange/crypt => github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77
go.etcd.io/bbolt => go.etcd.io/bbolt v1.3.3 go.etcd.io/bbolt => go.etcd.io/bbolt v1.3.3
go.opencensus.io => go.opencensus.io v0.20.2 go.opencensus.io => go.opencensus.io v0.20.2
go.uber.org/atomic => go.uber.org/atomic v1.4.0 go.uber.org/atomic => go.uber.org/atomic v1.4.0
@@ -396,8 +395,9 @@ replace (
k8s.io/apiserver => k8s.io/apiserver v0.0.0-20190507070644-e9c02aff496d k8s.io/apiserver => k8s.io/apiserver v0.0.0-20190507070644-e9c02aff496d
k8s.io/client-go => k8s.io/client-go v0.0.0-20181213151034-8d9ed539ba31 k8s.io/client-go => k8s.io/client-go v0.0.0-20181213151034-8d9ed539ba31
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b k8s.io/code-generator => k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b
k8s.io/component-base => k8s.io/component-base v0.0.0-20190831075413-37a093468564
k8s.io/gengo => k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a k8s.io/gengo => k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a
k8s.io/klog => k8s.io/klog v0.3.1 k8s.io/klog => k8s.io/klog v0.4.0
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5 k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5
k8s.io/kubernetes => k8s.io/kubernetes v1.13.6 k8s.io/kubernetes => k8s.io/kubernetes v1.13.6
k8s.io/utils => k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 k8s.io/utils => k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5

24
go.sum
View File

@@ -47,6 +47,7 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30 h1:Kn3rqvbUFqSepE2OqVu0Pn1CbDw9IuMlONapol0zuwk= github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30 h1:Kn3rqvbUFqSepE2OqVu0Pn1CbDw9IuMlONapol0zuwk=
github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M= github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/asaskevich/govalidator v0.0.0-20180315120708-ccb8e960c48f h1:y2hSFdXeA1y5z5f0vfNO0Dg5qVY036qzlz3Pds0B92o= github.com/asaskevich/govalidator v0.0.0-20180315120708-ccb8e960c48f h1:y2hSFdXeA1y5z5f0vfNO0Dg5qVY036qzlz3Pds0B92o=
github.com/asaskevich/govalidator v0.0.0-20180315120708-ccb8e960c48f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20180315120708-ccb8e960c48f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.22.2 h1:uYP58k2Cd9y1qBy8CxTe5ADmdi4kANm8Ul8ch3kkIcQ= github.com/aws/aws-sdk-go v1.22.2 h1:uYP58k2Cd9y1qBy8CxTe5ADmdi4kANm8Ul8ch3kkIcQ=
@@ -55,6 +56,7 @@ github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
@@ -202,6 +204,8 @@ github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+d
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/igm/sockjs-go v2.0.1+incompatible h1:iyv0auU1Xh1KC8N+GIiLPa3zZXwRsfRZTIzo09UzeUU= github.com/igm/sockjs-go v2.0.1+incompatible h1:iyv0auU1Xh1KC8N+GIiLPa3zZXwRsfRZTIzo09UzeUU=
@@ -254,6 +258,8 @@ github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lucas-clemente/quic-go v0.11.1 h1:zasajC848Dqq/+WqfqBCkmPw+YHNe1MBts/z7y7nXf4= github.com/lucas-clemente/quic-go v0.11.1 h1:zasajC848Dqq/+WqfqBCkmPw+YHNe1MBts/z7y7nXf4=
github.com/lucas-clemente/quic-go v0.11.1/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lucas-clemente/quic-go v0.11.1/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA= github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA=
@@ -270,6 +276,8 @@ github.com/miekg/dns v1.1.9 h1:OIdC9wT96RzuZMf2PfKRhFgsStHUUBZLM/lo1LqiM9E=
github.com/miekg/dns v1.1.9/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.9/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
@@ -296,6 +304,8 @@ github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709 h1:zNBQb37RGLmJybyMcs
github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@@ -338,10 +348,16 @@ github.com/speps/go-hashids v2.0.0+incompatible h1:kSfxGfESueJKTx0mpER9Y/1XHl+FV
github.com/speps/go-hashids v2.0.0+incompatible/go.mod h1:P7hqPzMdnZOfyIk+xrlG1QaSMw+gCBdHKsBDnhpaZvc= github.com/speps/go-hashids v2.0.0+incompatible/go.mod h1:P7hqPzMdnZOfyIk+xrlG1QaSMw+gCBdHKsBDnhpaZvc=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
@@ -350,10 +366,12 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk=
@@ -440,10 +458,12 @@ k8s.io/client-go v0.0.0-20181213151034-8d9ed539ba31 h1:OH3z6khCtxnJBAc0C5CMYWLl1
k8s.io/client-go v0.0.0-20181213151034-8d9ed539ba31/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= k8s.io/client-go v0.0.0-20181213151034-8d9ed539ba31/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b h1:KH0fUlgdFZH8UMxJ/FDCYHpczfSQKefetq5NjL6BVF0= k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b h1:KH0fUlgdFZH8UMxJ/FDCYHpczfSQKefetq5NjL6BVF0=
k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8= k8s.io/code-generator v0.0.0-20181117043124-c2090bec4d9b/go.mod h1:MYiN+ZJZ9HkETbgVZdWw2AsuAi9PZ4V80cwfuf2axe8=
k8s.io/component-base v0.0.0-20190831075413-37a093468564 h1:mY4AxuX1h/hbjrwVkBBiTGnWeh41YGfEcFIFGb9Iabs=
k8s.io/component-base v0.0.0-20190831075413-37a093468564/go.mod h1:pB3zmhcOR5xextKMKdxRr2XUCERS2UNFA/6Tr2WmSJs=
k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a h1:QoHVuRquf80YZ+/bovwxoMO3Q/A3nt3yTgS0/0nejuk= k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a h1:QoHVuRquf80YZ+/bovwxoMO3Q/A3nt3yTgS0/0nejuk=
k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ=
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5 h1:MH8SvyTlIiLt8b1oHy4Dtp1zPpLGp6lTOjvfzPTkoQE= k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5 h1:MH8SvyTlIiLt8b1oHy4Dtp1zPpLGp6lTOjvfzPTkoQE=
k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kubernetes v1.13.6 h1:eUAUryzMLFmi4ZY8kMOUtLG5lHp2PUx5WOmy4RVaobk= k8s.io/kubernetes v1.13.6 h1:eUAUryzMLFmi4ZY8kMOUtLG5lHp2PUx5WOmy4RVaobk=

View File

@@ -9,7 +9,7 @@ TAG=latest
# check if build was triggered by a travis cronjob # check if build was triggered by a travis cronjob
if [[ -z "$TRAVIS_EVENT_TYPE" ]]; then if [[ -z "$TRAVIS_EVENT_TYPE" ]]; then
echo "TRAVIS_EVENT_TYPE is empty, also normaly build" echo "TRAVIS_EVENT_TYPE is empty, also normaly build"
elif [ $TRAVIS_EVENT_TYPE == "cron" ]; then elif [[ $TRAVIS_EVENT_TYPE == "cron" ]]; then
TAG=dev-$(date +%Y%m%d) TAG=dev-$(date +%Y%m%d)
fi fi
@@ -18,6 +18,7 @@ docker build -f build/ks-apigateway/Dockerfile -t $REPO/ks-apigateway:$TAG .
docker build -f build/ks-apiserver/Dockerfile -t $REPO/ks-apiserver:$TAG . docker build -f build/ks-apiserver/Dockerfile -t $REPO/ks-apiserver:$TAG .
docker build -f build/ks-iam/Dockerfile -t $REPO/ks-account:$TAG . docker build -f build/ks-iam/Dockerfile -t $REPO/ks-account:$TAG .
docker build -f build/ks-controller-manager/Dockerfile -t $REPO/ks-controller-manager:$TAG . docker build -f build/ks-controller-manager/Dockerfile -t $REPO/ks-controller-manager:$TAG .
docker build -f build/hypersphere/Dockerfile -t $REPO/hypersphere:$TAG .
docker build -f ./pkg/db/Dockerfile -t $REPO/ks-devops:flyway-$TAG ./pkg/db/ docker build -f ./pkg/db/Dockerfile -t $REPO/ks-devops:flyway-$TAG ./pkg/db/
# Push image to dockerhub, need to support multiple push # Push image to dockerhub, need to support multiple push
@@ -27,4 +28,5 @@ docker push $REPO/ks-apigateway:$TAG
docker push $REPO/ks-apiserver:$TAG docker push $REPO/ks-apiserver:$TAG
docker push $REPO/ks-account:$TAG docker push $REPO/ks-account:$TAG
docker push $REPO/ks-controller-manager:$TAG docker push $REPO/ks-controller-manager:$TAG
docker push $REPO/hypersphere:$TAG
docker push $REPO/ks-devops:flyway-$TAG docker push $REPO/ks-devops:flyway-$TAG

View File

@@ -168,7 +168,7 @@ func addWebService(c *restful.Container) error {
Param(webservice.PathParameter("workload", "workload name").Required(true)). Param(webservice.PathParameter("workload", "workload name").Required(true)).
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)). Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
Param(webservice.QueryParameter("queryTime", "the time to use for query")). Param(webservice.QueryParameter("queryTime", "the time to use for query")).
ReturnsError(http.StatusOK, "ok", workloadHealthResponse{}). Returns(http.StatusOK, "ok", workloadHealthResponse{}).
Writes(workloadHealthResponse{})).Produces(restful.MIME_JSON) Writes(workloadHealthResponse{})).Produces(restful.MIME_JSON)
// Get app health // Get app health

View File

@@ -20,8 +20,14 @@ package monitoring
import ( import (
"fmt" "fmt"
"github.com/emicklei/go-restful" "github.com/emicklei/go-restful"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/metrics" "kubesphere.io/kubesphere/pkg/models/metrics"
"kubesphere.io/kubesphere/pkg/simple/client/prometheus" "kubesphere.io/kubesphere/pkg/simple/client"
"net/url"
"strconv"
"strings"
"time"
) )
func MonitorAllPodsOfSpecificNamespace(request *restful.Request, response *restful.Response) { func MonitorAllPodsOfSpecificNamespace(request *restful.Request, response *restful.Response) {
@@ -41,7 +47,7 @@ func MonitorSpecificPodOnSpecificNode(request *restful.Request, response *restfu
} }
func MonitorPod(request *restful.Request, response *restful.Response) { func MonitorPod(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
podName := requestParams.PodName podName := requestParams.PodName
if podName != "" { if podName != "" {
requestParams.ResourcesFilter = fmt.Sprintf("^%s$", requestParams.PodName) requestParams.ResourcesFilter = fmt.Sprintf("^%s$", requestParams.PodName)
@@ -68,7 +74,7 @@ func MonitorSpecificContainerOfSpecificNamespace(request *restful.Request, respo
} }
func MonitorContainer(request *restful.Request, response *restful.Response) { func MonitorContainer(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
rawMetrics := metrics.GetContainerLevelMetrics(requestParams) rawMetrics := metrics.GetContainerLevelMetrics(requestParams)
// sorting // sorting
sortedMetrics, maxMetricCount := metrics.Sort(requestParams.SortMetricName, requestParams.SortType, rawMetrics) sortedMetrics, maxMetricCount := metrics.Sort(requestParams.SortMetricName, requestParams.SortType, rawMetrics)
@@ -91,7 +97,7 @@ func MonitorAllWorkloadsOfSpecificNamespace(request *restful.Request, response *
} }
func MonitorWorkload(request *restful.Request, response *restful.Response) { func MonitorWorkload(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
rawMetrics := metrics.GetWorkloadLevelMetrics(requestParams) rawMetrics := metrics.GetWorkloadLevelMetrics(requestParams)
@@ -107,7 +113,7 @@ func MonitorWorkload(request *restful.Request, response *restful.Response) {
func MonitorAllWorkspaces(request *restful.Request, response *restful.Response) { func MonitorAllWorkspaces(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
tp := requestParams.Tp tp := requestParams.Tp
if tp == "statistics" { if tp == "statistics" {
@@ -129,7 +135,7 @@ func MonitorAllWorkspaces(request *restful.Request, response *restful.Response)
} }
func MonitorSpecificWorkspace(request *restful.Request, response *restful.Response) { func MonitorSpecificWorkspace(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
tp := requestParams.Tp tp := requestParams.Tp
if tp == "rank" { if tp == "rank" {
@@ -164,7 +170,7 @@ func MonitorSpecificNamespace(request *restful.Request, response *restful.Respon
} }
func MonitorNamespace(request *restful.Request, response *restful.Response) { func MonitorNamespace(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
// multiple // multiple
rawMetrics := metrics.GetNamespaceLevelMetrics(requestParams) rawMetrics := metrics.GetNamespaceLevelMetrics(requestParams)
@@ -176,13 +182,23 @@ func MonitorNamespace(request *restful.Request, response *restful.Response) {
} }
func MonitorCluster(request *restful.Request, response *restful.Response) { func MonitorCluster(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
metricName := requestParams.MetricsName metricName := requestParams.MetricsName
if metricName != "" { if metricName != "" {
prometheusClient, err := client.ClientSets().Prometheus()
if err != nil {
if _, ok := err.(client.ClientSetNotEnabledError); ok {
klog.Error("monitoring is not enabled")
return
} else {
klog.Errorf("get prometheus client failed %+v", err)
}
}
// single // single
queryType, params := metrics.AssembleClusterMetricRequestInfo(requestParams, metricName) queryType, params := metrics.AssembleClusterMetricRequestInfo(requestParams, metricName)
metricsStr := prometheus.SendMonitoringRequest(prometheus.PrometheusEndpoint, queryType, params) metricsStr := prometheusClient.SendMonitoringRequest(queryType, params)
res := metrics.ReformatJson(metricsStr, metricName, map[string]string{metrics.MetricLevelCluster: "local"}) res := metrics.ReformatJson(metricsStr, metricName, map[string]string{metrics.MetricLevelCluster: "local"})
response.WriteAsJson(res) response.WriteAsJson(res)
@@ -202,13 +218,22 @@ func MonitorSpecificNode(request *restful.Request, response *restful.Response) {
} }
func MonitorNode(request *restful.Request, response *restful.Response) { func MonitorNode(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
metricName := requestParams.MetricsName metricName := requestParams.MetricsName
if metricName != "" { if metricName != "" {
prometheusClient, err := client.ClientSets().Prometheus()
if err != nil {
if _, ok := err.(client.ClientSetNotEnabledError); ok {
klog.Error("monitoring is not enabled")
return
} else {
klog.Errorf("get prometheus client failed %+v", err)
}
}
// single // single
queryType, params := metrics.AssembleNodeMetricRequestInfo(requestParams, metricName) queryType, params := metrics.AssembleNodeMetricRequestInfo(requestParams, metricName)
metricsStr := prometheus.SendMonitoringRequest(prometheus.PrometheusEndpoint, queryType, params) metricsStr := prometheusClient.SendMonitoringRequest(queryType, params)
res := metrics.ReformatJson(metricsStr, metricName, map[string]string{metrics.MetricLevelNode: ""}) res := metrics.ReformatJson(metricsStr, metricName, map[string]string{metrics.MetricLevelNode: ""})
// The raw node-exporter result doesn't include ip address information // The raw node-exporter result doesn't include ip address information
// Thereby, append node ip address to .data.result[].metric // Thereby, append node ip address to .data.result[].metric
@@ -248,7 +273,7 @@ func MonitorSpecificPVCofSpecificNamespace(request *restful.Request, response *r
} }
func MonitorPVC(request *restful.Request, response *restful.Response) { func MonitorPVC(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
pvcName := requestParams.PVCName pvcName := requestParams.PVCName
if pvcName != "" { if pvcName != "" {
requestParams.ResourcesFilter = fmt.Sprintf("^%s$", requestParams.PVCName) requestParams.ResourcesFilter = fmt.Sprintf("^%s$", requestParams.PVCName)
@@ -263,7 +288,7 @@ func MonitorPVC(request *restful.Request, response *restful.Response) {
} }
func MonitorComponent(request *restful.Request, response *restful.Response) { func MonitorComponent(request *restful.Request, response *restful.Response) {
requestParams := prometheus.ParseMonitoringRequestParams(request) requestParams := ParseMonitoringRequestParams(request)
if requestParams.MetricsFilter == "" { if requestParams.MetricsFilter == "" {
requestParams.MetricsFilter = requestParams.ComponentName + "_.*" requestParams.MetricsFilter = requestParams.ComponentName + "_.*"
@@ -273,3 +298,113 @@ func MonitorComponent(request *restful.Request, response *restful.Response) {
response.WriteAsJson(rawMetrics) response.WriteAsJson(rawMetrics)
} }
func ParseMonitoringRequestParams(request *restful.Request) *metrics.MonitoringRequestParams {
instantTime := strings.Trim(request.QueryParameter("time"), " ")
start := strings.Trim(request.QueryParameter("start"), " ")
end := strings.Trim(request.QueryParameter("end"), " ")
step := strings.Trim(request.QueryParameter("step"), " ")
timeout := strings.Trim(request.QueryParameter("timeout"), " ")
sortMetricName := strings.Trim(request.QueryParameter("sort_metric"), " ")
sortType := strings.Trim(request.QueryParameter("sort_type"), " ")
pageNum := strings.Trim(request.QueryParameter("page"), " ")
limitNum := strings.Trim(request.QueryParameter("limit"), " ")
tp := strings.Trim(request.QueryParameter("type"), " ")
metricsFilter := strings.Trim(request.QueryParameter("metrics_filter"), " ")
resourcesFilter := strings.Trim(request.QueryParameter("resources_filter"), " ")
metricsName := strings.Trim(request.QueryParameter("metrics_name"), " ")
workloadName := strings.Trim(request.PathParameter("workload"), " ")
nodeId := strings.Trim(request.PathParameter("node"), " ")
wsName := strings.Trim(request.PathParameter("workspace"), " ")
nsName := strings.Trim(request.PathParameter("namespace"), " ")
podName := strings.Trim(request.PathParameter("pod"), " ")
pvcName := strings.Trim(request.PathParameter("pvc"), " ")
storageClassName := strings.Trim(request.PathParameter("storageclass"), " ")
containerName := strings.Trim(request.PathParameter("container"), " ")
workloadKind := strings.Trim(request.PathParameter("kind"), " ")
componentName := strings.Trim(request.PathParameter("component"), " ")
var requestParams = metrics.MonitoringRequestParams{
SortMetricName: sortMetricName,
SortType: sortType,
PageNum: pageNum,
LimitNum: limitNum,
Tp: tp,
MetricsFilter: metricsFilter,
ResourcesFilter: resourcesFilter,
MetricsName: metricsName,
WorkloadName: workloadName,
NodeId: nodeId,
WsName: wsName,
NsName: nsName,
PodName: podName,
PVCName: pvcName,
StorageClassName: storageClassName,
ContainerName: containerName,
WorkloadKind: workloadKind,
ComponentName: componentName,
}
if timeout == "" {
timeout = metrics.DefaultQueryTimeout
}
if step == "" {
step = metrics.DefaultQueryStep
}
// Whether query or query_range request
u := url.Values{}
if start != "" && end != "" {
u.Set("start", convertTimeGranularity(start))
u.Set("end", convertTimeGranularity(end))
u.Set("step", step)
u.Set("timeout", timeout)
// range query start time must be greater than the namespace creation time
if nsName != "" {
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
ns, err := nsLister.Get(nsName)
if err == nil {
queryStartTime := u.Get("start")
nsCreationTime := strconv.FormatInt(ns.CreationTimestamp.Unix(), 10)
if nsCreationTime > queryStartTime {
u.Set("start", nsCreationTime)
}
}
}
requestParams.QueryType = metrics.RangeQueryType
requestParams.Params = u
return &requestParams
}
if instantTime != "" {
u.Set("time", instantTime)
u.Set("timeout", timeout)
requestParams.QueryType = metrics.DefaultQueryType
requestParams.Params = u
return &requestParams
} else {
u.Set("timeout", timeout)
requestParams.QueryType = metrics.DefaultQueryType
requestParams.Params = u
return &requestParams
}
}
func convertTimeGranularity(ts string) string {
timeFloat, err := strconv.ParseFloat(ts, 64)
if err != nil {
klog.Errorf("convert second timestamp %s to minute timestamp failed", ts)
return strconv.FormatInt(int64(time.Now().Unix()), 10)
}
timeInt := int64(timeFloat)
// convert second timestamp to minute timestamp
secondTime := time.Unix(timeInt, 0).Truncate(time.Minute).Unix()
return strconv.FormatInt(secondTime, 10)
}

View File

@@ -22,11 +22,11 @@ import (
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
log "k8s.io/klog"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
servicemeshinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh/v1alpha2" servicemeshinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh/v1alpha2"
servicemeshlisters "kubesphere.io/kubesphere/pkg/client/listers/servicemesh/v1alpha2" servicemeshlisters "kubesphere.io/kubesphere/pkg/client/listers/servicemesh/v1alpha2"
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util" "kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
) )
const ( const (
@@ -38,8 +38,6 @@ const (
maxRetries = 15 maxRetries = 15
) )
var log = logf.Log.WithName("application-controller")
type ApplicationController struct { type ApplicationController struct {
client clientset.Interface client clientset.Interface

View File

@@ -27,6 +27,7 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
log "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/utils/k8sutil" "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"reflect" "reflect"
@@ -35,14 +36,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/reconcile"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
"sigs.k8s.io/controller-runtime/pkg/source" "sigs.k8s.io/controller-runtime/pkg/source"
) )
var (
log = logf.Log.WithName("clusterrolebinding-controller")
)
/** /**
* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller * USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller
* business logic. Delete these comments after modifying this file.* * business logic. Delete these comments after modifying this file.*
@@ -139,7 +135,7 @@ func (r *ReconcileClusterRoleBinding) updateRoleBindings(clusterRoleBinding *rba
err := r.Get(context.TODO(), types.NamespacedName{Namespace: namespace.Name, Name: adminBinding.Name}, found) err := r.Get(context.TODO(), types.NamespacedName{Namespace: namespace.Name, Name: adminBinding.Name}, found)
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
log.Info("Creating default role binding", "namespace", namespace.Name, "name", adminBinding.Name) log.V(4).Info("Creating default role binding", "namespace", namespace.Name, "name", adminBinding.Name)
err = r.Create(context.TODO(), adminBinding) err = r.Create(context.TODO(), adminBinding)
if err != nil { if err != nil {
log.Error(err, "default role binding create failed", "namespace", namespace.Name, "name", adminBinding.Name) log.Error(err, "default role binding create failed", "namespace", namespace.Name, "name", adminBinding.Name)
@@ -151,7 +147,7 @@ func (r *ReconcileClusterRoleBinding) updateRoleBindings(clusterRoleBinding *rba
} }
if !reflect.DeepEqual(found.RoleRef, adminBinding.RoleRef) { if !reflect.DeepEqual(found.RoleRef, adminBinding.RoleRef) {
log.Info("Deleting conflict role binding", "namespace", namespace.Name, "name", adminBinding.Name) log.V(4).Info("Deleting conflict role binding", "namespace", namespace.Name, "name", adminBinding.Name)
err = r.Delete(context.TODO(), found) err = r.Delete(context.TODO(), found)
if err != nil { if err != nil {
return err return err
@@ -161,7 +157,7 @@ func (r *ReconcileClusterRoleBinding) updateRoleBindings(clusterRoleBinding *rba
if !reflect.DeepEqual(found.Subjects, adminBinding.Subjects) { if !reflect.DeepEqual(found.Subjects, adminBinding.Subjects) {
found.Subjects = adminBinding.Subjects found.Subjects = adminBinding.Subjects
log.Info("Updating role binding", "namespace", namespace.Name, "name", adminBinding.Name) log.V(4).Info("Updating role binding", "namespace", namespace.Name, "name", adminBinding.Name)
err = r.Update(context.TODO(), found) err = r.Update(context.TODO(), found)
if err != nil { if err != nil {
return err return err

View File

@@ -16,10 +16,10 @@ import (
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/kubernetes/scheme"
v1core "k8s.io/client-go/kubernetes/typed/core/v1" v1core "k8s.io/client-go/kubernetes/typed/core/v1"
log "k8s.io/klog"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util" "kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
"time" "time"
@@ -49,8 +49,6 @@ const (
maxRetries = 15 maxRetries = 15
) )
var log = logf.Log.WithName("destinationrule-controller")
type DestinationRuleController struct { type DestinationRuleController struct {
client clientset.Interface client clientset.Interface

View File

@@ -30,8 +30,8 @@ import (
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
batchv1informers "k8s.io/client-go/informers/batch/v1" batchv1informers "k8s.io/client-go/informers/batch/v1"
batchv1listers "k8s.io/client-go/listers/batch/v1" batchv1listers "k8s.io/client-go/listers/batch/v1"
log "k8s.io/klog"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
"time" "time"
@@ -51,8 +51,6 @@ const (
revisionsAnnotationKey = "revisions" revisionsAnnotationKey = "revisions"
) )
var log = logf.Log.WithName("job-controller")
type JobController struct { type JobController struct {
client clientset.Interface client clientset.Interface
eventBroadcaster record.EventBroadcaster eventBroadcaster record.EventBroadcaster

View File

@@ -33,6 +33,7 @@ import (
"k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
cs "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix" "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/utils/k8sutil" "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
@@ -356,6 +357,10 @@ func (r *ReconcileNamespace) checkAndCreateRoleBindings(namespace *corev1.Namesp
// Create openpitrix runtime // Create openpitrix runtime
func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace) error { func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace) error {
openPitrixClient, err := cs.ClientSets().OpenPitrix()
if err != nil {
return err
}
if runtimeId := namespace.Annotations[constants.OpenPitrixRuntimeAnnotationKey]; runtimeId != "" { if runtimeId := namespace.Annotations[constants.OpenPitrixRuntimeAnnotationKey]; runtimeId != "" {
return nil return nil
@@ -363,7 +368,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace)
cm := &corev1.ConfigMap{} cm := &corev1.ConfigMap{}
configName := fmt.Sprintf("kubeconfig-%s", constants.AdminUserName) configName := fmt.Sprintf("kubeconfig-%s", constants.AdminUserName)
err := r.Get(context.TODO(), types.NamespacedName{Namespace: constants.KubeSphereControlNamespace, Name: configName}, cm) err = r.Get(context.TODO(), types.NamespacedName{Namespace: constants.KubeSphereControlNamespace, Name: configName}, cm)
if err != nil { if err != nil {
return err return err
@@ -371,7 +376,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace)
runtime := &openpitrix.RunTime{Name: namespace.Name, Zone: namespace.Name, Provider: "kubernetes", RuntimeCredential: cm.Data["config"]} runtime := &openpitrix.RunTime{Name: namespace.Name, Zone: namespace.Name, Provider: "kubernetes", RuntimeCredential: cm.Data["config"]}
if err := openpitrix.Client().CreateRuntime(runtime); err != nil { if err := openPitrixClient.CreateRuntime(runtime); err != nil {
klog.Errorf("creating openpitrix runtime namespace: %s, error: %s", namespace.Name, err) klog.Errorf("creating openpitrix runtime namespace: %s, error: %s", namespace.Name, err)
return err return err
} }
@@ -387,7 +392,12 @@ func (r *ReconcileNamespace) deleteRuntime(namespace *corev1.Namespace) error {
for i := float64(0); i < maxRetries; i++ { for i := float64(0); i < maxRetries; i++ {
time.Sleep(time.Duration(i*math.Pow(2, i)) * time.Second) time.Sleep(time.Duration(i*math.Pow(2, i)) * time.Second)
err := openpitrix.Client().DeleteRuntime(runtimeId) openPitrixClient, err := cs.ClientSets().OpenPitrix()
if err != nil {
return err
}
err = openPitrixClient.DeleteRuntime(runtimeId)
if err == nil || openpitrix.IsNotFound(err) || openpitrix.IsDeleted(err) { if err == nil || openpitrix.IsNotFound(err) || openpitrix.IsDeleted(err) {
return nil return nil

View File

@@ -71,9 +71,9 @@ var _ = Describe("Wsnetworkpolicy", func() {
wsnp := newWorkspaceNP(testName) wsnp := newWorkspaceNP(testName)
wsnp.Spec.PolicyTypes = []k8snetwork.PolicyType{k8snetwork.PolicyTypeIngress} wsnp.Spec.PolicyTypes = []k8snetwork.PolicyType{k8snetwork.PolicyTypeIngress}
wsnp.Spec.Ingress = []v1alpha1.WorkspaceNetworkPolicyIngressRule{ wsnp.Spec.Ingress = []v1alpha1.WorkspaceNetworkPolicyIngressRule{
v1alpha1.WorkspaceNetworkPolicyIngressRule{ {
From: []v1alpha1.WorkspaceNetworkPolicyPeer{ From: []v1alpha1.WorkspaceNetworkPolicyPeer{
v1alpha1.WorkspaceNetworkPolicyPeer{ {
WorkspaceSelector: &metav1.LabelSelector{ WorkspaceSelector: &metav1.LabelSelector{
MatchLabels: label, MatchLabels: label,
}, },

View File

@@ -17,7 +17,7 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3" "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"time" "time"
@@ -210,12 +210,16 @@ func (c *S2iBinaryController) syncHandler(key string) error {
} }
func (c *S2iBinaryController) deleteBinaryInS3(s2ibin *devopsv1alpha1.S2iBinary) error { func (c *S2iBinaryController) deleteBinaryInS3(s2ibin *devopsv1alpha1.S2iBinary) error {
s3client := s2is3.Client() s3Client, err := client.ClientSets().S3()
if err != nil {
return err
}
input := &s3.DeleteObjectInput{ input := &s3.DeleteObjectInput{
Bucket: s2is3.Bucket(), Bucket: s3Client.Bucket(),
Key: aws.String(fmt.Sprintf("%s-%s", s2ibin.Namespace, s2ibin.Name)), Key: aws.String(fmt.Sprintf("%s-%s", s2ibin.Namespace, s2ibin.Name)),
} }
_, err := s3client.DeleteObject(input) _, err = s3Client.Client().DeleteObject(input)
if err != nil { if err != nil {
if aerr, ok := err.(awserr.Error); ok { if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() { switch aerr.Code() {

View File

@@ -16,9 +16,9 @@ import (
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/kubernetes/scheme"
v1core "k8s.io/client-go/kubernetes/typed/core/v1" v1core "k8s.io/client-go/kubernetes/typed/core/v1"
log "k8s.io/klog"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util" "kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
istioclient "github.com/knative/pkg/client/clientset/versioned" istioclient "github.com/knative/pkg/client/clientset/versioned"
istioinformers "github.com/knative/pkg/client/informers/externalversions/istio/v1alpha3" istioinformers "github.com/knative/pkg/client/informers/externalversions/istio/v1alpha3"
@@ -46,8 +46,6 @@ const (
maxRetries = 15 maxRetries = 15
) )
var log = logf.Log.WithName("virtualservice-controller")
type VirtualServiceController struct { type VirtualServiceController struct {
client clientset.Interface client clientset.Interface
@@ -152,7 +150,7 @@ func (v *VirtualServiceController) Run(workers int, stopCh <-chan struct{}) erro
defer utilruntime.HandleCrash() defer utilruntime.HandleCrash()
defer v.queue.ShutDown() defer v.queue.ShutDown()
log.Info("starting virtualservice controller") log.V(0).Info("starting virtualservice controller")
defer log.Info("shutting down virtualservice controller") defer log.Info("shutting down virtualservice controller")
if !cache.WaitForCacheSync(stopCh, v.serviceSynced, v.virtualServiceSynced, v.destinationRuleSynced, v.strategySynced) { if !cache.WaitForCacheSync(stopCh, v.serviceSynced, v.virtualServiceSynced, v.destinationRuleSynced, v.strategySynced) {

View File

@@ -18,15 +18,12 @@
package informers package informers
import ( import (
s2iinformers "github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions"
k8sinformers "k8s.io/client-go/informers"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/simple/client"
"sync" "sync"
"time" "time"
s2iInformers "github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions"
"k8s.io/client-go/informers"
ksInformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
) )
const defaultResync = 600 * time.Second const defaultResync = 600 * time.Second
@@ -35,31 +32,31 @@ var (
k8sOnce sync.Once k8sOnce sync.Once
s2iOnce sync.Once s2iOnce sync.Once
ksOnce sync.Once ksOnce sync.Once
informerFactory informers.SharedInformerFactory informerFactory k8sinformers.SharedInformerFactory
s2iInformerFactory s2iInformers.SharedInformerFactory s2iInformerFactory s2iinformers.SharedInformerFactory
ksInformerFactory ksInformers.SharedInformerFactory ksInformerFactory ksinformers.SharedInformerFactory
) )
func SharedInformerFactory() informers.SharedInformerFactory { func SharedInformerFactory() k8sinformers.SharedInformerFactory {
k8sOnce.Do(func() { k8sOnce.Do(func() {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
informerFactory = informers.NewSharedInformerFactory(k8sClient, defaultResync) informerFactory = k8sinformers.NewSharedInformerFactory(k8sClient, defaultResync)
}) })
return informerFactory return informerFactory
} }
func S2iSharedInformerFactory() s2iInformers.SharedInformerFactory { func S2iSharedInformerFactory() s2iinformers.SharedInformerFactory {
s2iOnce.Do(func() { s2iOnce.Do(func() {
k8sClient := k8s.S2iClient() k8sClient := client.ClientSets().K8s().S2i()
s2iInformerFactory = s2iInformers.NewSharedInformerFactory(k8sClient, defaultResync) s2iInformerFactory = s2iinformers.NewSharedInformerFactory(k8sClient, defaultResync)
}) })
return s2iInformerFactory return s2iInformerFactory
} }
func KsSharedInformerFactory() ksInformers.SharedInformerFactory { func KsSharedInformerFactory() ksinformers.SharedInformerFactory {
ksOnce.Do(func() { ksOnce.Do(func() {
k8sClient := k8s.KsClient() k8sClient := client.ClientSets().K8s().KubeSphere()
ksInformerFactory = ksInformers.NewSharedInformerFactory(k8sClient, defaultResync) ksInformerFactory = ksinformers.NewSharedInformerFactory(k8sClient, defaultResync)
}) })
return ksInformerFactory return ksInformerFactory
} }

View File

@@ -31,7 +31,7 @@ import (
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources" "kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params" "kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix" "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"strings" "strings"
"time" "time"
@@ -63,7 +63,11 @@ type workLoads struct {
} }
func ListApplication(runtimeId string, conditions *params.Conditions, limit, offset int) (*models.PageableResponse, error) { func ListApplication(runtimeId string, conditions *params.Conditions, limit, offset int) (*models.PageableResponse, error) {
clusterList, err := openpitrix.ListClusters(runtimeId, conditions.Match["keyword"], conditions.Match["status"], limit, offset) openPitrixClient, err := client.ClientSets().OpenPitrix()
if err != nil {
return nil, err
}
clusterList, err := openPitrixClient.ListClusters(runtimeId, conditions.Match["keyword"], conditions.Match["status"], limit, offset)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -76,13 +80,13 @@ func ListApplication(runtimeId string, conditions *params.Conditions, limit, off
app.ClusterID = item.ClusterID app.ClusterID = item.ClusterID
app.UpdateTime = item.UpdateTime app.UpdateTime = item.UpdateTime
app.Status = item.Status app.Status = item.Status
versionInfo, _ := openpitrix.GetVersion(item.VersionID) versionInfo, _ := openPitrixClient.GetVersion(item.VersionID)
app.Version = versionInfo app.Version = versionInfo
app.VersionId = item.VersionID app.VersionId = item.VersionID
runtimeInfo, _ := openpitrix.GetRuntime(item.RunTimeId) runtimeInfo, _ := openPitrixClient.GetRuntime(item.RunTimeId)
app.Runtime = runtimeInfo app.Runtime = runtimeInfo
app.RuntimeId = item.RunTimeId app.RuntimeId = item.RunTimeId
appInfo, _, appId, _ := openpitrix.GetAppInfo(item.AppID) appInfo, _, appId, _ := openPitrixClient.GetAppInfo(item.AppID)
app.App = appInfo app.App = appInfo
app.AppId = appId app.AppId = appId
app.Description = item.Description app.Description = item.Description
@@ -94,8 +98,11 @@ func ListApplication(runtimeId string, conditions *params.Conditions, limit, off
} }
func GetApp(clusterId string) (*Application, error) { func GetApp(clusterId string) (*Application, error) {
openPitrixClient, err := client.ClientSets().OpenPitrix()
item, err := openpitrix.GetCluster(clusterId) if err != nil {
return nil, err
}
item, err := openPitrixClient.GetCluster(clusterId)
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
@@ -109,19 +116,19 @@ func GetApp(clusterId string) (*Application, error) {
app.UpdateTime = item.UpdateTime app.UpdateTime = item.UpdateTime
app.CreateTime = item.CreateTime app.CreateTime = item.CreateTime
app.Status = item.Status app.Status = item.Status
versionInfo, _ := openpitrix.GetVersion(item.VersionID) versionInfo, _ := openPitrixClient.GetVersion(item.VersionID)
app.Version = versionInfo app.Version = versionInfo
app.VersionId = item.VersionID app.VersionId = item.VersionID
runtimeInfo, _ := openpitrix.GetRuntime(item.RunTimeId) runtimeInfo, _ := openPitrixClient.GetRuntime(item.RunTimeId)
app.Runtime = runtimeInfo app.Runtime = runtimeInfo
app.RuntimeId = item.RunTimeId app.RuntimeId = item.RunTimeId
appInfo, repoId, appId, _ := openpitrix.GetAppInfo(item.AppID) appInfo, repoId, appId, _ := openPitrixClient.GetAppInfo(item.AppID)
app.App = appInfo app.App = appInfo
app.AppId = appId app.AppId = appId
app.Description = item.Description app.Description = item.Description
app.RepoName, _ = openpitrix.GetRepo(repoId) app.RepoName, _ = openPitrixClient.GetRepo(repoId)
workloads, err := getWorkLoads(app.Runtime, item.ClusterRoleSets) workloads, err := getWorkLoads(app.Runtime, item.ClusterRoleSets)
if err != nil { if err != nil {
@@ -195,7 +202,7 @@ func getWorkLoads(namespace string, clusterRoles []openpitrix.ClusterRole) (*wor
} }
func getLabels(namespace string, workloads *workLoads) *[]map[string]string { func getLabels(namespace string, workloads *workLoads) *[]map[string]string {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
var workloadLables []map[string]string var workloadLables []map[string]string
if workloads == nil { if workloads == nil {
@@ -242,7 +249,7 @@ func getSvcs(namespace string, workLoadLabels *[]map[string]string) []v1.Service
if len(*workLoadLabels) == 0 { if len(*workLoadLabels) == 0 {
return nil return nil
} }
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
var services []v1.Service var services []v1.Service
for _, label := range *workLoadLabels { for _, label := range *workLoadLabels {
labelSelector := labels.Set(label).AsSelector().String() labelSelector := labels.Set(label).AsSelector().String()
@@ -302,6 +309,11 @@ func getIng(namespace string, services []v1.Service) []v1beta1.Ingress {
} }
func DeployApplication(namespace string, app openpitrix.CreateClusterRequest) error { func DeployApplication(namespace string, app openpitrix.CreateClusterRequest) error {
openPitrixClient, err := client.ClientSets().OpenPitrix()
if err != nil {
return err
}
ns, err := informers.SharedInformerFactory().Core().V1().Namespaces().Lister().Get(namespace) ns, err := informers.SharedInformerFactory().Core().V1().Namespaces().Lister().Get(namespace)
if err != nil { if err != nil {
glog.Errorf("deploy application failed: %+v", err) glog.Errorf("deploy application failed: %+v", err)
@@ -313,9 +325,14 @@ func DeployApplication(namespace string, app openpitrix.CreateClusterRequest) er
} else { } else {
return fmt.Errorf("runtime not init: namespace %s", namespace) return fmt.Errorf("runtime not init: namespace %s", namespace)
} }
return openpitrix.CreateCluster(app) return openPitrixClient.CreateCluster(app)
} }
func DeleteApplication(clusterId string) error { func DeleteApplication(clusterId string) error {
return openpitrix.DeleteCluster(openpitrix.DeleteClusterRequest{ClusterId: []string{clusterId}}) openPitrixClient, err := client.ClientSets().OpenPitrix()
if err != nil {
return err
}
return openPitrixClient.DeleteCluster(openpitrix.DeleteClusterRequest{ClusterId: []string{clusterId}})
} }

View File

@@ -19,9 +19,9 @@ package components
import ( import (
"fmt" "fmt"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
@@ -93,7 +93,7 @@ func GetSystemHealthStatus() (*models.HealthStatus, error) {
status := &models.HealthStatus{} status := &models.HealthStatus{}
componentStatuses, err := k8s.Client().CoreV1().ComponentStatuses().List(meta_v1.ListOptions{}) componentStatuses, err := client.ClientSets().K8s().Kubernetes().CoreV1().ComponentStatuses().List(metav1.ListOptions{})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -16,9 +16,10 @@ package devops
import ( import (
"fmt" "fmt"
"github.com/fatih/structs" "github.com/fatih/structs"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/db" "kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/gojenkins" "kubesphere.io/kubesphere/pkg/gojenkins"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql" "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/reflectutils" "kubesphere.io/kubesphere/pkg/utils/reflectutils"
"kubesphere.io/kubesphere/pkg/utils/stringutils" "kubesphere.io/kubesphere/pkg/utils/stringutils"
) )
@@ -126,7 +127,7 @@ var JenkinsOwnerProjectPermissionIds = &gojenkins.ProjectPermissionIds{
} }
var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
ProjectOwner: gojenkins.ProjectPermissionIds{ ProjectOwner: {
CredentialCreate: true, CredentialCreate: true,
CredentialDelete: true, CredentialDelete: true,
CredentialManageDomains: true, CredentialManageDomains: true,
@@ -146,7 +147,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true, RunUpdate: true,
SCMTag: true, SCMTag: true,
}, },
ProjectMaintainer: gojenkins.ProjectPermissionIds{ ProjectMaintainer: {
CredentialCreate: true, CredentialCreate: true,
CredentialDelete: true, CredentialDelete: true,
CredentialManageDomains: true, CredentialManageDomains: true,
@@ -166,7 +167,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true, RunUpdate: true,
SCMTag: true, SCMTag: true,
}, },
ProjectDeveloper: gojenkins.ProjectPermissionIds{ ProjectDeveloper: {
CredentialCreate: false, CredentialCreate: false,
CredentialDelete: false, CredentialDelete: false,
CredentialManageDomains: false, CredentialManageDomains: false,
@@ -186,7 +187,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true, RunUpdate: true,
SCMTag: false, SCMTag: false,
}, },
ProjectReporter: gojenkins.ProjectPermissionIds{ ProjectReporter: {
CredentialCreate: false, CredentialCreate: false,
CredentialDelete: false, CredentialDelete: false,
CredentialManageDomains: false, CredentialManageDomains: false,
@@ -209,7 +210,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
} }
var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
ProjectOwner: gojenkins.ProjectPermissionIds{ ProjectOwner: {
CredentialCreate: true, CredentialCreate: true,
CredentialDelete: true, CredentialDelete: true,
CredentialManageDomains: true, CredentialManageDomains: true,
@@ -229,7 +230,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true, RunUpdate: true,
SCMTag: true, SCMTag: true,
}, },
ProjectMaintainer: gojenkins.ProjectPermissionIds{ ProjectMaintainer: {
CredentialCreate: true, CredentialCreate: true,
CredentialDelete: true, CredentialDelete: true,
CredentialManageDomains: true, CredentialManageDomains: true,
@@ -249,7 +250,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true, RunUpdate: true,
SCMTag: true, SCMTag: true,
}, },
ProjectDeveloper: gojenkins.ProjectPermissionIds{ ProjectDeveloper: {
CredentialCreate: false, CredentialCreate: false,
CredentialDelete: false, CredentialDelete: false,
CredentialManageDomains: false, CredentialManageDomains: false,
@@ -269,7 +270,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true, RunUpdate: true,
SCMTag: false, SCMTag: false,
}, },
ProjectReporter: gojenkins.ProjectPermissionIds{ ProjectReporter: {
CredentialCreate: false, CredentialCreate: false,
CredentialDelete: false, CredentialDelete: false,
CredentialManageDomains: false, CredentialManageDomains: false,
@@ -311,9 +312,18 @@ func CheckProjectUserInRole(username, projectId string, roles []string) error {
if username == KS_ADMIN { if username == KS_ADMIN {
return nil return nil
} }
dbconn := devops_mysql.OpenDatabase() dbconn, err := client.ClientSets().MySQL()
if err != nil {
if _, ok := err.(client.ClientSetNotEnabledError); ok {
klog.Error("mysql is not enabled")
} else {
klog.Error("error creating mysql client", err)
}
return nil
}
membership := &DevOpsProjectMembership{} membership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...). err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
Where(db.And( Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, username), db.Eq(DevOpsProjectMembershipUsernameColumn, username),
@@ -331,9 +341,17 @@ func GetProjectUserRole(username, projectId string) (string, error) {
if username == KS_ADMIN { if username == KS_ADMIN {
return ProjectOwner, nil return ProjectOwner, nil
} }
dbconn := devops_mysql.OpenDatabase() dbconn, err := client.ClientSets().MySQL()
if err != nil {
if _, ok := err.(client.ClientSetNotEnabledError); ok {
klog.Error("mysql is not enabled")
} else {
klog.Error("error creating mysql client", err)
}
return "", err
}
membership := &DevOpsProjectMembership{} membership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...). err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
Where(db.And( Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, username), db.Eq(DevOpsProjectMembershipUsernameColumn, username),

View File

@@ -23,11 +23,11 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
log "github.com/golang/glog" "github.com/emicklei/go-restful"
"io" "io"
"io/ioutil" "io/ioutil"
"kubesphere.io/kubesphere/pkg/gojenkins" log "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins" cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@@ -40,15 +40,13 @@ const (
cronJobLayout = "Monday, January 2, 2006 15:04:05 PM" cronJobLayout = "Monday, January 2, 2006 15:04:05 PM"
) )
var jenkins *gojenkins.Jenkins
func JenkinsInit() {
jenkins = admin_jenkins.GetJenkins()
}
func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) { func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipelineUrl, projectName, pipelineName) devops, err := cs.ClientSets().Devops()
log.Infof("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipelineUrl, projectName, pipelineName)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -60,8 +58,12 @@ func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e
} }
func SearchPipelines(req *http.Request) ([]byte, error) { func SearchPipelines(req *http.Request) ([]byte, error) {
baseUrl := jenkins.Server + SearchPipelineUrl + req.URL.RawQuery devops, err := cs.ClientSets().Devops()
log.Infof("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := devops.Jenkins().Server + SearchPipelineUrl + req.URL.RawQuery
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -73,9 +75,12 @@ func SearchPipelines(req *http.Request) ([]byte, error) {
} }
func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([]byte, error) { func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+SearchPipelineRunUrl, projectName, pipelineName) devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
log.Info("Jenkins-url: " + baseUrl) baseUrl := fmt.Sprintf(devops.Jenkins().Server+SearchPipelineRunUrl, projectName, pipelineName)
res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req) res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req)
if err != nil { if err != nil {
@@ -87,8 +92,12 @@ func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([]
} }
func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchRunUrl, projectName, pipelineName, branchName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeBranchRunUrl, projectName, pipelineName, branchName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -100,7 +109,12 @@ func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, r
} }
func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
log.Info("Jenkins-url: " + baseUrl) log.Info("Jenkins-url: " + baseUrl)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
@@ -113,8 +127,12 @@ func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId st
} }
func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) { func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchStepLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchStepLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
resBody, header, err := jenkinsClient(baseUrl, req) resBody, header, err := jenkinsClient(baseUrl, req)
if err != nil { if err != nil {
@@ -126,8 +144,12 @@ func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, step
} }
func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) { func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetStepLogUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetStepLogUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
resBody, header, err := jenkinsClient(baseUrl, req) resBody, header, err := jenkinsClient(baseUrl, req)
if err != nil { if err != nil {
@@ -136,12 +158,15 @@ func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *ht
} }
return resBody, header, err return resBody, header, err
} }
func GetSCMServers(scmId string, req *http.Request) ([]byte, error) { func GetSCMServers(scmId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetSCMServersUrl, scmId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetSCMServersUrl, scmId)
req.Method = http.MethodGet req.Method = http.MethodGet
resBody, err := sendJenkinsRequest(baseUrl, req) resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -152,6 +177,11 @@ func GetSCMServers(scmId string, req *http.Request) ([]byte, error) {
} }
func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) { func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
requestBody, err := ioutil.ReadAll(req.Body) requestBody, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
@@ -169,6 +199,7 @@ func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
log.Error(err) log.Error(err)
return nil, err return nil, err
} }
var servers []*SCMServer var servers []*SCMServer
_ = json.Unmarshal(byteServers, &servers) _ = json.Unmarshal(byteServers, &servers)
for _, server := range servers { for _, server := range servers {
@@ -177,8 +208,9 @@ func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
} }
} }
req.Body = ioutil.NopCloser(bytes.NewReader(requestBody)) req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
baseUrl := fmt.Sprintf(jenkins.Server+CreateSCMServersUrl, scmId)
log.Info("Jenkins-url: " + baseUrl) baseUrl := fmt.Sprintf(devops.Jenkins().Server+CreateSCMServersUrl, scmId)
req.Method = http.MethodPost req.Method = http.MethodPost
resBody, err := sendJenkinsRequest(baseUrl, req) resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -189,8 +221,12 @@ func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
} }
func Validate(scmId string, req *http.Request) ([]byte, error) { func Validate(scmId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ValidateUrl, scmId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+ValidateUrl, scmId)
req.Method = http.MethodPut req.Method = http.MethodPut
resBody, err := sendJenkinsRequest(baseUrl, req) resBody, err := sendJenkinsRequest(baseUrl, req)
@@ -203,8 +239,12 @@ func Validate(scmId string, req *http.Request) ([]byte, error) {
} }
func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) { func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetSCMOrgUrl+req.URL.RawQuery, scmId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetSCMOrgUrl+req.URL.RawQuery, scmId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -216,8 +256,12 @@ func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) {
} }
func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error) { func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetOrgRepoUrl+req.URL.RawQuery, scmId, organizationId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetOrgRepoUrl+req.URL.RawQuery, scmId, organizationId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -229,8 +273,12 @@ func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error)
} }
func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+StopBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+StopBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
req.Method = http.MethodPut req.Method = http.MethodPut
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
@@ -243,8 +291,12 @@ func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req
} }
func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+StopPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+StopPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
req.Method = http.MethodPut req.Method = http.MethodPut
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
@@ -257,8 +309,12 @@ func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([
} }
func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ReplayBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+ReplayBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -270,8 +326,12 @@ func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, r
} }
func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ReplayPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+ReplayPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -283,8 +343,12 @@ func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request)
} }
func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchRunLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchRunLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -296,8 +360,12 @@ func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *h
} }
func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetRunLogUrl+req.URL.RawQuery, projectName, pipelineName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetRunLogUrl+req.URL.RawQuery, projectName, pipelineName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -309,8 +377,12 @@ func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]by
} }
func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) { func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -322,8 +394,12 @@ func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req
} }
func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -335,8 +411,12 @@ func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([
} }
func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) { func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchUrl, projectName, pipelineName) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeBranchUrl, projectName, pipelineName)
res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req) res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req)
if err != nil { if err != nil {
@@ -348,8 +428,12 @@ func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte,
} }
func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) { func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+CheckBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+CheckBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
newBody, err := getInputReqBody(req.Body) newBody, err := getInputReqBody(req.Body)
if err != nil { if err != nil {
@@ -367,8 +451,12 @@ func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId,
} }
func SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) { func SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+CheckPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+CheckPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
newBody, err := getInputReqBody(req.Body) newBody, err := getInputReqBody(req.Body)
if err != nil { if err != nil {
@@ -425,8 +513,12 @@ func parseBody(body io.Reader) (newReqBody io.ReadCloser) {
} }
func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, error) { func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetConsoleLogUrl+req.URL.RawQuery, projectName, pipelineName) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetConsoleLogUrl+req.URL.RawQuery, projectName, pipelineName)
resBody, err := sendJenkinsRequest(baseUrl, req) resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -438,8 +530,12 @@ func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte,
} }
func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) { func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ScanBranchUrl+req.URL.RawQuery, projectName, pipelineName) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+ScanBranchUrl+req.URL.RawQuery, projectName, pipelineName)
resBody, err := sendJenkinsRequest(baseUrl, req) resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -451,8 +547,12 @@ func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, er
} }
func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) { func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+RunBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+RunBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -464,8 +564,11 @@ func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.R
} }
func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) { func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+RunPipelineUrl+req.URL.RawQuery, projectName, pipelineName) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+RunPipelineUrl+req.URL.RawQuery, projectName, pipelineName)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -477,8 +580,12 @@ func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e
} }
func GetCrumb(req *http.Request) ([]byte, error) { func GetCrumb(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server + GetCrumbUrl) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server + GetCrumbUrl)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -490,8 +597,12 @@ func GetCrumb(req *http.Request) ([]byte, error) {
} }
func CheckScriptCompile(projectName, pipelineName string, req *http.Request) ([]byte, error) { func CheckScriptCompile(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+CheckScriptCompileUrl, projectName, pipelineName) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+CheckScriptCompileUrl, projectName, pipelineName)
resBody, err := sendJenkinsRequest(baseUrl, req) resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -503,6 +614,13 @@ func CheckScriptCompile(projectName, pipelineName string, req *http.Request) ([]
} }
func CheckCron(projectName string, req *http.Request) (*CheckCronRes, error) { func CheckCron(projectName string, req *http.Request) (*CheckCronRes, error) {
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
jenkins := devops.Jenkins()
var res = new(CheckCronRes) var res = new(CheckCronRes)
var cron = new(CronData) var cron = new(CronData)
var reader io.ReadCloser var reader io.ReadCloser
@@ -518,24 +636,24 @@ func CheckCron(projectName string, req *http.Request) (*CheckCronRes, error) {
baseUrl = fmt.Sprintf(jenkins.Server+CheckCronUrl, projectName, cron.Cron) baseUrl = fmt.Sprintf(jenkins.Server+CheckCronUrl, projectName, cron.Cron)
} }
log.Info("Jenkins-url: " + baseUrl) newUrl, err := url.Parse(baseUrl)
newurl, err := url.Parse(baseUrl)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return nil, err return nil, err
} }
newurl.RawQuery = newurl.Query().Encode() newUrl.RawQuery = newUrl.Query().Encode()
reqJenkins := &http.Request{ reqJenkins := &http.Request{
Method: http.MethodGet, Method: http.MethodGet,
URL: newurl, URL: newUrl,
Header: req.Header, Header: req.Header,
} }
client := &http.Client{Timeout: 30 * time.Second} client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(reqJenkins) resp, err := client.Do(reqJenkins)
if resp.StatusCode != http.StatusOK {
if resp != nil && resp.StatusCode != http.StatusOK {
resBody, _ := getRespBody(resp) resBody, _ := getRespBody(resp)
return &CheckCronRes{ return &CheckCronRes{
Result: "error", Result: "error",
@@ -569,6 +687,7 @@ func CheckCron(projectName string, req *http.Request) (*CheckCronRes, error) {
} }
func parseCronJobTime(msg string) (string, string, error) { func parseCronJobTime(msg string) (string, string, error) {
times := strings.Split(msg, ";") times := strings.Split(msg, ";")
lastTmp := strings.SplitN(times[0], " ", 2) lastTmp := strings.SplitN(times[0], " ", 2)
@@ -593,8 +712,12 @@ func parseCronJobTime(msg string) (string, string, error) {
} }
func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipelineRunUrl, projectName, pipelineName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipelineRunUrl, projectName, pipelineName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -606,8 +729,12 @@ func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request)
} }
func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) { func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeUrl, projectName, pipelineName, branchName) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchPipeUrl, projectName, pipelineName, branchName)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -619,8 +746,12 @@ func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.R
} }
func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) { func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -632,8 +763,12 @@ func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Requ
} }
func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]byte, error) { func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -645,8 +780,12 @@ func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId str
} }
func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]byte, error) { func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -658,8 +797,12 @@ func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Req
} }
func ToJenkinsfile(req *http.Request) ([]byte, error) { func ToJenkinsfile(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server + ToJenkinsfileUrl) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJenkinsfileUrl)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -671,8 +814,12 @@ func ToJenkinsfile(req *http.Request) ([]byte, error) {
} }
func ToJson(req *http.Request) ([]byte, error) { func ToJson(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server + ToJsonUrl) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJsonUrl)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -684,8 +831,12 @@ func ToJson(req *http.Request) ([]byte, error) {
} }
func GetNotifyCommit(req *http.Request) ([]byte, error) { func GetNotifyCommit(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprint(jenkins.Server, GetNotifyCommitUrl, req.URL.RawQuery) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprint(devops.Jenkins().Server, GetNotifyCommitUrl, req.URL.RawQuery)
req.Method = "GET" req.Method = "GET"
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
@@ -698,8 +849,12 @@ func GetNotifyCommit(req *http.Request) ([]byte, error) {
} }
func GithubWebhook(req *http.Request) ([]byte, error) { func GithubWebhook(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprint(jenkins.Server, GithubWebhookUrl, req.URL.RawQuery) devops, err := cs.ClientSets().Devops()
log.Info("Jenkins-url: " + baseUrl) if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprint(devops.Jenkins().Server, GithubWebhookUrl, req.URL.RawQuery)
res, err := sendJenkinsRequest(baseUrl, req) res, err := sendJenkinsRequest(baseUrl, req)
if err != nil { if err != nil {
@@ -711,8 +866,6 @@ func GithubWebhook(req *http.Request) ([]byte, error) {
} }
func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, req *http.Request) ([]NodesDetail, error) { func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, req *http.Request) ([]NodesDetail, error) {
getNodesUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
log.Info("getNodesUrl: " + getNodesUrl)
var wg sync.WaitGroup var wg sync.WaitGroup
var nodesDetails []NodesDetail var nodesDetails []NodesDetail
stepChan := make(chan *NodesStepsIndex, channelMaxCapacity) stepChan := make(chan *NodesStepsIndex, channelMaxCapacity)
@@ -758,8 +911,6 @@ func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, r
} }
func GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) ([]NodesDetail, error) { func GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) ([]NodesDetail, error) {
getNodesUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId)
log.Info("getNodesUrl: " + getNodesUrl)
var wg sync.WaitGroup var wg sync.WaitGroup
var nodesDetails []NodesDetail var nodesDetails []NodesDetail
stepChan := make(chan *NodesStepsIndex, channelMaxCapacity) stepChan := make(chan *NodesStepsIndex, channelMaxCapacity)

View File

@@ -24,25 +24,25 @@ import (
"kubesphere.io/kubesphere/pkg/db" "kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/gojenkins" "kubesphere.io/kubesphere/pkg/gojenkins"
"kubesphere.io/kubesphere/pkg/gojenkins/utils" "kubesphere.io/kubesphere/pkg/gojenkins/utils"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins" cs "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
"net/http" "net/http"
"strings" "strings"
) )
func CreateProjectCredential(projectId, username string, credentialRequest *JenkinsCredential) (string, error) { func CreateProjectCredential(projectId, username string, credentialRequest *JenkinsCredential) (string, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return "", restful.NewError(http.StatusServiceUnavailable, err.Error()) return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
err := checkJenkinsCredentialExists(projectId, credentialRequest.Domain, credentialRequest.Id) jenkinsClient := devops.Jenkins()
err = checkJenkinsCredentialExists(projectId, credentialRequest.Domain, credentialRequest.Id)
if err != nil { if err != nil {
glog.Errorf("%+v", err) glog.Errorf("%+v", err)
return "", err return "", err
} }
switch credentialRequest.Type { switch credentialRequest.Type {
case CredentialTypeUsernamePassword: case CredentialTypeUsernamePassword:
if credentialRequest.UsernamePasswordCredential == nil { if credentialRequest.UsernamePasswordCredential == nil {
@@ -144,12 +144,12 @@ func CreateProjectCredential(projectId, username string, credentialRequest *Jenk
} }
func UpdateProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) { func UpdateProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return "", restful.NewError(http.StatusServiceUnavailable, err.Error()) return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
jenkinsClient := devops.Jenkins()
jenkinsCredential, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain, jenkinsCredential, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
credentialId, credentialId,
projectId) projectId)
@@ -238,20 +238,25 @@ func UpdateProjectCredential(projectId, credentialId string, credentialRequest *
} }
func DeleteProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) { func DeleteProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return "", restful.NewError(http.StatusServiceUnavailable, err.Error()) return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
dbClient := devops_mysql.OpenDatabase() jenkinsClient := devops.Jenkins()
_, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
}
_, err = jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
credentialId, credentialId,
projectId) projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) glog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
id, err := jenkinsClient.DeleteCredentialInFolder(credentialRequest.Domain, credentialId, projectId) id, err := jenkinsClient.DeleteCredentialInFolder(credentialRequest.Domain, credentialId, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) glog.Errorf("%+v", err)
@@ -277,13 +282,16 @@ func DeleteProjectCredential(projectId, credentialId string, credentialRequest *
} }
func GetProjectCredential(projectId, credentialId, domain, getContent string) (*JenkinsCredential, error) { func GetProjectCredential(projectId, credentialId, domain, getContent string) (*JenkinsCredential, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins") return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
glog.Error(err) }
jenkinsClient := devops.Jenkins()
dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
dbClient := devops_mysql.OpenDatabase()
jenkinsResponse, err := jenkinsClient.GetCredentialInFolder(domain, jenkinsResponse, err := jenkinsClient.GetCredentialInFolder(domain,
credentialId, credentialId,
projectId) projectId)
@@ -352,13 +360,16 @@ func GetProjectCredential(projectId, credentialId, domain, getContent string) (*
} }
func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, error) { func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins") return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
glog.Error(err) }
jenkinsClient := devops.Jenkins()
dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
dbClient := devops_mysql.OpenDatabase()
jenkinsCredentialResponses, err := jenkinsClient.GetCredentialsInFolder(domain, projectId) jenkinsCredentialResponses, err := jenkinsClient.GetCredentialsInFolder(domain, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) glog.Errorf("%+v", err)
@@ -380,9 +391,13 @@ func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, erro
} }
func insertCredentialToDb(projectId, credentialId, domain, username string) error { func insertCredentialToDb(projectId, credentialId, domain, username string) error {
dbClient := devops_mysql.OpenDatabase() dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return err
}
projectCredential := NewProjectCredential(projectId, credentialId, domain, username) projectCredential := NewProjectCredential(projectId, credentialId, domain, username)
_, err := dbClient.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...). _, err = dbClient.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...).
Record(projectCredential).Exec() Record(projectCredential).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) glog.Errorf("%+v", err)
@@ -392,12 +407,13 @@ func insertCredentialToDb(projectId, credentialId, domain, username string) erro
} }
func checkJenkinsCredentialExists(projectId, domain, credentialId string) error { func checkJenkinsCredentialExists(projectId, domain, credentialId string) error {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return restful.NewError(http.StatusServiceUnavailable, err.Error()) return restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
jenkinsClient := devops.Jenkins()
credential, err := jenkinsClient.GetCredentialInFolder(domain, credentialId, projectId) credential, err := jenkinsClient.GetCredentialInFolder(domain, credentialId, projectId)
if credential != nil { if credential != nil {
err := fmt.Errorf("credential id [%s] has been used", credential.Id) err := fmt.Errorf("credential id [%s] has been used", credential.Id)

View File

@@ -19,14 +19,17 @@ import (
"github.com/gocraft/dbr" "github.com/gocraft/dbr"
"github.com/golang/glog" "github.com/golang/glog"
"kubesphere.io/kubesphere/pkg/db" "kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql" cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http" "net/http"
) )
func GetProject(projectId string) (*DevOpsProject, error) { func GetProject(projectId string) (*DevOpsProject, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
project := &DevOpsProject{} project := &DevOpsProject{}
err := dbconn.Select(DevOpsProjectColumns...). err = dbconn.Select(DevOpsProjectColumns...).
From(DevOpsProjectTableName). From(DevOpsProjectTableName).
Where(db.Eq(DevOpsProjectIdColumn, projectId)). Where(db.Eq(DevOpsProjectIdColumn, projectId)).
LoadOne(project) LoadOne(project)
@@ -43,7 +46,11 @@ func GetProject(projectId string) (*DevOpsProject, error) {
} }
func UpdateProject(project *DevOpsProject) (*DevOpsProject, error) { func UpdateProject(project *DevOpsProject) (*DevOpsProject, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
query := dbconn.Update(DevOpsProjectTableName) query := dbconn.Update(DevOpsProjectTableName)
if !govalidator.IsNull(project.Description) { if !govalidator.IsNull(project.Description) {
query.Set(DevOpsProjectDescriptionColumn, project.Description) query.Set(DevOpsProjectDescriptionColumn, project.Description)
@@ -65,7 +72,7 @@ func UpdateProject(project *DevOpsProject) (*DevOpsProject, error) {
} }
} }
newProject := &DevOpsProject{} newProject := &DevOpsProject{}
err := dbconn.Select(DevOpsProjectColumns...). err = dbconn.Select(DevOpsProjectColumns...).
From(DevOpsProjectTableName). From(DevOpsProjectTableName).
Where(db.Eq(DevOpsProjectIdColumn, project.ProjectId)). Where(db.Eq(DevOpsProjectIdColumn, project.ProjectId)).
LoadOne(newProject) LoadOne(newProject)

View File

@@ -14,22 +14,24 @@ package devops
import ( import (
"fmt" "fmt"
"k8s.io/klog"
"net/http" "net/http"
"github.com/emicklei/go-restful" "github.com/emicklei/go-restful"
"github.com/gocraft/dbr" "github.com/gocraft/dbr"
"github.com/golang/glog"
"kubesphere.io/kubesphere/pkg/db" "kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/gojenkins" "kubesphere.io/kubesphere/pkg/gojenkins"
"kubesphere.io/kubesphere/pkg/gojenkins/utils" "kubesphere.io/kubesphere/pkg/gojenkins/utils"
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/params" "kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins" cs "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
) )
func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) { func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
memberships := make([]*DevOpsProjectMembership, 0) memberships := make([]*DevOpsProjectMembership, 0)
var sqconditions []dbr.Builder var sqconditions []dbr.Builder
sqconditions = append(sqconditions, db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId)) sqconditions = append(sqconditions, db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId))
@@ -59,14 +61,14 @@ func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy
} else { } else {
query.Where(sqconditions[0]) query.Where(sqconditions[0])
} }
_, err := query.Load(&memberships) _, err = query.Load(&memberships)
if err != nil && err != dbr.ErrNotFound { if err != nil && err != dbr.ErrNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
count, err := query.Count() count, err := query.Count()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
result := make([]interface{}, 0) result := make([]interface{}, 0)
@@ -78,35 +80,46 @@ func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy
} }
func GetProjectMember(projectId, username string) (*DevOpsProjectMembership, error) { func GetProjectMember(projectId, username string) (*DevOpsProjectMembership, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
member := &DevOpsProjectMembership{} member := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...). err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
Where(db.And(db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId), Where(db.And(db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
db.Eq(DevOpsProjectMembershipUsernameColumn, username))). db.Eq(DevOpsProjectMembershipUsernameColumn, username))).
LoadOne(&member) LoadOne(&member)
if err != nil && err != dbr.ErrNotFound { if err != nil && err != dbr.ErrNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
if err == dbr.ErrNotFound { if err == dbr.ErrNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusNotFound, err.Error()) return nil, restful.NewError(http.StatusNotFound, err.Error())
} }
return member, nil return member, nil
} }
func AddProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) { func AddProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
jenkinsClient := admin_jenkins.Client() if err != nil {
return nil, err
}
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, err
}
jenkinsClient := devops.Jenkins()
if jenkinsClient == nil { if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins") err := fmt.Errorf("could not connect to jenkins")
glog.Error(err) klog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
membership := &DevOpsProjectMembership{} membership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...). err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
Where(db.And( Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username), db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
@@ -114,18 +127,18 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
// if user could be founded in db, user have been added to project // if user could be founded in db, user have been added to project
if err == nil { if err == nil {
err = fmt.Errorf("user [%s] have been added to project", member.Username) err = fmt.Errorf("user [%s] have been added to project", member.Username)
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error()) return nil, restful.NewError(http.StatusBadRequest, err.Error())
} }
if err != nil && err != db.ErrNotFound { if err != db.ErrNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
globalRole, err := jenkinsClient.GetGlobalRole(JenkinsAllUserRoleName) globalRole, err := jenkinsClient.GetGlobalRole(JenkinsAllUserRoleName)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
if globalRole == nil { if globalRole == nil {
@@ -133,33 +146,33 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
GlobalRead: true, GlobalRead: true,
}, true) }, true)
if err != nil { if err != nil {
glog.Errorf("failed to create jenkins global role %+v", err) klog.Errorf("failed to create jenkins global role %+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
} }
err = globalRole.AssignRole(member.Username) err = globalRole.AssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role)) projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = projectRole.AssignRole(member.Username) err = projectRole.AssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role)) pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = pipelineRole.AssignRole(member.Username) err = pipelineRole.AssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
projectMembership := NewDevOpsProjectMemberShip(member.Username, projectId, member.Role, operator) projectMembership := NewDevOpsProjectMemberShip(member.Username, projectId, member.Role, operator)
@@ -168,15 +181,15 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
Columns(DevOpsProjectMembershipColumns...). Columns(DevOpsProjectMembershipColumns...).
Record(projectMembership).Exec() Record(projectMembership).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
err = projectRole.UnAssignRole(member.Username) err = projectRole.UnAssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = pipelineRole.UnAssignRole(member.Username) err = pipelineRole.UnAssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
@@ -185,66 +198,82 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
} }
func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) { func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
jenkinsClient := admin_jenkins.Client() if err != nil {
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, err
}
jenkinsClient := devops.Jenkins()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
klog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
oldMembership := &DevOpsProjectMembership{} oldMembership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...). err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
Where(db.And( Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username), db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId), db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
)).LoadOne(oldMembership) )).LoadOne(oldMembership)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error()) return nil, restful.NewError(http.StatusBadRequest, err.Error())
} }
oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role)) oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = oldProjectRole.UnAssignRole(member.Username) err = oldProjectRole.UnAssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role)) oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = oldPipelineRole.UnAssignRole(member.Username) err = oldPipelineRole.UnAssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role)) projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = projectRole.AssignRole(member.Username) err = projectRole.AssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role)) pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = pipelineRole.AssignRole(member.Username) err = pipelineRole.AssignRole(member.Username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
_, err = dbconn.Update(DevOpsProjectMembershipTableName). _, err = dbconn.Update(DevOpsProjectMembershipTableName).
Set(DevOpsProjectMembershipRoleColumn, member.Role). Set(DevOpsProjectMembershipRoleColumn, member.Role).
Where(db.And( Where(db.And(
@@ -252,9 +281,10 @@ func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMember
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username), db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
)).Exec() )).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
responseMembership := &DevOpsProjectMembership{} responseMembership := &DevOpsProjectMembership{}
err = dbconn.Select(DevOpsProjectMembershipColumns...). err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
@@ -263,35 +293,42 @@ func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMember
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId), db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
)).LoadOne(responseMembership) )).LoadOne(responseMembership)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
return responseMembership, nil return responseMembership, nil
} }
func DeleteProjectMember(projectId, username string) (string, error) { func DeleteProjectMember(projectId, username string) (string, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
jenkinsClient := admin_jenkins.Client() if err != nil {
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return "", restful.NewError(http.StatusServiceUnavailable, err.Error()) return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
devops, err := cs.ClientSets().Devops()
if err != nil {
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
}
jenkinsClient := devops.Jenkins()
oldMembership := &DevOpsProjectMembership{} oldMembership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...). err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
Where(db.And( Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, username), db.Eq(DevOpsProjectMembershipUsernameColumn, username),
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId), db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
)).LoadOne(oldMembership) )).LoadOne(oldMembership)
if err != nil && err != db.ErrNotFound { if err != nil {
glog.Errorf("%+v", err) if err != db.ErrNotFound {
return "", restful.NewError(http.StatusInternalServerError, err.Error()) klog.Errorf("%+v", err)
} return "", restful.NewError(http.StatusInternalServerError, err.Error())
if err == db.ErrNotFound { } else if err == db.ErrNotFound {
glog.Warningf("user [%s] not found in project", username) klog.Warningf("user [%s] not found in project", username)
return username, nil return username, nil
}
} }
if oldMembership.Role == ProjectOwner { if oldMembership.Role == ProjectOwner {
count, err := dbconn.Select(DevOpsProjectMembershipProjectIdColumn). count, err := dbconn.Select(DevOpsProjectMembershipProjectIdColumn).
From(DevOpsProjectMembershipTableName). From(DevOpsProjectMembershipTableName).
@@ -299,34 +336,35 @@ func DeleteProjectMember(projectId, username string) (string, error) {
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId), db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
db.Eq(DevOpsProjectMembershipRoleColumn, ProjectOwner))).Count() db.Eq(DevOpsProjectMembershipRoleColumn, ProjectOwner))).Count()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error()) return "", restful.NewError(http.StatusInternalServerError, err.Error())
} }
if count == 1 { if count == 1 {
err = fmt.Errorf("project must has at least one admin") err = fmt.Errorf("project must has at least one admin")
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error()) return "", restful.NewError(http.StatusBadRequest, err.Error())
} }
} }
oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role)) oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = oldProjectRole.UnAssignRole(username) err = oldProjectRole.UnAssignRole(username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role)) oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = oldPipelineRole.UnAssignRole(username) err = oldPipelineRole.UnAssignRole(username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
@@ -336,7 +374,7 @@ func DeleteProjectMember(projectId, username string) (string, error) {
db.Eq(DevOpsProjectMembershipUsernameColumn, username), db.Eq(DevOpsProjectMembershipUsernameColumn, username),
)).Exec() )).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error()) return "", restful.NewError(http.StatusInternalServerError, err.Error())
} }
return username, nil return username, nil

View File

@@ -19,7 +19,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"github.com/kubesphere/sonargo/sonar" "github.com/kubesphere/sonargo/sonar"
"kubesphere.io/kubesphere/pkg/gojenkins" "kubesphere.io/kubesphere/pkg/gojenkins"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube" "kubesphere.io/kubesphere/pkg/simple/client"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -175,7 +175,7 @@ type RemoteTrigger struct {
} }
func replaceXmlVersion(config, oldVersion, targetVersion string) string { func replaceXmlVersion(config, oldVersion, targetVersion string) string {
lines := strings.Split(string(config), "\n") lines := strings.Split(config, "\n")
lines[0] = strings.Replace(lines[0], oldVersion, targetVersion, -1) lines[0] = strings.Replace(lines[0], oldVersion, targetVersion, -1)
output := strings.Join(lines, "\n") output := strings.Join(lines, "\n")
return output return output
@@ -1077,7 +1077,12 @@ func toCrontab(millis int64) string {
} }
func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) { func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
sonarClient := sonarqube.Client()
sonarClient, err := client.ClientSets().SonarQube()
if err != nil {
return nil, err
}
actions := build.GetActions() actions := build.GetActions()
sonarStatuses := make([]*SonarStatus, 0) sonarStatuses := make([]*SonarStatus, 0)
for _, action := range actions { for _, action := range actions {
@@ -1086,7 +1091,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
taskOptions := &sonargo.CeTaskOption{ taskOptions := &sonargo.CeTaskOption{
Id: action.SonarTaskId, Id: action.SonarTaskId,
} }
ceTask, _, err := sonarClient.Ce.Task(taskOptions) ceTask, _, err := sonarClient.SonarQube().Ce.Task(taskOptions)
if err != nil { if err != nil {
glog.Errorf("get sonar task error [%+v]", err) glog.Errorf("get sonar task error [%+v]", err)
continue continue
@@ -1097,7 +1102,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
AdditionalFields: SonarAdditionalFields, AdditionalFields: SonarAdditionalFields,
MetricKeys: SonarMetricKeys, MetricKeys: SonarMetricKeys,
} }
measures, _, err := sonarClient.Measures.Component(measuresComponentOption) measures, _, err := sonarClient.SonarQube().Measures.Component(measuresComponentOption)
if err != nil { if err != nil {
glog.Errorf("get sonar task error [%+v]", err) glog.Errorf("get sonar task error [%+v]", err)
continue continue
@@ -1112,7 +1117,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
S: "FILE_LINE", S: "FILE_LINE",
Facets: "severities,types", Facets: "severities,types",
} }
issuesSearch, _, err := sonarClient.Issues.Search(issuesSearchOption) issuesSearch, _, err := sonarClient.SonarQube().Issues.Search(issuesSearchOption)
sonarStatus.Issues = issuesSearch sonarStatus.Issues = issuesSearch
jenkinsAction := action jenkinsAction := action
sonarStatus.JenkinsAction = &jenkinsAction sonarStatus.JenkinsAction = &jenkinsAction

View File

@@ -16,43 +16,43 @@ package devops
import ( import (
"fmt" "fmt"
"github.com/emicklei/go-restful" "github.com/emicklei/go-restful"
"github.com/golang/glog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/gojenkins/utils" "kubesphere.io/kubesphere/pkg/gojenkins/utils"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins" cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http" "net/http"
) )
func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string, error) { func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return "", restful.NewError(http.StatusServiceUnavailable, err.Error()) return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
jenkinsClient := devops.Jenkins()
switch pipeline.Type { switch pipeline.Type {
case NoScmPipelineType: case NoScmPipelineType:
config, err := createPipelineConfigXml(pipeline.Pipeline) config, err := createPipelineConfigXml(pipeline.Pipeline)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error()) return "", restful.NewError(http.StatusInternalServerError, err.Error())
} }
job, err := jenkinsClient.GetJob(pipeline.Pipeline.Name, projectId) job, err := jenkinsClient.GetJob(pipeline.Pipeline.Name, projectId)
if job != nil { if job != nil {
err := fmt.Errorf("job name [%s] has been used", job.GetName()) err := fmt.Errorf("job name [%s] has been used", job.GetName())
glog.Warning(err.Error()) klog.Warning(err.Error())
return "", restful.NewError(http.StatusConflict, err.Error()) return "", restful.NewError(http.StatusConflict, err.Error())
} }
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound { if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
_, err = jenkinsClient.CreateJobInFolder(config, pipeline.Pipeline.Name, projectId) _, err = jenkinsClient.CreateJobInFolder(config, pipeline.Pipeline.Name, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
@@ -60,7 +60,7 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
case MultiBranchPipelineType: case MultiBranchPipelineType:
config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline) config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error()) return "", restful.NewError(http.StatusInternalServerError, err.Error())
} }
@@ -68,18 +68,18 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
job, err := jenkinsClient.GetJob(pipeline.MultiBranchPipeline.Name, projectId) job, err := jenkinsClient.GetJob(pipeline.MultiBranchPipeline.Name, projectId)
if job != nil { if job != nil {
err := fmt.Errorf("job name [%s] has been used", job.GetName()) err := fmt.Errorf("job name [%s] has been used", job.GetName())
glog.Warning(err.Error()) klog.Warning(err.Error())
return "", restful.NewError(http.StatusConflict, err.Error()) return "", restful.NewError(http.StatusConflict, err.Error())
} }
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound { if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
_, err = jenkinsClient.CreateJobInFolder(config, pipeline.MultiBranchPipeline.Name, projectId) _, err = jenkinsClient.CreateJobInFolder(config, pipeline.MultiBranchPipeline.Name, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
@@ -87,52 +87,52 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
default: default:
err := fmt.Errorf("error unsupport job type") err := fmt.Errorf("error unsupport job type")
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error()) return "", restful.NewError(http.StatusBadRequest, err.Error())
} }
} }
func DeleteProjectPipeline(projectId string, pipelineId string) (string, error) { func DeleteProjectPipeline(projectId string, pipelineId string) (string, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return "", restful.NewError(http.StatusServiceUnavailable, err.Error()) return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
_, err := jenkinsClient.DeleteJob(pipelineId, projectId) jenkinsClient := devops.Jenkins()
_, err = jenkinsClient.DeleteJob(pipelineId, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
return pipelineId, nil return pipelineId, nil
} }
func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeline) (string, error) { func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeline) (string, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return "", restful.NewError(http.StatusServiceUnavailable, err.Error()) return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
jenkinsClient := devops.Jenkins()
switch pipeline.Type { switch pipeline.Type {
case NoScmPipelineType: case NoScmPipelineType:
config, err := createPipelineConfigXml(pipeline.Pipeline) config, err := createPipelineConfigXml(pipeline.Pipeline)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error()) return "", restful.NewError(http.StatusInternalServerError, err.Error())
} }
job, err := jenkinsClient.GetJob(pipelineId, projectId) job, err := jenkinsClient.GetJob(pipelineId, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = job.UpdateConfig(config) err = job.UpdateConfig(config)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
@@ -141,7 +141,7 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline) config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error()) return "", restful.NewError(http.StatusInternalServerError, err.Error())
} }
@@ -149,13 +149,13 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
job, err := jenkinsClient.GetJob(pipelineId, projectId) job, err := jenkinsClient.GetJob(pipelineId, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = job.UpdateConfig(config) err = job.UpdateConfig(config)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
@@ -163,33 +163,33 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
default: default:
err := fmt.Errorf("error unsupport job type") err := fmt.Errorf("error unsupport job type")
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error()) return "", restful.NewError(http.StatusBadRequest, err.Error())
} }
} }
func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error) { func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
jenkinsClient := devops.Jenkins()
job, err := jenkinsClient.GetJob(pipelineId, projectId) job, err := jenkinsClient.GetJob(pipelineId, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
switch job.Raw.Class { switch job.Raw.Class {
case "org.jenkinsci.plugins.workflow.job.WorkflowJob": case "org.jenkinsci.plugins.workflow.job.WorkflowJob":
config, err := job.GetConfig() config, err := job.GetConfig()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
pipeline, err := parsePipelineConfigXml(config) pipeline, err := parsePipelineConfigXml(config)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
pipeline.Name = pipelineId pipeline.Name = pipelineId
@@ -201,12 +201,12 @@ func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error)
case "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject": case "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject":
config, err := job.GetConfig() config, err := job.GetConfig()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
pipeline, err := parseMultiBranchPipelineConfigXml(config) pipeline, err := parseMultiBranchPipelineConfigXml(config)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
pipeline.Name = pipelineId pipeline.Name = pipelineId
@@ -216,50 +216,50 @@ func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error)
}, nil }, nil
default: default:
err := fmt.Errorf("error unsupport job type") err := fmt.Errorf("error unsupport job type")
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error()) return nil, restful.NewError(http.StatusBadRequest, err.Error())
} }
} }
func GetPipelineSonar(projectId, pipelineId string) ([]*SonarStatus, error) { func GetPipelineSonar(projectId, pipelineId string) ([]*SonarStatus, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
jenkinsClient := devops.Jenkins()
job, err := jenkinsClient.GetJob(pipelineId, projectId) job, err := jenkinsClient.GetJob(pipelineId, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
build, err := job.GetLastBuild() build, err := job.GetLastBuild()
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound { if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil { } else if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, nil return nil, nil
} }
sonarStatus, err := getBuildSonarResults(build) sonarStatus, err := getBuildSonarResults(build)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error()) return nil, restful.NewError(http.StatusBadRequest, err.Error())
} }
if len(sonarStatus) == 0 { if len(sonarStatus) == 0 {
build, err := job.GetLastCompletedBuild() build, err := job.GetLastCompletedBuild()
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound { if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil { } else if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, nil return nil, nil
} }
sonarStatus, err = getBuildSonarResults(build) sonarStatus, err = getBuildSonarResults(build)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error()) return nil, restful.NewError(http.StatusBadRequest, err.Error())
} }
} }
@@ -267,43 +267,43 @@ func GetPipelineSonar(projectId, pipelineId string) ([]*SonarStatus, error) {
} }
func GetMultiBranchPipelineSonar(projectId, pipelineId, branchId string) ([]*SonarStatus, error) { func GetMultiBranchPipelineSonar(projectId, pipelineId, branchId string) ([]*SonarStatus, error) {
jenkinsClient := admin_jenkins.Client() devops, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
jenkinsClient := devops.Jenkins()
job, err := jenkinsClient.GetJob(branchId, projectId, pipelineId) job, err := jenkinsClient.GetJob(branchId, projectId, pipelineId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
build, err := job.GetLastBuild() build, err := job.GetLastBuild()
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound { if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil { } else if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, nil return nil, nil
} }
sonarStatus, err := getBuildSonarResults(build) sonarStatus, err := getBuildSonarResults(build)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error()) return nil, restful.NewError(http.StatusBadRequest, err.Error())
} }
if len(sonarStatus) == 0 { if len(sonarStatus) == 0 {
build, err := job.GetLastCompletedBuild() build, err := job.GetLastCompletedBuild()
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound { if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil { } else if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, nil return nil, nil
} }
sonarStatus, err = getBuildSonarResults(build) sonarStatus, err = getBuildSonarResults(build)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error()) return nil, restful.NewError(http.StatusBadRequest, err.Error())
} }
} }

View File

@@ -20,17 +20,17 @@ import (
func Test_NoScmPipelineConfig(t *testing.T) { func Test_NoScmPipelineConfig(t *testing.T) {
inputs := []*NoScmPipeline{ inputs := []*NoScmPipeline{
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "", Description: "",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "", Description: "",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -55,7 +55,7 @@ func Test_NoScmPipelineConfig(t *testing.T) {
func Test_NoScmPipelineConfig_Discarder(t *testing.T) { func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
inputs := []*NoScmPipeline{ inputs := []*NoScmPipeline{
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -63,7 +63,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
"3", "5", "3", "5",
}, },
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -71,7 +71,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
"3", "", "3", "",
}, },
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -79,7 +79,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
"", "21321", "", "21321",
}, },
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -106,7 +106,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
func Test_NoScmPipelineConfig_Param(t *testing.T) { func Test_NoScmPipelineConfig_Param(t *testing.T) {
inputs := []*NoScmPipeline{ inputs := []*NoScmPipeline{
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -119,7 +119,7 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
}, },
}, },
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -169,7 +169,7 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
func Test_NoScmPipelineConfig_Trigger(t *testing.T) { func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
inputs := []*NoScmPipeline{ inputs := []*NoScmPipeline{
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -178,7 +178,7 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
}, },
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -186,7 +186,7 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
Token: "abc", Token: "abc",
}, },
}, },
&NoScmPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
Jenkinsfile: "node{echo 'hello'}", Jenkinsfile: "node{echo 'hello'}",
@@ -218,28 +218,28 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
func Test_MultiBranchPipelineConfig(t *testing.T) { func Test_MultiBranchPipelineConfig(t *testing.T) {
inputs := []*MultiBranchPipeline{ inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
SourceType: "git", SourceType: "git",
GitSource: &GitSource{}, GitSource: &GitSource{},
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
SourceType: "github", SourceType: "github",
GitHubSource: &GithubSource{}, GitHubSource: &GithubSource{},
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
SourceType: "single_svn", SourceType: "single_svn",
SingleSvnSource: &SingleSvnSource{}, SingleSvnSource: &SingleSvnSource{},
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -266,7 +266,7 @@ func Test_MultiBranchPipelineConfig(t *testing.T) {
func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) { func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
inputs := []*MultiBranchPipeline{ inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -296,7 +296,7 @@ func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) { func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
inputs := []*MultiBranchPipeline{ inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -326,7 +326,7 @@ func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
func Test_MultiBranchPipelineConfig_Source(t *testing.T) { func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
inputs := []*MultiBranchPipeline{ inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -340,7 +340,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
DiscoverBranches: true, DiscoverBranches: true,
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -361,7 +361,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
}, },
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -383,7 +383,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -398,7 +398,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
Includes: "tag/*", Includes: "tag/*",
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -432,7 +432,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
func Test_MultiBranchPipelineCloneConfig(t *testing.T) { func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
inputs := []*MultiBranchPipeline{ inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -448,7 +448,7 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
}, },
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -493,7 +493,7 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
func Test_MultiBranchPipelineRegexFilter(t *testing.T) { func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
inputs := []*MultiBranchPipeline{ inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -505,7 +505,7 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
RegexFilter: ".*", RegexFilter: ".*",
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -546,7 +546,7 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) { func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
inputs := []*MultiBranchPipeline{ inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -569,7 +569,7 @@ func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
DeleteActionJobsToTrigger: "ddd", DeleteActionJobsToTrigger: "ddd",
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",
@@ -591,7 +591,7 @@ func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
CreateActionJobsToTrigger: "abc", CreateActionJobsToTrigger: "abc",
}, },
}, },
&MultiBranchPipeline{ {
Name: "", Name: "",
Description: "for test", Description: "for test",
ScriptPath: "Jenkinsfile", ScriptPath: "Jenkinsfile",

View File

@@ -13,8 +13,7 @@ import (
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1" "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"reflect" "reflect"
@@ -26,6 +25,11 @@ const (
) )
func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHeader) (*v1alpha1.S2iBinary, error) { func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHeader) (*v1alpha1.S2iBinary, error) {
s3Client, err := client.ClientSets().S3()
if err != nil {
return nil, err
}
binFile, err := fileHeader.Open() binFile, err := fileHeader.Open()
if err != nil { if err != nil {
klog.Errorf("%+v", err) klog.Errorf("%+v", err)
@@ -66,7 +70,8 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
copy.Spec.Size = bytefmt.ByteSize(uint64(fileHeader.Size)) copy.Spec.Size = bytefmt.ByteSize(uint64(fileHeader.Size))
copy.Spec.FileName = fileHeader.Filename copy.Spec.FileName = fileHeader.Filename
copy.Spec.DownloadURL = fmt.Sprintf(GetS2iBinaryURL, namespace, name, copy.Spec.FileName) copy.Spec.DownloadURL = fmt.Sprintf(GetS2iBinaryURL, namespace, name, copy.Spec.FileName)
s3session := s2is3.Session()
s3session := s3Client.Session()
if s3session == nil { if s3session == nil {
err := fmt.Errorf("could not connect to s2i s3") err := fmt.Errorf("could not connect to s2i s3")
klog.Error(err) klog.Error(err)
@@ -82,7 +87,7 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
uploader.LeavePartsOnError = true uploader.LeavePartsOnError = true
}) })
_, err = uploader.Upload(&s3manager.UploadInput{ _, err = uploader.Upload(&s3manager.UploadInput{
Bucket: s2is3.Bucket(), Bucket: s3Client.Bucket(),
Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)), Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)),
Body: binFile, Body: binFile,
ContentMD5: aws.String(md5), ContentMD5: aws.String(md5),
@@ -116,7 +121,7 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
copy.Spec.UploadTimeStamp = new(metav1.Time) copy.Spec.UploadTimeStamp = new(metav1.Time)
} }
*copy.Spec.UploadTimeStamp = metav1.Now() *copy.Spec.UploadTimeStamp = metav1.Now()
copy, err = k8s.KsClient().DevopsV1alpha1().S2iBinaries(namespace).Update(copy) copy, err = client.ClientSets().K8s().KubeSphere().DevopsV1alpha1().S2iBinaries(namespace).Update(copy)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return nil, err return nil, err
@@ -131,6 +136,11 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
} }
func DownloadS2iBinary(namespace, name, fileName string) (string, error) { func DownloadS2iBinary(namespace, name, fileName string) (string, error) {
s3Client, err := client.ClientSets().S3()
if err != nil {
return "", err
}
origin, err := informers.KsSharedInformerFactory().Devops().V1alpha1().S2iBinaries().Lister().S2iBinaries(namespace).Get(name) origin, err := informers.KsSharedInformerFactory().Devops().V1alpha1().S2iBinaries().Lister().S2iBinaries(namespace).Get(name)
if err != nil { if err != nil {
klog.Errorf("%+v", err) klog.Errorf("%+v", err)
@@ -146,14 +156,9 @@ func DownloadS2iBinary(namespace, name, fileName string) (string, error) {
klog.Error(err) klog.Error(err)
return "", err return "", err
} }
s3Client := s2is3.Client()
if s3Client == nil { req, _ := s3Client.Client().GetObjectRequest(&s3.GetObjectInput{
err := fmt.Errorf("could not get s3 client") Bucket: s3Client.Bucket(),
klog.Error(err)
return "", err
}
req, _ := s3Client.GetObjectRequest(&s3.GetObjectInput{
Bucket: s2is3.Bucket(),
Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)), Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)),
ResponseContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", origin.Spec.FileName)), ResponseContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", origin.Spec.FileName)),
}) })
@@ -169,7 +174,7 @@ func DownloadS2iBinary(namespace, name, fileName string) (string, error) {
func SetS2iBinaryStatus(s2ibin *v1alpha1.S2iBinary, status string) (*v1alpha1.S2iBinary, error) { func SetS2iBinaryStatus(s2ibin *v1alpha1.S2iBinary, status string) (*v1alpha1.S2iBinary, error) {
copy := s2ibin.DeepCopy() copy := s2ibin.DeepCopy()
copy.Status.Phase = status copy.Status.Phase = status
copy, err := k8s.KsClient().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(copy) copy, err := client.ClientSets().K8s().KubeSphere().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(copy)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return nil, err return nil, err
@@ -188,7 +193,7 @@ func SetS2iBinaryStatusWithRetry(s2ibin *v1alpha1.S2iBinary, status string) (*v1
return err return err
} }
bin.Status.Phase = status bin.Status.Phase = status
bin, err = k8s.KsClient().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(bin) bin, err = client.ClientSets().K8s().KubeSphere().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(bin)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return err return err

View File

@@ -33,7 +33,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/kubectl" "kubesphere.io/kubesphere/pkg/models/kubectl"
"kubesphere.io/kubesphere/pkg/models/resources" "kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params" "kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/k8sutil" "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"sort" "sort"
@@ -650,7 +650,7 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
found, err := clusterRoleBindingLister.Get(username) found, err := clusterRoleBindingLister.Get(username)
if apierrors.IsNotFound(err) { if apierrors.IsNotFound(err) {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding) _, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
if err != nil { if err != nil {
glog.Errorln("create cluster role binding", err) glog.Errorln("create cluster role binding", err)
return err return err
@@ -665,14 +665,14 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
deletePolicy := metav1.DeletePropagationForeground deletePolicy := metav1.DeletePropagationForeground
gracePeriodSeconds := int64(0) gracePeriodSeconds := int64(0)
deleteOption := &metav1.DeleteOptions{PropagationPolicy: &deletePolicy, GracePeriodSeconds: &gracePeriodSeconds} deleteOption := &metav1.DeleteOptions{PropagationPolicy: &deletePolicy, GracePeriodSeconds: &gracePeriodSeconds}
err = k8s.Client().RbacV1().ClusterRoleBindings().Delete(found.Name, deleteOption) err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Delete(found.Name, deleteOption)
if err != nil { if err != nil {
glog.Errorln("delete cluster role binding", err) glog.Errorln("delete cluster role binding", err)
return err return err
} }
maxRetries := 3 maxRetries := 3
for i := 0; i < maxRetries; i++ { for i := 0; i < maxRetries; i++ {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding) _, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
if err == nil { if err == nil {
return nil return nil
} }
@@ -684,7 +684,7 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
if !k8sutil.ContainsUser(found.Subjects, username) { if !k8sutil.ContainsUser(found.Subjects, username) {
found.Subjects = clusterRoleBinding.Subjects found.Subjects = clusterRoleBinding.Subjects
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(found) _, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(found)
if err != nil { if err != nil {
glog.Errorln("update cluster role binding", err) glog.Errorln("update cluster role binding", err)
return err return err

View File

@@ -23,6 +23,7 @@ import (
"fmt" "fmt"
"github.com/emicklei/go-restful" "github.com/emicklei/go-restful"
"io/ioutil" "io/ioutil"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/db" "kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
@@ -30,10 +31,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/kubeconfig" "kubesphere.io/kubesphere/pkg/models/kubeconfig"
"kubesphere.io/kubesphere/pkg/models/kubectl" "kubesphere.io/kubesphere/pkg/models/kubectl"
"kubesphere.io/kubesphere/pkg/params" "kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins" clientset "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
"kubesphere.io/kubesphere/pkg/utils/k8sutil" "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"net/http" "net/http"
@@ -45,9 +43,8 @@ import (
"github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go"
"github.com/go-ldap/ldap" "github.com/go-ldap/ldap"
"github.com/golang/glog"
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap" ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap"
@@ -81,25 +78,22 @@ func Init(email, password string, expireTime time.Duration, authRateLimit string
adminPassword = password adminPassword = password
tokenExpireTime = expireTime tokenExpireTime = expireTime
maxAuthFailed, authTimeInterval = parseAuthRateLimit(authRateLimit) maxAuthFailed, authTimeInterval = parseAuthRateLimit(authRateLimit)
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return err return err
} }
defer conn.Close()
err = checkAndCreateDefaultUser(conn) err = checkAndCreateDefaultUser(conn)
if err != nil { if err != nil {
glog.Errorln("create default users", err) klog.Errorln("create default users", err)
return err return err
} }
err = checkAndCreateDefaultGroup(conn) err = checkAndCreateDefaultGroup(conn)
if err != nil { if err != nil {
glog.Errorln("create default groups", err) klog.Errorln("create default groups", err)
return err return err
} }
@@ -117,28 +111,28 @@ func parseAuthRateLimit(authRateLimit string) (int, time.Duration) {
maxCount, _ = strconv.Atoi(groups[1]) maxCount, _ = strconv.Atoi(groups[1])
timeInterval, _ = time.ParseDuration(groups[2]) timeInterval, _ = time.ParseDuration(groups[2])
} else { } else {
glog.Warning("invalid auth rate limit", authRateLimit) klog.Warning("invalid auth rate limit", authRateLimit)
} }
return maxCount, timeInterval return maxCount, timeInterval
} }
func checkAndCreateDefaultGroup(conn ldap.Client) error { func checkAndCreateDefaultGroup(conn *ldapclient.LdapClient) error {
groupSearchRequest := ldap.NewSearchRequest( groupSearchRequest := ldap.NewSearchRequest(
ldapclient.GroupSearchBase, conn.GroupSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=posixGroup))", "(&(objectClass=posixGroup))",
nil, nil,
nil, nil,
) )
_, err := conn.Search(groupSearchRequest) _, err := conn.Ldap().Search(groupSearchRequest)
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) { if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
err = createGroupsBaseDN(conn) err = createGroupsBaseDN(conn)
if err != nil { if err != nil {
return fmt.Errorf("GroupBaseDN %s create failed: %s\n", ldapclient.GroupSearchBase, err) return fmt.Errorf("GroupBaseDN %s create failed: %s\n", conn.GroupSearchBase(), err)
} }
} }
@@ -149,22 +143,22 @@ func checkAndCreateDefaultGroup(conn ldap.Client) error {
return nil return nil
} }
func checkAndCreateDefaultUser(conn ldap.Client) error { func checkAndCreateDefaultUser(conn *ldapclient.LdapClient) error {
userSearchRequest := ldap.NewSearchRequest( userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase, conn.GroupSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=inetOrgPerson))", "(&(objectClass=inetOrgPerson))",
[]string{"uid"}, []string{"uid"},
nil, nil,
) )
result, err := conn.Search(userSearchRequest) result, err := conn.Ldap().Search(userSearchRequest)
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) { if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
err = createUserBaseDN(conn) err = createUserBaseDN(conn)
if err != nil { if err != nil {
return fmt.Errorf("UserBaseDN %s create failed: %s\n", ldapclient.UserSearchBase, err) return fmt.Errorf("UserBaseDN %s create failed: %s\n", conn.UserSearchBase(), err)
} }
} }
@@ -182,7 +176,7 @@ func checkAndCreateDefaultUser(conn ldap.Client) error {
if result == nil || !containsUser(result.Entries, user) { if result == nil || !containsUser(result.Entries, user) {
_, err = CreateUser(&user.User) _, err = CreateUser(&user.User)
if err != nil && !ldap.IsErrorWithCode(err, ldap.LDAPResultEntryAlreadyExists) { if err != nil && !ldap.IsErrorWithCode(err, ldap.LDAPResultEntryAlreadyExists) {
glog.Errorln("user init failed", user.Username, err) klog.Errorln("user init failed", user.Username, err)
return fmt.Errorf("user %s init failed: %s\n", user.Username, err) return fmt.Errorf("user %s init failed: %s\n", user.Username, err)
} }
} }
@@ -201,36 +195,33 @@ func containsUser(entries []*ldap.Entry, user initUser) bool {
return false return false
} }
func createUserBaseDN(conn ldap.Client) error { func createUserBaseDN(conn *ldapclient.LdapClient) error {
conn, err := ldapclient.Client() groupsCreateRequest := ldap.NewAddRequest(conn.UserSearchBase(), nil)
if err != nil {
return err
}
defer conn.Close()
groupsCreateRequest := ldap.NewAddRequest(ldapclient.UserSearchBase, nil)
groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"}) groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"})
groupsCreateRequest.Attribute("ou", []string{"Users"}) groupsCreateRequest.Attribute("ou", []string{"Users"})
return conn.Add(groupsCreateRequest) return conn.Ldap().Add(groupsCreateRequest)
} }
func createGroupsBaseDN(conn ldap.Client) error { func createGroupsBaseDN(conn *ldapclient.LdapClient) error {
groupsCreateRequest := ldap.NewAddRequest(ldapclient.GroupSearchBase, nil) groupsCreateRequest := ldap.NewAddRequest(conn.GroupSearchBase(), nil)
groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"}) groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"})
groupsCreateRequest.Attribute("ou", []string{"Groups"}) groupsCreateRequest.Attribute("ou", []string{"Groups"})
return conn.Add(groupsCreateRequest) return conn.Ldap().Add(groupsCreateRequest)
} }
// User login // User login
func Login(username string, password string, ip string) (*models.Token, error) { func Login(username string, password string, ip string) (*models.Token, error) {
redisClient := redis.Client() redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return nil, err
}
records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", username)).Result() records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", username)).Result()
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
@@ -238,24 +229,21 @@ func Login(username string, password string, ip string) (*models.Token, error) {
return nil, restful.NewError(http.StatusTooManyRequests, "auth rate limit exceeded") return nil, restful.NewError(http.StatusTooManyRequests, "auth rate limit exceeded")
} }
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
glog.Error(err)
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close()
userSearchRequest := ldap.NewSearchRequest( userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase, conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", username, username), fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", username, username),
[]string{"uid", "mail"}, []string{"uid", "mail"},
nil, nil,
) )
result, err := conn.Search(userSearchRequest) result, err := conn.Ldap().Search(userSearchRequest)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -270,10 +258,10 @@ func Login(username string, password string, ip string) (*models.Token, error) {
dn := result.Entries[0].DN dn := result.Entries[0].DN
// bind as the user to verify their password // bind as the user to verify their password
err = conn.Bind(dn, password) err = conn.Ldap().Bind(dn, password)
if err != nil { if err != nil {
glog.Infoln("auth failed", username, err) klog.Infoln("auth failed", username, err)
if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) { if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) {
loginFailedRecord := fmt.Sprintf("kubesphere:authfailed:%s:%d", username, time.Now().UnixNano()) loginFailedRecord := fmt.Sprintf("kubesphere:authfailed:%s:%d", username, time.Now().UnixNano())
@@ -300,14 +288,20 @@ func Login(username string, password string, ip string) (*models.Token, error) {
func loginLog(uid, ip string) { func loginLog(uid, ip string) {
if ip != "" { if ip != "" {
redisClient := redis.Client() redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return
}
redisClient.RPush(fmt.Sprintf("kubesphere:users:%s:login-log", uid), fmt.Sprintf("%s,%s", time.Now().UTC().Format("2006-01-02T15:04:05Z"), ip)) redisClient.RPush(fmt.Sprintf("kubesphere:users:%s:login-log", uid), fmt.Sprintf("%s,%s", time.Now().UTC().Format("2006-01-02T15:04:05Z"), ip))
redisClient.LTrim(fmt.Sprintf("kubesphere:users:%s:login-log", uid), -10, -1) redisClient.LTrim(fmt.Sprintf("kubesphere:users:%s:login-log", uid), -10, -1)
} }
} }
func LoginLog(username string) ([]string, error) { func LoginLog(username string) ([]string, error) {
redisClient := redis.Client() redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return nil, err
}
data, err := redisClient.LRange(fmt.Sprintf("kubesphere:users:%s:login-log", username), -10, -1).Result() data, err := redisClient.LRange(fmt.Sprintf("kubesphere:users:%s:login-log", username), -10, -1).Result()
@@ -320,13 +314,11 @@ func LoginLog(username string) ([]string, error) {
func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) { func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close()
pageControl := ldap.NewControlPaging(1000) pageControl := ldap.NewControlPaging(1000)
@@ -356,17 +348,17 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi
for { for {
userSearchRequest := ldap.NewSearchRequest( userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase, conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
filter, filter,
[]string{"uid", "mail", "description", "preferredLanguage", "createTimestamp"}, []string{"uid", "mail", "description", "preferredLanguage", "createTimestamp"},
[]ldap.Control{pageControl}, []ldap.Control{pageControl},
) )
response, err := conn.Search(userSearchRequest) response, err := conn.Ldap().Search(userSearchRequest)
if err != nil { if err != nil {
glog.Errorln("search user", err) klog.Errorln("search user", err)
return nil, err return nil, err
} }
@@ -461,26 +453,24 @@ func DescribeUser(username string) (*models.User, error) {
// Get user info only included email description & lang // Get user info only included email description & lang
func GetUserInfo(username string) (*models.User, error) { func GetUserInfo(username string) (*models.User, error) {
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close()
userSearchRequest := ldap.NewSearchRequest( userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase, conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(uid=%s))", username), fmt.Sprintf("(&(objectClass=inetOrgPerson)(uid=%s))", username),
[]string{"mail", "description", "preferredLanguage", "createTimestamp"}, []string{"mail", "description", "preferredLanguage", "createTimestamp"},
nil, nil,
) )
result, err := conn.Search(userSearchRequest) result, err := conn.Ldap().Search(userSearchRequest)
if err != nil { if err != nil {
glog.Errorln("search user", err) klog.Errorln("search user", err)
return nil, err return nil, err
} }
@@ -500,23 +490,22 @@ func GetUserInfo(username string) (*models.User, error) {
} }
func GetUserGroups(username string) ([]string, error) { func GetUserGroups(username string) ([]string, error) {
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Close() defer conn.Ldap().Close()
groupSearchRequest := ldap.NewSearchRequest( groupSearchRequest := ldap.NewSearchRequest(
ldapclient.GroupSearchBase, conn.GroupSearchBase(),
ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=posixGroup)(memberUid=%s))", username), fmt.Sprintf("(&(objectClass=posixGroup)(memberUid=%s))", username),
nil, nil,
nil, nil,
) )
result, err := conn.Search(groupSearchRequest) result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -533,7 +522,12 @@ func GetUserGroups(username string) ([]string, error) {
} }
func getLastLoginTime(username string) string { func getLastLoginTime(username string) string {
lastLogin, err := redis.Client().LRange(fmt.Sprintf("kubesphere:users:%s:login-log", username), -1, -1).Result() redis, err := clientset.ClientSets().Redis()
if err != nil {
return ""
}
lastLogin, err := redis.LRange(fmt.Sprintf("kubesphere:users:%s:login-log", username), -1, -1).Result()
if err != nil { if err != nil {
return "" return ""
@@ -547,13 +541,22 @@ func getLastLoginTime(username string) string {
} }
func setAvatar(username, avatar string) error { func setAvatar(username, avatar string) error {
_, err := redis.Client().HMSet("kubesphere:users:avatar", map[string]interface{}{"username": avatar}).Result() redis, err := clientset.ClientSets().Redis()
if err != nil {
return err
}
_, err = redis.HMSet("kubesphere:users:avatar", map[string]interface{}{"username": avatar}).Result()
return err return err
} }
func getAvatar(username string) string { func getAvatar(username string) string {
redis, err := clientset.ClientSets().Redis()
if err != nil {
return ""
}
avatar, err := redis.Client().HMGet("kubesphere:users:avatar", username).Result() avatar, err := redis.HMGet("kubesphere:users:avatar", username).Result()
if err != nil { if err != nil {
return "" return ""
@@ -570,53 +573,54 @@ func getAvatar(username string) string {
func DeleteUser(username string) error { func DeleteUser(username string) error {
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return err return err
} }
defer conn.Ldap().Close()
defer conn.Close() deleteRequest := ldap.NewDelRequest(fmt.Sprintf("uid=%s,%s", username, conn.UserSearchBase()), nil)
deleteRequest := ldap.NewDelRequest(fmt.Sprintf("uid=%s,%s", username, ldapclient.UserSearchBase), nil) if err = conn.Ldap().Del(deleteRequest); err != nil {
klog.Errorln("delete user", err)
if err = conn.Del(deleteRequest); err != nil {
glog.Errorln("delete user", err)
return err return err
} }
if err = deleteRoleBindings(username); err != nil { if err = deleteRoleBindings(username); err != nil {
glog.Errorln("delete user role bindings failed", username, err) klog.Errorln("delete user role bindings failed", username, err)
} }
if err := kubeconfig.DelKubeConfig(username); err != nil { if err := kubeconfig.DelKubeConfig(username); err != nil {
glog.Errorln("delete user kubeconfig failed", username, err) klog.Errorln("delete user kubeconfig failed", username, err)
} }
if err := kubectl.DelKubectlDeploy(username); err != nil { if err := kubectl.DelKubectlDeploy(username); err != nil {
glog.Errorln("delete user terminal pod failed", username, err) klog.Errorln("delete user terminal pod failed", username, err)
} }
devopsDb := devops_mysql.OpenDatabase() devopsDb, err := clientset.ClientSets().MySQL()
if err != nil {
jenkinsClient := admin_jenkins.Client() return err
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
dp, err := clientset.ClientSets().Devops()
if err != nil {
return err
}
jenkinsClient := dp.Jenkins()
_, err = devopsDb.DeleteFrom(devops.DevOpsProjectMembershipTableName). _, err = devopsDb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
Where(db.And( Where(db.And(
db.Eq(devops.DevOpsProjectMembershipUsernameColumn, username), db.Eq(devops.DevOpsProjectMembershipUsernameColumn, username),
)).Exec() )).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return err return err
} }
err = jenkinsClient.DeleteUserInProject(username) err = jenkinsClient.DeleteUserInProject(username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return err return err
} }
@@ -646,17 +650,17 @@ func deleteRoleBindings(username string) error {
length2 := len(roleBinding.Subjects) length2 := len(roleBinding.Subjects)
if length2 == 0 { if length2 == 0 {
deletePolicy := meta_v1.DeletePropagationForeground deletePolicy := metav1.DeletePropagationForeground
err = k8s.Client().RbacV1().RoleBindings(roleBinding.Namespace).Delete(roleBinding.Name, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy}) err = clientset.ClientSets().K8s().Kubernetes().RbacV1().RoleBindings(roleBinding.Namespace).Delete(roleBinding.Name, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
if err != nil { if err != nil {
glog.Errorf("delete role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err) klog.Errorf("delete role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err)
} }
} else if length2 < length1 { } else if length2 < length1 {
_, err = k8s.Client().RbacV1().RoleBindings(roleBinding.Namespace).Update(roleBinding) _, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().RoleBindings(roleBinding.Namespace).Update(roleBinding)
if err != nil { if err != nil {
glog.Errorf("update role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err) klog.Errorf("update role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err)
} }
} }
} }
@@ -679,19 +683,19 @@ func deleteRoleBindings(username string) error {
if length2 == 0 { if length2 == 0 {
// delete if it's not workspace role binding // delete if it's not workspace role binding
if isWorkspaceRoleBinding(clusterRoleBinding) { if isWorkspaceRoleBinding(clusterRoleBinding) {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding) _, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
} else { } else {
deletePolicy := meta_v1.DeletePropagationForeground deletePolicy := metav1.DeletePropagationForeground
err = k8s.Client().RbacV1().ClusterRoleBindings().Delete(clusterRoleBinding.Name, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy}) err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Delete(clusterRoleBinding.Name, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
} }
if err != nil { if err != nil {
glog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err) klog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err)
} }
} else if length2 < length1 { } else if length2 < length1 {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding) _, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
if err != nil { if err != nil {
glog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err) klog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err)
} }
} }
@@ -707,27 +711,26 @@ func isWorkspaceRoleBinding(clusterRoleBinding *rbacv1.ClusterRoleBinding) bool
func UserCreateCheck(check string) (exist bool, err error) { func UserCreateCheck(check string) (exist bool, err error) {
// bind root DN // bind root DN
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return false, err return false, err
} }
defer conn.Close() defer conn.Ldap().Close()
// search for the given username // search for the given username
userSearchRequest := ldap.NewSearchRequest( userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase, conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", check, check), fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", check, check),
[]string{"uid", "mail"}, []string{"uid", "mail"},
nil, nil,
) )
result, err := conn.Search(userSearchRequest) result, err := conn.Ldap().Search(userSearchRequest)
if err != nil { if err != nil {
glog.Errorln("search user", err) klog.Errorln("search user", err)
return false, err return false, err
} }
@@ -740,26 +743,24 @@ func CreateUser(user *models.User) (*models.User, error) {
user.Password = strings.TrimSpace(user.Password) user.Password = strings.TrimSpace(user.Password)
user.Description = strings.TrimSpace(user.Description) user.Description = strings.TrimSpace(user.Description)
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close()
userSearchRequest := ldap.NewSearchRequest( userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase, conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", user.Username, user.Email), fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", user.Username, user.Email),
[]string{"uid", "mail"}, []string{"uid", "mail"},
nil, nil,
) )
result, err := conn.Search(userSearchRequest) result, err := conn.Ldap().Search(userSearchRequest)
if err != nil { if err != nil {
glog.Errorln("search user", err) klog.Errorln("search user", err)
return nil, err return nil, err
} }
@@ -770,13 +771,13 @@ func CreateUser(user *models.User) (*models.User, error) {
maxUid, err := getMaxUid(conn) maxUid, err := getMaxUid(conn)
if err != nil { if err != nil {
glog.Errorln("get max uid", err) klog.Errorln("get max uid", err)
return nil, err return nil, err
} }
maxUid += 1 maxUid += 1
userCreateRequest := ldap.NewAddRequest(fmt.Sprintf("uid=%s,%s", user.Username, ldapclient.UserSearchBase), nil) userCreateRequest := ldap.NewAddRequest(fmt.Sprintf("uid=%s,%s", user.Username, conn.UserSearchBase()), nil)
userCreateRequest.Attribute("objectClass", []string{"inetOrgPerson", "posixAccount", "top"}) userCreateRequest.Attribute("objectClass", []string{"inetOrgPerson", "posixAccount", "top"})
userCreateRequest.Attribute("cn", []string{user.Username}) // RFC4519: common name(s) for which the entity is known by userCreateRequest.Attribute("cn", []string{user.Username}) // RFC4519: common name(s) for which the entity is known by
userCreateRequest.Attribute("sn", []string{" "}) // RFC2256: last (family) name(s) for which the entity is known by userCreateRequest.Attribute("sn", []string{" "}) // RFC2256: last (family) name(s) for which the entity is known by
@@ -794,14 +795,14 @@ func CreateUser(user *models.User) (*models.User, error) {
} }
if err := kubeconfig.CreateKubeConfig(user.Username); err != nil { if err := kubeconfig.CreateKubeConfig(user.Username); err != nil {
glog.Errorln("create user kubeconfig failed", user.Username, err) klog.Errorln("create user kubeconfig failed", user.Username, err)
return nil, err return nil, err
} }
err = conn.Add(userCreateRequest) err = conn.Ldap().Add(userCreateRequest)
if err != nil { if err != nil {
glog.Errorln("create user", err) klog.Errorln("create user", err)
return nil, err return nil, err
} }
@@ -813,7 +814,7 @@ func CreateUser(user *models.User) (*models.User, error) {
err := CreateClusterRoleBinding(user.Username, user.ClusterRole) err := CreateClusterRoleBinding(user.Username, user.ClusterRole)
if err != nil { if err != nil {
glog.Errorln("create cluster role binding filed", err) klog.Errorln("create cluster role binding filed", err)
return nil, err return nil, err
} }
} }
@@ -821,14 +822,14 @@ func CreateUser(user *models.User) (*models.User, error) {
return DescribeUser(user.Username) return DescribeUser(user.Username)
} }
func getMaxUid(conn ldap.Client) (int, error) { func getMaxUid(conn *ldapclient.LdapClient) (int, error) {
userSearchRequest := ldap.NewSearchRequest(ldapclient.UserSearchBase, userSearchRequest := ldap.NewSearchRequest(conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=inetOrgPerson))", "(&(objectClass=inetOrgPerson))",
[]string{"uidNumber"}, []string{"uidNumber"},
nil) nil)
result, err := conn.Search(userSearchRequest) result, err := conn.Ldap().Search(userSearchRequest)
if err != nil { if err != nil {
return 0, err return 0, err
@@ -850,15 +851,15 @@ func getMaxUid(conn ldap.Client) (int, error) {
return maxUid, nil return maxUid, nil
} }
func getMaxGid(conn ldap.Client) (int, error) { func getMaxGid(conn *ldapclient.LdapClient) (int, error) {
groupSearchRequest := ldap.NewSearchRequest(ldapclient.GroupSearchBase, groupSearchRequest := ldap.NewSearchRequest(conn.GroupSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=posixGroup))", "(&(objectClass=posixGroup))",
[]string{"gidNumber"}, []string{"gidNumber"},
nil) nil)
result, err := conn.Search(groupSearchRequest) result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil { if err != nil {
return 0, err return 0, err
@@ -882,38 +883,36 @@ func getMaxGid(conn ldap.Client) (int, error) {
func UpdateUser(user *models.User) (*models.User, error) { func UpdateUser(user *models.User) (*models.User, error) {
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close() dn := fmt.Sprintf("uid=%s,%s", user.Username, conn.UserSearchBase())
dn := fmt.Sprintf("uid=%s,%s", user.Username, ldapclient.UserSearchBase)
userModifyRequest := ldap.NewModifyRequest(dn, nil) userModifyRequest := ldap.NewModifyRequest(dn, nil)
if user.Email != "" { if user.Email != "" {
userSearchRequest := ldap.NewSearchRequest( userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase, conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(mail=%s))", user.Email), fmt.Sprintf("(&(objectClass=inetOrgPerson)(mail=%s))", user.Email),
[]string{"uid", "mail"}, []string{"uid", "mail"},
nil, nil,
) )
result, err := conn.Search(userSearchRequest) result, err := conn.Ldap().Search(userSearchRequest)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
if len(result.Entries) > 1 { if len(result.Entries) > 1 {
err = ldap.NewError(ldap.ErrorDebugging, fmt.Errorf("email is duplicated: %s", user.Email)) err = ldap.NewError(ldap.ErrorDebugging, fmt.Errorf("email is duplicated: %s", user.Email))
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
if len(result.Entries) == 1 && result.Entries[0].GetAttributeValue("uid") != user.Username { if len(result.Entries) == 1 && result.Entries[0].GetAttributeValue("uid") != user.Username {
err = ldap.NewError(ldap.LDAPResultEntryAlreadyExists, fmt.Errorf("email is duplicated: %s", user.Email)) err = ldap.NewError(ldap.LDAPResultEntryAlreadyExists, fmt.Errorf("email is duplicated: %s", user.Email))
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
userModifyRequest.Replace("mail", []string{user.Email}) userModifyRequest.Replace("mail", []string{user.Email})
@@ -935,27 +934,30 @@ func UpdateUser(user *models.User) (*models.User, error) {
} }
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
err = conn.Modify(userModifyRequest) err = conn.Ldap().Modify(userModifyRequest)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
err = CreateClusterRoleBinding(user.Username, user.ClusterRole) err = CreateClusterRoleBinding(user.Username, user.ClusterRole)
if err != nil { if err != nil {
glog.Errorln("create cluster role binding filed", err) klog.Errorln("create cluster role binding filed", err)
return nil, err return nil, err
} }
// clear auth failed record // clear auth failed record
if user.Password != "" { if user.Password != "" {
redisClient := redis.Client() redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return nil, err
}
records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", user.Username)).Result() records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", user.Username)).Result()
@@ -969,19 +971,19 @@ func UpdateUser(user *models.User) (*models.User, error) {
func DeleteGroup(path string) error { func DeleteGroup(path string) error {
// bind root DN // bind root DN
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return err return err
} }
defer conn.Close() defer conn.Ldap().Close()
searchBase, cn := splitPath(path) searchBase, cn := splitPath(path)
groupDeleteRequest := ldap.NewDelRequest(fmt.Sprintf("cn=%s,%s", cn, searchBase), nil) groupDeleteRequest := ldap.NewDelRequest(fmt.Sprintf("cn=%s,%s", cn, searchBase), nil)
err = conn.Del(groupDeleteRequest) err = conn.Ldap().Del(groupDeleteRequest)
if err != nil { if err != nil {
glog.Errorln("delete user group", err) klog.Errorln("delete user group", err)
return err return err
} }
@@ -990,18 +992,16 @@ func DeleteGroup(path string) error {
func CreateGroup(group *models.Group) (*models.Group, error) { func CreateGroup(group *models.Group) (*models.Group, error) {
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close()
maxGid, err := getMaxGid(conn) maxGid, err := getMaxGid(conn)
if err != nil { if err != nil {
glog.Errorln("get max gid", err) klog.Errorln("get max gid", err)
return nil, err return nil, err
} }
@@ -1026,10 +1026,10 @@ func CreateGroup(group *models.Group) (*models.Group, error) {
groupCreateRequest.Attribute("memberUid", group.Members) groupCreateRequest.Attribute("memberUid", group.Members)
} }
err = conn.Add(groupCreateRequest) err = conn.Ldap().Add(groupCreateRequest)
if err != nil { if err != nil {
glog.Errorln("create group", err) klog.Errorln("create group", err)
return nil, err return nil, err
} }
@@ -1041,11 +1041,11 @@ func CreateGroup(group *models.Group) (*models.Group, error) {
func UpdateGroup(group *models.Group) (*models.Group, error) { func UpdateGroup(group *models.Group) (*models.Group, error) {
// bind root DN // bind root DN
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Close() defer conn.Ldap().Close()
old, err := DescribeGroup(group.Path) old, err := DescribeGroup(group.Path)
@@ -1073,10 +1073,10 @@ func UpdateGroup(group *models.Group) (*models.Group, error) {
groupUpdateRequest.Replace("memberUid", group.Members) groupUpdateRequest.Replace("memberUid", group.Members)
} }
err = conn.Modify(groupUpdateRequest) err = conn.Ldap().Modify(groupUpdateRequest)
if err != nil { if err != nil {
glog.Errorln("update group", err) klog.Errorln("update group", err)
return nil, err return nil, err
} }
@@ -1086,17 +1086,15 @@ func UpdateGroup(group *models.Group) (*models.Group, error) {
func ChildList(path string) ([]models.Group, error) { func ChildList(path string) ([]models.Group, error) {
// bind root DN // bind root DN
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close()
var groupSearchRequest *ldap.SearchRequest var groupSearchRequest *ldap.SearchRequest
if path == "" { if path == "" {
groupSearchRequest = ldap.NewSearchRequest(ldapclient.GroupSearchBase, groupSearchRequest = ldap.NewSearchRequest(conn.GroupSearchBase(),
ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=posixGroup))", "(&(objectClass=posixGroup))",
[]string{"cn", "gidNumber", "memberUid", "description"}, []string{"cn", "gidNumber", "memberUid", "description"},
@@ -1110,7 +1108,7 @@ func ChildList(path string) ([]models.Group, error) {
nil) nil)
} }
result, err := conn.Search(groupSearchRequest) result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1133,7 +1131,7 @@ func ChildList(path string) ([]models.Group, error) {
[]string{""}, []string{""},
nil) nil)
result, err = conn.Search(childSearchRequest) result, err = conn.Ldap().Search(childSearchRequest)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1158,13 +1156,11 @@ func DescribeGroup(path string) (*models.Group, error) {
searchBase, cn := splitPath(path) searchBase, cn := splitPath(path)
conn, err := ldapclient.Client() conn, err := clientset.ClientSets().Ldap()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer conn.Ldap().Close()
defer conn.Close()
groupSearchRequest := ldap.NewSearchRequest(searchBase, groupSearchRequest := ldap.NewSearchRequest(searchBase,
ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false, ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false,
@@ -1172,10 +1168,10 @@ func DescribeGroup(path string) (*models.Group, error) {
[]string{"cn", "gidNumber", "memberUid", "description"}, []string{"cn", "gidNumber", "memberUid", "description"},
nil) nil)
result, err := conn.Search(groupSearchRequest) result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil { if err != nil {
glog.Errorln("search group", err) klog.Errorln("search group", err)
return nil, err return nil, err
} }

View File

@@ -19,7 +19,7 @@ package iam
import ( import (
"fmt" "fmt"
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap" "kubesphere.io/kubesphere/pkg/simple/client"
"regexp" "regexp"
"strings" "strings"
) )
@@ -44,6 +44,10 @@ func convertDNToPath(dn string) string {
} }
func splitPath(path string) (searchBase string, cn string) { func splitPath(path string) (searchBase string, cn string) {
ldapClient, err := client.ClientSets().Ldap()
if err != nil {
return "", ""
}
paths := strings.Split(path, ":") paths := strings.Split(path, ":")
length := len(paths) length := len(paths)
@@ -60,12 +64,12 @@ func splitPath(path string) (searchBase string, cn string) {
basePath[i], basePath[j] = basePath[j], basePath[i] basePath[i], basePath[j] = basePath[j], basePath[i]
} }
searchBase = fmt.Sprintf("%s,%s", strings.Join(basePath, ","), ldapclient.GroupSearchBase) searchBase = fmt.Sprintf("%s,%s", strings.Join(basePath, ","), ldapClient.GroupSearchBase())
} else if length == 2 { } else if length == 2 {
searchBase = fmt.Sprintf("cn=%s,%s", paths[0], ldapclient.GroupSearchBase) searchBase = fmt.Sprintf("cn=%s,%s", paths[0], ldapClient.GroupSearchBase())
cn = paths[1] cn = paths[1]
} else { } else {
searchBase = ldapclient.GroupSearchBase searchBase = ldapClient.GroupSearchBase()
if paths[0] == "" { if paths[0] == "" {
cn = "*" cn = "*"
} else { } else {

View File

@@ -29,7 +29,7 @@ import (
"fmt" "fmt"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"io/ioutil" "io/ioutil"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"math/big" "math/big"
rd "math/rand" rd "math/rand"
"time" "time"
@@ -217,7 +217,7 @@ func createKubeConfig(username string) (string, error) {
return "", err return "", err
} }
base64ServerCa := base64.StdEncoding.EncodeToString(serverCa) base64ServerCa := base64.StdEncoding.EncodeToString(serverCa)
tmpClusterInfo := clusterInfo{CertificateAuthorityData: base64ServerCa, Server: k8s.KubeConfig.Host} tmpClusterInfo := clusterInfo{CertificateAuthorityData: base64ServerCa, Server: client.ClientSets().K8s().Master()}
tmpCluster := cluster{Cluster: tmpClusterInfo, Name: clusterName} tmpCluster := cluster{Cluster: tmpClusterInfo, Name: clusterName}
tmpKubeConfig.Clusters = append(tmpKubeConfig.Clusters, tmpCluster) tmpKubeConfig.Clusters = append(tmpKubeConfig.Clusters, tmpCluster)
@@ -244,7 +244,7 @@ func createKubeConfig(username string) (string, error) {
} }
func CreateKubeConfig(username string) error { func CreateKubeConfig(username string) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
configName := fmt.Sprintf("kubeconfig-%s", username) configName := fmt.Sprintf("kubeconfig-%s", username)
_, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{}) _, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
@@ -255,7 +255,7 @@ func CreateKubeConfig(username string) error {
return err return err
} }
data := map[string]string{"config": string(config)} data := map[string]string{"config": config}
configMap := v1.ConfigMap{TypeMeta: metaV1.TypeMeta{Kind: "Configmap", APIVersion: "v1"}, ObjectMeta: metaV1.ObjectMeta{Name: configName}, Data: data} configMap := v1.ConfigMap{TypeMeta: metaV1.TypeMeta{Kind: "Configmap", APIVersion: "v1"}, ObjectMeta: metaV1.ObjectMeta{Name: configName}, Data: data}
_, err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(&configMap) _, err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(&configMap)
if err != nil && !errors.IsAlreadyExists(err) { if err != nil && !errors.IsAlreadyExists(err) {
@@ -269,7 +269,7 @@ func CreateKubeConfig(username string) error {
} }
func GetKubeConfig(username string) (string, error) { func GetKubeConfig(username string) (string, error) {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
configName := fmt.Sprintf("kubeconfig-%s", username) configName := fmt.Sprintf("kubeconfig-%s", username)
configMap, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{}) configMap, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
if err != nil { if err != nil {
@@ -284,10 +284,7 @@ func GetKubeConfig(username string) (string, error) {
glog.Error(err) glog.Error(err)
return "", err return "", err
} }
masterURL := k8s.KubeConfig.Host masterURL := client.ClientSets().K8s().Master()
if host := k8s.MasterURL; host != "" {
masterURL = host
}
for i, cluster := range kubeConfig.Clusters { for i, cluster := range kubeConfig.Clusters {
cluster.Cluster.Server = masterURL cluster.Cluster.Server = masterURL
kubeConfig.Clusters[i] = cluster kubeConfig.Clusters[i] = cluster
@@ -301,7 +298,7 @@ func GetKubeConfig(username string) (string, error) {
} }
func DelKubeConfig(username string) error { func DelKubeConfig(username string) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
configName := fmt.Sprintf("kubeconfig-%s", username) configName := fmt.Sprintf("kubeconfig-%s", username)
_, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{}) _, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
if errors.IsNotFound(err) { if errors.IsNotFound(err) {

View File

@@ -21,7 +21,7 @@ package kubectl
import ( import (
"fmt" "fmt"
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"math/rand" "math/rand"
"os" "os"
@@ -49,7 +49,7 @@ func init() {
} }
func GetKubectlPod(username string) (models.PodInfo, error) { func GetKubectlPod(username string) (models.PodInfo, error) {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
deployName := fmt.Sprintf("kubectl-%s", username) deployName := fmt.Sprintf("kubectl-%s", username)
deploy, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{}) deploy, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
if err != nil { if err != nil {
@@ -97,7 +97,7 @@ func selectCorrectPod(namespace string, pods []v1.Pod) (kubectlPod v1.Pod, err e
} }
func CreateKubectlDeploy(username string) error { func CreateKubectlDeploy(username string) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
deployName := fmt.Sprintf("kubectl-%s", username) deployName := fmt.Sprintf("kubectl-%s", username)
configName := fmt.Sprintf("kubeconfig-%s", username) configName := fmt.Sprintf("kubeconfig-%s", username)
_, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{}) _, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
@@ -140,7 +140,7 @@ func CreateKubectlDeploy(username string) error {
} }
func DelKubectlDeploy(username string) error { func DelKubectlDeploy(username string) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
deployName := fmt.Sprintf("kubectl-%s", username) deployName := fmt.Sprintf("kubectl-%s", username)
_, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{}) _, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
if errors.IsNotFound(err) { if errors.IsNotFound(err) {

View File

@@ -20,6 +20,7 @@ package metrics
import ( import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere" "kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
"net/url" "net/url"
@@ -36,7 +37,7 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"kubesphere.io/kubesphere/pkg/models/workspaces" "kubesphere.io/kubesphere/pkg/models/workspaces"
client "kubesphere.io/kubesphere/pkg/simple/client/prometheus" cs "kubesphere.io/kubesphere/pkg/simple/client"
) )
var jsonIter = jsoniter.ConfigCompatibleWithStandardLibrary var jsonIter = jsoniter.ConfigCompatibleWithStandardLibrary
@@ -136,10 +137,15 @@ func getAllWorkspaceNames(formatedMetric *FormatedMetric) map[string]int {
func getAllWorkspaces() map[string]int { func getAllWorkspaces() map[string]int {
client, err := cs.ClientSets().Prometheus()
if err != nil {
return nil
}
paramValues := make(url.Values) paramValues := make(url.Values)
paramValues.Set("query", WorkspaceNamespaceLabelRule) paramValues.Set("query", WorkspaceNamespaceLabelRule)
params := paramValues.Encode() params := paramValues.Encode()
res := client.SendMonitoringRequest(client.PrometheusEndpoint, client.DefaultQueryType, params) res := client.SendSecondaryMonitoringRequest(DefaultQueryType, params)
metric := ReformatJson(res, "", map[string]string{"workspace": "workspace"}) metric := ReformatJson(res, "", map[string]string{"workspace": "workspace"})
@@ -234,7 +240,13 @@ func unifyMetricHistoryTimeRange(fmtMetrics *FormatedMetric) {
} }
} }
func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string, bool) { func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string, bool) {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return "", "", false
}
nsName := monitoringRequest.NsName nsName := monitoringRequest.NsName
wlName := monitoringRequest.WorkloadName wlName := monitoringRequest.WorkloadName
@@ -244,7 +256,7 @@ func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.Monitor
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
params := makeRequestParamString(rule, paramValues) params := makeRequestParamString(rule, paramValues)
res := client.SendMonitoringRequest(client.PrometheusEndpoint, client.DefaultQueryType, params) res := client.SendMonitoringRequest(DefaultQueryType, params)
podNamesFilter := getPodNameRegexInWorkload(res, podsFilter) podNamesFilter := getPodNameRegexInWorkload(res, podsFilter)
@@ -255,7 +267,7 @@ func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.Monitor
return queryType, params, rule == "" return queryType, params, rule == ""
} }
func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) { func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
@@ -266,7 +278,7 @@ func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRe
return queryType, params return queryType, params
} }
func AssemblePodMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string, bool) { func AssemblePodMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string, bool) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
@@ -276,7 +288,7 @@ func AssemblePodMetricRequestInfo(monitoringRequest *client.MonitoringRequestPar
return queryType, params, rule == "" return queryType, params, rule == ""
} }
func AssemblePVCMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string, bool) { func AssemblePVCMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string, bool) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
@@ -318,14 +330,20 @@ func AddNodeAddressMetric(nodeMetric *FormatedMetric, nodeAddress *map[string][]
} }
} }
func MonitorContainer(monitoringRequest *client.MonitoringRequestParams, metricName string) *FormatedMetric { func MonitorContainer(monitoringRequest *MonitoringRequestParams, metricName string) *FormatedMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
queryType, params := AssembleContainerMetricRequestInfo(monitoringRequest, metricName) queryType, params := AssembleContainerMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
res := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelContainerName: ""}) res := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelContainerName: ""})
return res return res
} }
func AssembleContainerMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) { func AssembleContainerMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
@@ -335,7 +353,7 @@ func AssembleContainerMetricRequestInfo(monitoringRequest *client.MonitoringRequ
return queryType, params return queryType, params
} }
func AssembleNamespaceMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) { func AssembleNamespaceMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
@@ -345,7 +363,7 @@ func AssembleNamespaceMetricRequestInfo(monitoringRequest *client.MonitoringRequ
return queryType, params return queryType, params
} }
func AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest *client.MonitoringRequestParams, namespace string, metricName string) (string, string) { func AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest *MonitoringRequestParams, namespace string, metricName string) (string, string) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
@@ -356,7 +374,7 @@ func AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest *client.Mon
return queryType, params return queryType, params
} }
func AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, namespaceList []string, workspace string, metricName string) (string, string) { func AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest *MonitoringRequestParams, namespaceList []string, workspace string, metricName string) (string, string) {
nsFilter := "^(" + strings.Join(namespaceList, "|") + ")$" nsFilter := "^(" + strings.Join(namespaceList, "|") + ")$"
@@ -368,7 +386,7 @@ func AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest *client.Monito
return queryType, params return queryType, params
} }
func AssembleAllWorkspaceMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, namespaceList []string, metricName string) (string, string) { func AssembleAllWorkspaceMetricRequestInfo(monitoringRequest *MonitoringRequestParams, namespaceList []string, metricName string) (string, string) {
var nsFilter = "^()$" var nsFilter = "^()$"
if namespaceList != nil { if namespaceList != nil {
@@ -418,7 +436,7 @@ func filterNamespace(nsFilter string, namespaceList []string) []string {
return newNSlist return newNSlist
} }
func MonitorAllWorkspaces(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func MonitorAllWorkspaces(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if strings.Trim(metricsFilter, " ") == "" { if strings.Trim(metricsFilter, " ") == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -479,7 +497,13 @@ func MonitorAllWorkspaces(monitoringRequest *client.MonitoringRequestParams) *Fo
} }
} }
func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, ws string, filterMetricsName []string, wgAll *sync.WaitGroup, wsAllch chan *[]FormatedMetric) { func collectWorkspaceMetric(monitoringRequest *MonitoringRequestParams, ws string, filterMetricsName []string, wgAll *sync.WaitGroup, wsAllch chan *[]FormatedMetric) {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return
}
defer wgAll.Done() defer wgAll.Done()
var wg sync.WaitGroup var wg sync.WaitGroup
var ch = make(chan *FormatedMetric, ChannelMaxCapacity) var ch = make(chan *FormatedMetric, ChannelMaxCapacity)
@@ -494,7 +518,7 @@ func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, w
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest, namespaceArray, ws, metricName) queryType, params := AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest, namespaceArray, ws, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: ws}) ch <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: ws})
wg.Done() wg.Done()
}(metricName) }(metricName)
@@ -521,7 +545,12 @@ func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, w
wsAllch <- &metricsArray wsAllch <- &metricsArray
} }
func GetClusterLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetClusterLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -536,7 +565,7 @@ func GetClusterLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *
wg.Add(1) wg.Add(1)
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleClusterMetricRequestInfo(monitoringRequest, metricName) queryType, params := AssembleClusterMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelCluster: "local"}) ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelCluster: "local"})
wg.Done() wg.Done()
}(metricName) }(metricName)
@@ -560,7 +589,12 @@ func GetClusterLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *
} }
} }
func GetNodeLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetNodeLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -575,7 +609,7 @@ func GetNodeLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *For
wg.Add(1) wg.Add(1)
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleNodeMetricRequestInfo(monitoringRequest, metricName) queryType, params := AssembleNodeMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelNode: ""}) ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelNode: ""})
wg.Done() wg.Done()
}(metricName) }(metricName)
@@ -599,7 +633,13 @@ func GetNodeLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *For
} }
} }
func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetWorkspaceLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -638,7 +678,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
go func(metricName string, namespace string) { go func(metricName string, namespace string) {
queryType, params := AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest, namespace, metricName) queryType, params := AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest, namespace, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
chForOneMetric <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: namespace}) chForOneMetric <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: namespace})
wgForOneMetric.Done() wgForOneMetric.Done()
}(metricName, ns) }(metricName, ns)
@@ -682,7 +722,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1) wg.Add(1)
go func(metricName string, workspace string) { go func(metricName string, workspace string) {
queryType, params := AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest, namespaceArray, workspace, metricName) queryType, params := AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest, namespaceArray, workspace, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: workspace}) ch <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: workspace})
wg.Done() wg.Done()
}(metricName, workspace) }(metricName, workspace)
@@ -699,7 +739,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleAllWorkspaceMetricRequestInfo(monitoringRequest, nil, metricName) queryType, params := AssembleAllWorkspaceMetricRequestInfo(monitoringRequest, nil, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelWorkspace: "workspaces"}) ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelWorkspace: "workspaces"})
wg.Done() wg.Done()
@@ -725,7 +765,13 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
} }
} }
func GetNamespaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetNamespaceLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -741,7 +787,7 @@ func GetNamespaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleNamespaceMetricRequestInfo(monitoringRequest, metricName) queryType, params := AssembleNamespaceMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
rawResult := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelNamespace: ""}) rawResult := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelNamespace: ""})
ch <- rawResult ch <- rawResult
@@ -768,7 +814,13 @@ func GetNamespaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
} }
} }
func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetWorkloadLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -784,7 +836,7 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1) wg.Add(1)
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleAllWorkloadMetricRequestInfo(monitoringRequest, metricName) queryType, params := AssembleAllWorkloadMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
reformattedResult := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelWorkload: ""}) reformattedResult := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelWorkload: ""})
// no need to append a null result // no need to append a null result
ch <- reformattedResult ch <- reformattedResult
@@ -801,7 +853,7 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
metricName = strings.TrimLeft(metricName, "workload_") metricName = strings.TrimLeft(metricName, "workload_")
queryType, params, nullRule := AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest, metricName) queryType, params, nullRule := AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest, metricName)
if !nullRule { if !nullRule {
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
fmtMetrics := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""}) fmtMetrics := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""})
unifyMetricHistoryTimeRange(fmtMetrics) unifyMetricHistoryTimeRange(fmtMetrics)
ch <- fmtMetrics ch <- fmtMetrics
@@ -829,7 +881,13 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
} }
} }
func GetPodLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetPodLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -845,7 +903,7 @@ func GetPodLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
go func(metricName string) { go func(metricName string) {
queryType, params, nullRule := AssemblePodMetricRequestInfo(monitoringRequest, metricName) queryType, params, nullRule := AssemblePodMetricRequestInfo(monitoringRequest, metricName)
if !nullRule { if !nullRule {
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""}) ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""})
} else { } else {
ch <- nil ch <- nil
@@ -872,7 +930,13 @@ func GetPodLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
} }
} }
func GetContainerLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetContainerLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -887,7 +951,7 @@ func GetContainerLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1) wg.Add(1)
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleContainerMetricRequestInfo(monitoringRequest, metricName) queryType, params := AssembleContainerMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelContainerName: ""}) ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelContainerName: ""})
wg.Done() wg.Done()
}(metricName) }(metricName)
@@ -911,7 +975,13 @@ func GetContainerLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
} }
} }
func GetPVCLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetPVCLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -927,7 +997,7 @@ func GetPVCLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
go func(metricName string) { go func(metricName string) {
queryType, params, nullRule := AssemblePVCMetricRequestInfo(monitoringRequest, metricName) queryType, params, nullRule := AssemblePVCMetricRequestInfo(monitoringRequest, metricName)
if !nullRule { if !nullRule {
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPVC: ""}) ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPVC: ""})
} else { } else {
ch <- nil ch <- nil
@@ -954,7 +1024,13 @@ func GetPVCLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
} }
} }
func GetComponentLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric { func GetComponentLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" { if metricsFilter == "" {
metricsFilter = ".*" metricsFilter = ".*"
@@ -969,7 +1045,7 @@ func GetComponentLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1) wg.Add(1)
go func(metricName string) { go func(metricName string) {
queryType, params := AssembleComponentRequestInfo(monitoringRequest, metricName) queryType, params := AssembleComponentRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.SecondaryPrometheusEndpoint, queryType, params) metricsStr := client.SendMonitoringRequest(queryType, params)
formattedJson := ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: monitoringRequest.ComponentName}) formattedJson := ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: monitoringRequest.ComponentName})
if metricName == EtcdServerList { if metricName == EtcdServerList {
@@ -1175,7 +1251,7 @@ func getSpecificMetricItem(timestamp int64, metricName string, resource string,
return &nsMetrics return &nsMetrics
} }
func AssembleClusterMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) { func AssembleClusterMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
rule := MakeClusterRule(metricName) rule := MakeClusterRule(metricName)
@@ -1184,7 +1260,7 @@ func AssembleClusterMetricRequestInfo(monitoringRequest *client.MonitoringReques
return queryType, params return queryType, params
} }
func AssembleNodeMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) { func AssembleNodeMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
rule := MakeNodeRule(monitoringRequest.NodeId, monitoringRequest.ResourcesFilter, metricName) rule := MakeNodeRule(monitoringRequest.NodeId, monitoringRequest.ResourcesFilter, metricName)
@@ -1193,7 +1269,7 @@ func AssembleNodeMetricRequestInfo(monitoringRequest *client.MonitoringRequestPa
return queryType, params return queryType, params
} }
func AssembleComponentRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) { func AssembleComponentRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params paramValues := monitoringRequest.Params
rule := MakeComponentRule(metricName) rule := MakeComponentRule(metricName)

View File

@@ -22,8 +22,6 @@ import (
"strings" "strings"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
prom "kubesphere.io/kubesphere/pkg/simple/client/prometheus"
) )
func GetNamespacesWithMetrics(namespaces []*v1.Namespace) []*v1.Namespace { func GetNamespacesWithMetrics(namespaces []*v1.Namespace) []*v1.Namespace {
@@ -34,10 +32,10 @@ func GetNamespacesWithMetrics(namespaces []*v1.Namespace) []*v1.Namespace {
nsFilter := "^(" + strings.Join(nsNameList, "|") + ")$" nsFilter := "^(" + strings.Join(nsNameList, "|") + ")$"
var timeRelateParams = make(url.Values) var timeRelateParams = make(url.Values)
params := prom.MonitoringRequestParams{ params := MonitoringRequestParams{
ResourcesFilter: nsFilter, ResourcesFilter: nsFilter,
Params: timeRelateParams, Params: timeRelateParams,
QueryType: prom.DefaultQueryType, QueryType: DefaultQueryType,
MetricsFilter: "namespace_cpu_usage|namespace_memory_usage_wo_cache|namespace_pod_count", MetricsFilter: "namespace_cpu_usage|namespace_memory_usage_wo_cache|namespace_pod_count",
} }

View File

@@ -0,0 +1,33 @@
package metrics
import "net/url"
const (
DefaultQueryStep = "10m"
DefaultQueryTimeout = "10s"
RangeQueryType = "query_range?"
DefaultQueryType = "query?"
)
type MonitoringRequestParams struct {
Params url.Values
QueryType string
SortMetricName string
SortType string
PageNum string
LimitNum string
Tp string
MetricsFilter string
ResourcesFilter string
MetricsName string
WorkloadName string
NodeId string
WsName string
NsName string
PodName string
PVCName string
StorageClassName string
ContainerName string
WorkloadKind string
ComponentName string
}

View File

@@ -19,7 +19,7 @@ package nodes
import ( import (
"fmt" "fmt"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"math" "math"
"strings" "strings"
"time" "time"
@@ -36,7 +36,7 @@ import (
func DrainNode(nodename string) (err error) { func DrainNode(nodename string) (err error) {
k8sclient := k8s.Client() k8sclient := client.ClientSets().K8s().Kubernetes()
node, err := k8sclient.CoreV1().Nodes().Get(nodename, metav1.GetOptions{}) node, err := k8sclient.CoreV1().Nodes().Get(nodename, metav1.GetOptions{})
if err != nil { if err != nil {
return err return err
@@ -68,7 +68,7 @@ func DrainNode(nodename string) (err error) {
func drainEviction(nodename string, donech chan bool, errch chan error) { func drainEviction(nodename string, donech chan bool, errch chan error) {
k8sclient := k8s.Client() k8sclient := client.ClientSets().K8s().Kubernetes()
var options metav1.ListOptions var options metav1.ListOptions
pods := make([]v1.Pod, 0) pods := make([]v1.Pod, 0)
options.FieldSelector = "spec.nodeName=" + nodename options.FieldSelector = "spec.nodeName=" + nodename
@@ -107,7 +107,6 @@ func drainEviction(nodename string, donech chan bool, errch chan error) {
//create eviction //create eviction
getPodFn := func(namespace, name string) (*v1.Pod, error) { getPodFn := func(namespace, name string) (*v1.Pod, error) {
k8sclient := k8s.Client()
return k8sclient.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{}) return k8sclient.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})
} }
evicerr := evictPods(pods, 0, getPodFn) evicerr := evictPods(pods, 0, getPodFn)
@@ -118,9 +117,7 @@ func drainEviction(nodename string, donech chan bool, errch chan error) {
glog.Fatal(evicerr) glog.Fatal(evicerr)
errch <- err errch <- err
} }
} }
} }
func getPodSource(pod *v1.Pod) (string, error) { func getPodSource(pod *v1.Pod) (string, error) {
@@ -159,7 +156,7 @@ func containDaemonset(pod v1.Pod, daemonsetList appsv1.DaemonSetList) bool {
func evictPod(pod v1.Pod, GracePeriodSeconds int) error { func evictPod(pod v1.Pod, GracePeriodSeconds int) error {
k8sclient := k8s.Client() k8sclient := client.ClientSets().K8s().Kubernetes()
deleteOptions := &metav1.DeleteOptions{} deleteOptions := &metav1.DeleteOptions{}
if GracePeriodSeconds >= 0 { if GracePeriodSeconds >= 0 {
gracePeriodSeconds := int64(GracePeriodSeconds) gracePeriodSeconds := int64(GracePeriodSeconds)

View File

@@ -24,7 +24,7 @@ import (
"io/ioutil" "io/ioutil"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"sort" "sort"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
@@ -253,7 +253,7 @@ func createRouterService(namespace string, routerType corev1.ServiceType, annota
return nil, fmt.Errorf("service template not loaded") return nil, fmt.Errorf("service template not loaded")
} }
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
service := obj.(*corev1.Service) service := obj.(*corev1.Service)
@@ -277,7 +277,7 @@ func createRouterService(namespace string, routerType corev1.ServiceType, annota
func updateRouterService(namespace string, routerType corev1.ServiceType, annotations map[string]string) (*corev1.Service, error) { func updateRouterService(namespace string, routerType corev1.ServiceType, annotations map[string]string) (*corev1.Service, error) {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
service, err := getRouterService(namespace) service, err := getRouterService(namespace)
if err != nil { if err != nil {
@@ -309,7 +309,7 @@ func deleteRouterService(namespace string) (*corev1.Service, error) {
return service, err return service, err
} }
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
// delete controller service // delete controller service
serviceName := constants.IngressControllerPrefix + namespace serviceName := constants.IngressControllerPrefix + namespace
@@ -333,7 +333,7 @@ func createOrUpdateRouterWorkload(namespace string, publishService bool, service
deployName := constants.IngressControllerPrefix + namespace deployName := constants.IngressControllerPrefix + namespace
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
deployment, err := k8sClient.ExtensionsV1beta1().Deployments(constants.IngressControllerNamespace).Get(deployName, meta_v1.GetOptions{}) deployment, err := k8sClient.ExtensionsV1beta1().Deployments(constants.IngressControllerNamespace).Get(deployName, meta_v1.GetOptions{})
createDeployment := true createDeployment := true
@@ -403,7 +403,7 @@ func createOrUpdateRouterWorkload(namespace string, publishService bool, service
} }
func deleteRouterWorkload(namespace string) error { func deleteRouterWorkload(namespace string) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
deleteOptions := meta_v1.DeleteOptions{} deleteOptions := meta_v1.DeleteOptions{}
// delete controller deployment // delete controller deployment

View File

@@ -21,7 +21,6 @@ import (
"fmt" "fmt"
"github.com/emicklei/go-restful" "github.com/emicklei/go-restful"
"github.com/gocraft/dbr" "github.com/gocraft/dbr"
"github.com/golang/glog"
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/db" "kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/gojenkins" "kubesphere.io/kubesphere/pkg/gojenkins"
@@ -29,8 +28,7 @@ import (
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/devops" "kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/params" "kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins" cs "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
"net/http" "net/http"
"sync" "sync"
) )
@@ -42,7 +40,11 @@ type DevOpsProjectRoleResponse struct {
func ListDevopsProjects(workspace, username string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) { func ListDevopsProjects(workspace, username string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
if err != nil {
klog.Error(err)
return nil, err
}
query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, devops.DevOpsProject{})...). query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, devops.DevOpsProject{})...).
From(devops.DevOpsProjectTableName) From(devops.DevOpsProjectTableName)
@@ -87,14 +89,14 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
} }
query.Limit(uint64(limit)) query.Limit(uint64(limit))
query.Offset(uint64(offset)) query.Offset(uint64(offset))
_, err := query.Load(&projects) _, err = query.Load(&projects)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
count, err := query.Count() count, err := query.Count()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
@@ -107,7 +109,11 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
} }
func GetDevOpsProjectsCount(username string) (uint32, error) { func GetDevOpsProjectsCount(username string) (uint32, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := cs.ClientSets().MySQL()
if err != nil {
klog.Error(err)
return 0, err
}
query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, devops.DevOpsProject{})...). query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, devops.DevOpsProject{})...).
From(devops.DevOpsProjectTableName) From(devops.DevOpsProjectTableName)
@@ -137,20 +143,27 @@ func GetDevOpsProjectsCount(username string) (uint32, error) {
func DeleteDevOpsProject(projectId, username string) error { func DeleteDevOpsProject(projectId, username string) error {
err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner}) err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return restful.NewError(http.StatusForbidden, err.Error()) return restful.NewError(http.StatusForbidden, err.Error())
} }
gojenkins := admin_jenkins.Client()
if gojenkins == nil { dp, err := cs.ClientSets().Devops()
err := fmt.Errorf("could not connect to jenkins") if err != nil {
glog.Error(err) klog.Error(err)
return restful.NewError(http.StatusServiceUnavailable, err.Error()) return restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
devopsdb := devops_mysql.OpenDatabase() jenkins := dp.Jenkins()
_, err = gojenkins.DeleteJob(projectId)
devopsdb, err := cs.ClientSets().MySQL()
if err != nil {
klog.Error(err)
return restful.NewError(http.StatusServiceUnavailable, err.Error())
}
_, err = jenkins.DeleteJob(projectId)
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound { if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
@@ -159,22 +172,22 @@ func DeleteDevOpsProject(projectId, username string) error {
roleNames = append(roleNames, devops.GetProjectRoleName(projectId, role)) roleNames = append(roleNames, devops.GetProjectRoleName(projectId, role))
roleNames = append(roleNames, devops.GetPipelineRoleName(projectId, role)) roleNames = append(roleNames, devops.GetPipelineRoleName(projectId, role))
} }
err = gojenkins.DeleteProjectRoles(roleNames...) err = jenkins.DeleteProjectRoles(roleNames...)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
_, err = devopsdb.DeleteFrom(devops.DevOpsProjectMembershipTableName). _, err = devopsdb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
Where(db.Eq(devops.DevOpsProjectMembershipProjectIdColumn, projectId)).Exec() Where(db.Eq(devops.DevOpsProjectMembershipProjectIdColumn, projectId)).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
_, err = devopsdb.Update(devops.DevOpsProjectTableName). _, err = devopsdb.Update(devops.DevOpsProjectTableName).
Set(devops.StatusColumn, devops.StatusDeleted). Set(devops.StatusColumn, devops.StatusDeleted).
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).Exec() Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
project := &devops.DevOpsProject{} project := &devops.DevOpsProject{}
@@ -183,7 +196,7 @@ func DeleteDevOpsProject(projectId, username string) error {
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)). Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).
LoadOne(project) LoadOne(project)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
return nil return nil
@@ -191,17 +204,24 @@ func DeleteDevOpsProject(projectId, username string) error {
func CreateDevopsProject(username string, workspace string, req *devops.DevOpsProject) (*devops.DevOpsProject, error) { func CreateDevopsProject(username string, workspace string, req *devops.DevOpsProject) (*devops.DevOpsProject, error) {
jenkinsClient := admin_jenkins.Client() dp, err := cs.ClientSets().Devops()
if jenkinsClient == nil { if err != nil {
err := fmt.Errorf("could not connect to jenkins") klog.Error(err)
glog.Error(err) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
jenkinsClient := dp.Jenkins()
devopsdb, err := cs.ClientSets().MySQL()
if err != nil {
klog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error()) return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
} }
devopsdb := devops_mysql.OpenDatabase()
project := devops.NewDevOpsProject(req.Name, req.Description, username, req.Extra, workspace) project := devops.NewDevOpsProject(req.Name, req.Description, username, req.Extra, workspace)
_, err := jenkinsClient.CreateFolder(project.ProjectId, project.Description) _, err = jenkinsClient.CreateFolder(project.ProjectId, project.Description)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
@@ -229,14 +249,14 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
close(addRoleCh) close(addRoleCh)
for addRoleResponse := range addRoleCh { for addRoleResponse := range addRoleCh {
if addRoleResponse.Err != nil { if addRoleResponse.Err != nil {
glog.Errorf("%+v", addRoleResponse.Err) klog.Errorf("%+v", addRoleResponse.Err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(addRoleResponse.Err), addRoleResponse.Err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(addRoleResponse.Err), addRoleResponse.Err.Error())
} }
} }
globalRole, err := jenkinsClient.GetGlobalRole(devops.JenkinsAllUserRoleName) globalRole, err := jenkinsClient.GetGlobalRole(devops.JenkinsAllUserRoleName)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
if globalRole == nil { if globalRole == nil {
@@ -244,41 +264,41 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
GlobalRead: true, GlobalRead: true,
}, true) }, true)
if err != nil { if err != nil {
glog.Error("failed to create jenkins global role") klog.Error("failed to create jenkins global role")
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
} }
err = globalRole.AssignRole(username) err = globalRole.AssignRole(username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
projectRole, err := jenkinsClient.GetProjectRole(devops.GetProjectRoleName(project.ProjectId, devops.ProjectOwner)) projectRole, err := jenkinsClient.GetProjectRole(devops.GetProjectRoleName(project.ProjectId, devops.ProjectOwner))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = projectRole.AssignRole(username) err = projectRole.AssignRole(username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
pipelineRole, err := jenkinsClient.GetProjectRole(devops.GetPipelineRoleName(project.ProjectId, devops.ProjectOwner)) pipelineRole, err := jenkinsClient.GetProjectRole(devops.GetPipelineRoleName(project.ProjectId, devops.ProjectOwner))
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
err = pipelineRole.AssignRole(username) err = pipelineRole.AssignRole(username)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error()) return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} }
_, err = devopsdb.InsertInto(devops.DevOpsProjectTableName). _, err = devopsdb.InsertInto(devops.DevOpsProjectTableName).
Columns(devops.DevOpsProjectColumns...).Record(project).Exec() Columns(devops.DevOpsProjectColumns...).Record(project).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
@@ -286,7 +306,7 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
_, err = devopsdb.InsertInto(devops.DevOpsProjectMembershipTableName). _, err = devopsdb.InsertInto(devops.DevOpsProjectMembershipTableName).
Columns(devops.DevOpsProjectMembershipColumns...).Record(projectMembership).Exec() Columns(devops.DevOpsProjectMembershipColumns...).Record(projectMembership).Exec()
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error()) return nil, restful.NewError(http.StatusInternalServerError, err.Error())
} }
return project, nil return project, nil
@@ -295,7 +315,7 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
func GetUserDevopsSimpleRules(username, projectId string) ([]models.SimpleRule, error) { func GetUserDevopsSimpleRules(username, projectId string) ([]models.SimpleRule, error) {
role, err := devops.GetProjectUserRole(username, projectId) role, err := devops.GetProjectUserRole(username, projectId)
if err != nil { if err != nil {
glog.Errorf("%+v", err) klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusForbidden, err.Error()) return nil, restful.NewError(http.StatusForbidden, err.Error())
} }
return GetDevopsRoleSimpleRules(role), nil return GetDevopsRoleSimpleRules(role), nil

View File

@@ -25,7 +25,7 @@ import (
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
ws "kubesphere.io/kubesphere/pkg/models/workspaces" ws "kubesphere.io/kubesphere/pkg/models/workspaces"
"kubesphere.io/kubesphere/pkg/params" "kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"strconv" "strconv"
) )
@@ -44,7 +44,7 @@ func CreateNamespace(workspaceName string, namespace *v1.Namespace, username str
namespace.Labels[constants.WorkspaceLabelKey] = workspaceName namespace.Labels[constants.WorkspaceLabelKey] = workspaceName
return k8s.Client().CoreV1().Namespaces().Create(namespace) return client.ClientSets().K8s().Kubernetes().CoreV1().Namespaces().Create(namespace)
} }
func DescribeWorkspace(username, workspaceName string) (*v1alpha1.Workspace, error) { func DescribeWorkspace(username, workspaceName string) (*v1alpha1.Workspace, error) {

View File

@@ -29,7 +29,7 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/remotecommand" "k8s.io/client-go/tools/remotecommand"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
) )
// PtyHandler is what remotecommand expects from a pty // PtyHandler is what remotecommand expects from a pty
@@ -179,11 +179,9 @@ func HandleTerminalSession(session sockjs.Session) {
// Executed cmd in the container specified in request and connects it up with the ptyHandler (a session) // Executed cmd in the container specified in request and connects it up with the ptyHandler (a session)
func startProcess(namespace, podName, containerName string, cmd []string, ptyHandler PtyHandler) error { func startProcess(namespace, podName, containerName string, cmd []string, ptyHandler PtyHandler) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
cfg, err := k8s.Config()
if err != nil { cfg := client.ClientSets().K8s().Config()
return err
}
req := k8sClient.CoreV1().RESTClient().Post(). req := k8sClient.CoreV1().RESTClient().Post().
Resource("pods"). Resource("pods").
@@ -290,10 +288,6 @@ func NewSession(shell, namespace, podName, containerName string) (string, error)
sizeChan: make(chan remotecommand.TerminalSize), sizeChan: make(chan remotecommand.TerminalSize),
} }
if err != nil {
return "", err
}
go WaitingForConnection(shell, namespace, podName, containerName, sessionId) go WaitingForConnection(shell, namespace, podName, containerName, sessionId)
return sessionId, nil return sessionId, nil

View File

@@ -19,7 +19,7 @@ package workloads
import ( import (
"fmt" "fmt"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client"
"strings" "strings"
"time" "time"
@@ -31,7 +31,7 @@ import (
const retryTimes = 3 const retryTimes = 3
func JobReRun(namespace, jobName string) error { func JobReRun(namespace, jobName string) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
job, err := k8sClient.BatchV1().Jobs(namespace).Get(jobName, metav1.GetOptions{}) job, err := k8sClient.BatchV1().Jobs(namespace).Get(jobName, metav1.GetOptions{})
if err != nil { if err != nil {
return err return err
@@ -71,7 +71,7 @@ func JobReRun(namespace, jobName string) error {
} }
func deleteJob(namespace, job string) error { func deleteJob(namespace, job string) error {
k8sClient := k8s.Client() k8sClient := client.ClientSets().K8s().Kubernetes()
deletePolicy := metav1.DeletePropagationBackground deletePolicy := metav1.DeletePropagationBackground
err := k8sClient.BatchV1().Jobs(namespace).Delete(job, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy}) err := k8sClient.BatchV1().Jobs(namespace).Delete(job, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
return err return err

View File

@@ -30,8 +30,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/iam" "kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/resources" "kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params" "kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql" clientset "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/utils/k8sutil" "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"strings" "strings"
@@ -41,7 +40,7 @@ import (
"errors" "errors"
"k8s.io/api/rbac/v1" "k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
) )
@@ -67,13 +66,13 @@ func Namespaces(workspaceName string) ([]*core.Namespace, error) {
} }
func DeleteNamespace(workspace string, namespaceName string) error { func DeleteNamespace(workspace string, namespaceName string) error {
namespace, err := k8s.Client().CoreV1().Namespaces().Get(namespaceName, meta_v1.GetOptions{}) namespace, err := clientset.ClientSets().K8s().Kubernetes().CoreV1().Namespaces().Get(namespaceName, metav1.GetOptions{})
if err != nil { if err != nil {
return err return err
} }
if namespace.Labels[constants.WorkspaceLabelKey] == workspace { if namespace.Labels[constants.WorkspaceLabelKey] == workspace {
deletePolicy := meta_v1.DeletePropagationForeground deletePolicy := metav1.DeletePropagationForeground
return k8s.Client().CoreV1().Namespaces().Delete(namespaceName, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy}) return clientset.ClientSets().K8s().Kubernetes().CoreV1().Namespaces().Delete(namespaceName, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
} else { } else {
return errors.New("resource not found") return errors.New("resource not found")
} }
@@ -134,7 +133,7 @@ func CreateWorkspaceRoleBinding(workspace, username string, role string) error {
if !k8sutil.ContainsUser(workspaceRoleBinding.Subjects, username) { if !k8sutil.ContainsUser(workspaceRoleBinding.Subjects, username) {
workspaceRoleBinding = workspaceRoleBinding.DeepCopy() workspaceRoleBinding = workspaceRoleBinding.DeepCopy()
workspaceRoleBinding.Subjects = append(workspaceRoleBinding.Subjects, v1.Subject{APIGroup: "rbac.authorization.k8s.io", Kind: "User", Name: username}) workspaceRoleBinding.Subjects = append(workspaceRoleBinding.Subjects, v1.Subject{APIGroup: "rbac.authorization.k8s.io", Kind: "User", Name: username})
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding) _, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding)
if err != nil { if err != nil {
log.Errorf("update workspace role binding failed: %+v", err) log.Errorf("update workspace role binding failed: %+v", err)
return err return err
@@ -165,14 +164,17 @@ func DeleteWorkspaceRoleBinding(workspace, username string, role string) error {
} }
} }
workspaceRoleBinding, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding) workspaceRoleBinding, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding)
return err return err
} }
func GetDevOpsProjects(workspaceName string) ([]string, error) { func GetDevOpsProjects(workspaceName string) ([]string, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := clientset.ClientSets().MySQL()
if err != nil {
return nil, err
}
query := dbconn.Select(devops.DevOpsProjectIdColumn). query := dbconn.Select(devops.DevOpsProjectIdColumn).
From(devops.DevOpsProjectTableName). From(devops.DevOpsProjectTableName).
@@ -236,7 +238,10 @@ func GetAllProjectNums() (int, error) {
} }
func GetAllDevOpsProjectsNums() (int, error) { func GetAllDevOpsProjectsNums() (int, error) {
dbconn := devops_mysql.OpenDatabase() dbconn, err := clientset.ClientSets().MySQL()
if err != nil {
return 0, err
}
query := dbconn.Select(devops.DevOpsProjectIdColumn). query := dbconn.Select(devops.DevOpsProjectIdColumn).
From(devops.DevOpsProjectTableName). From(devops.DevOpsProjectTableName).

View File

@@ -17,7 +17,11 @@
*/ */
package options package options
import "github.com/spf13/pflag" import (
"fmt"
"github.com/spf13/pflag"
"kubesphere.io/kubesphere/pkg/utils/net"
)
type ServerRunOptions struct { type ServerRunOptions struct {
// server bind address // server bind address
@@ -49,6 +53,26 @@ func NewServerRunOptions() *ServerRunOptions {
return &s return &s
} }
func (s *ServerRunOptions) Validate() []error {
errs := []error{}
if s.SecurePort == 0 && s.InsecurePort == 0 {
errs = append(errs, fmt.Errorf("insecure and secure port can not be disabled at the same time"))
}
if net.IsValidPort(s.SecurePort) {
if s.TlsCertFile == "" {
errs = append(errs, fmt.Errorf("tls cert file is empty while secure serving"))
}
if s.TlsPrivateKey == "" {
errs = append(errs, fmt.Errorf("tls private key file is empty while secure serving"))
}
}
return errs
}
func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.BindAddress, "bind-address", "0.0.0.0", "server bind address") fs.StringVar(&s.BindAddress, "bind-address", "0.0.0.0", "server bind address")

157
pkg/server/config/config.go Normal file
View File

@@ -0,0 +1,157 @@
package config
import (
"fmt"
"github.com/emicklei/go-restful"
"github.com/spf13/viper"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/ldap"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/prometheus"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3"
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"net/http"
)
// install api for config
func InstallAPI(c *restful.Container) {
ws := runtime.NewWebService(schema.GroupVersion{
Group: "",
Version: "v1alpha1",
})
ws.Route(ws.GET("/configz").
To(func(request *restful.Request, response *restful.Response) {
response.WriteAsJson(sharedConfig)
}).
Doc("Get system components configuration").
Produces(restful.MIME_JSON).
Writes(Config{}).
Returns(http.StatusOK, "ok", Config{}))
c.Add(ws)
}
// load configuration after setup
func Load() error {
sharedConfig = newConfig()
viper.SetConfigName(DefaultConfigurationName)
viper.AddConfigPath(DefaultConfigurationPath)
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
klog.Warning("configuration file not found")
return nil
} else {
panic(fmt.Errorf("error parsing configuration file %s", err))
}
}
conf := &Config{}
if err := viper.Unmarshal(&conf); err != nil {
klog.Error(fmt.Errorf("error unmarshal configuration %v", err))
return err
} else {
conf.Apply(shadowConfig)
sharedConfig = conf
}
return nil
}
const (
DefaultConfigurationName = "kubesphere"
DefaultConfigurationPath = "/etc/kubesphere"
)
var (
// sharedConfig holds configuration across kubesphere
sharedConfig *Config
// shadowConfig contains options from commandline options
shadowConfig = &Config{}
)
type Config struct {
MySQLOptions *mysql.MySQLOptions `json:"mysql,omitempty" yaml:"mysql,omitempty" mapstructure:"mysql"`
DevopsOptions *devops.DevopsOptions `json:"devops,omitempty" yaml:"devops,omitempty" mapstructure:"devops"`
SonarQubeOptions *sonarqube.SonarQubeOptions `json:"sonarqube,omitempty" yaml:"sonarQube,omitempty" mapstructure:"sonarqube"`
KubernetesOptions *k8s.KubernetesOptions `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty" mapstructure:"kubernetes"`
ServiceMeshOptions *servicemesh.ServiceMeshOptions `json:"servicemesh,omitempty" yaml:"servicemesh,omitempty" mapstructure:"servicemesh"`
LdapOptions *ldap.LdapOptions `json:"ldap,omitempty" yaml:"ldap,omitempty" mapstructure:"ldap"`
RedisOptions *redis.RedisOptions `json:"redis,omitempty" yaml:"redis,omitempty" mapstructure:"redis"`
S3Options *s2is3.S3Options `json:"s3,omitempty" yaml:"s3,omitempty" mapstructure:"s3"`
OpenPitrixOptions *openpitrix.OpenPitrixOptions `json:"openpitrix,omitempty" yaml:"openpitrix,omitempty" mapstructure:"openpitrix"`
MonitoringOptions *prometheus.PrometheusOptions `json:"monitoring,omitempty" yaml:"monitoring,omitempty" mapstructure:"monitoring"`
}
func newConfig() *Config {
return &Config{
MySQLOptions: mysql.NewMySQLOptions(),
DevopsOptions: devops.NewDevopsOptions(),
SonarQubeOptions: sonarqube.NewSonarQubeOptions(),
KubernetesOptions: k8s.NewKubernetesOptions(),
ServiceMeshOptions: servicemesh.NewServiceMeshOptions(),
LdapOptions: ldap.NewLdapOptions(),
RedisOptions: redis.NewRedisOptions(),
S3Options: s2is3.NewS3Options(),
OpenPitrixOptions: openpitrix.NewOpenPitrixOptions(),
MonitoringOptions: prometheus.NewPrometheusOptions(),
}
}
func Get() *Config {
return sharedConfig
}
func (c *Config) Apply(conf *Config) {
shadowConfig = conf
if conf.MonitoringOptions != nil {
conf.MonitoringOptions.ApplyTo(c.MonitoringOptions)
}
if conf.OpenPitrixOptions != nil {
conf.OpenPitrixOptions.ApplyTo(c.OpenPitrixOptions)
}
if conf.S3Options != nil {
conf.S3Options.ApplyTo(c.S3Options)
}
if conf.RedisOptions != nil {
conf.RedisOptions.ApplyTo(c.RedisOptions)
}
if conf.LdapOptions != nil {
conf.LdapOptions.ApplyTo(c.LdapOptions)
}
if conf.ServiceMeshOptions != nil {
conf.ServiceMeshOptions.ApplyTo(c.ServiceMeshOptions)
}
if conf.KubernetesOptions != nil {
conf.KubernetesOptions.ApplyTo(c.KubernetesOptions)
}
if conf.SonarQubeOptions != nil {
conf.SonarQubeOptions.ApplyTo(c.SonarQubeOptions)
}
if conf.DevopsOptions != nil {
conf.DevopsOptions.ApplyTo(c.DevopsOptions)
}
if conf.MySQLOptions != nil {
conf.MySQLOptions.ApplyTo(c.MySQLOptions)
}
}

View File

@@ -0,0 +1,129 @@
package config
import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/ldap"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/prometheus"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3"
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"os"
"reflect"
"testing"
"time"
)
func newTestConfig() *Config {
conf := &Config{
MySQLOptions: &mysql.MySQLOptions{
Host: "10.68.96.5:3306",
Username: "root",
Password: "admin",
MaxIdleConnections: 10,
MaxOpenConnections: 20,
MaxConnectionLifeTime: time.Duration(10) * time.Second,
},
DevopsOptions: &devops.DevopsOptions{
Host: "http://ks-devops.kubesphere-devops-system.svc",
Username: "jenkins",
Password: "kubesphere",
MaxConnections: 10,
},
SonarQubeOptions: &sonarqube.SonarQubeOptions{
Host: "http://sonarqube.kubesphere-devops-system.svc",
Token: "ABCDEFG",
},
KubernetesOptions: &k8s.KubernetesOptions{
KubeConfig: "/Users/zry/.kube/config",
Master: "https://127.0.0.1:6443",
QPS: 1e6,
Burst: 1e6,
},
ServiceMeshOptions: &servicemesh.ServiceMeshOptions{
IstioPilotHost: "http://istio-pilot.istio-system.svc:9090",
JaegerQueryHost: "http://jaeger-query.istio-system.svc:80",
ServicemeshPrometheusHost: "http://prometheus-k8s.kubesphere-monitoring-system.svc",
},
LdapOptions: &ldap.LdapOptions{
Host: "http://openldap.kubesphere-system.svc",
ManagerDN: "cn=admin,dc=example,dc=org",
ManagerPassword: "P@88w0rd",
UserSearchBase: "ou=Users,dc=example,dc=org",
GroupSearchBase: "ou=Groups,dc=example,dc=org",
},
RedisOptions: &redis.RedisOptions{
Host: "10.10.111.110",
Port: 6379,
Password: "",
DB: 0,
},
S3Options: &s2is3.S3Options{
Endpoint: "http://minio.openpitrix-system.svc",
Region: "us-east-1",
DisableSSL: true,
ForcePathStyle: false,
AccessKeyID: "ABCDEFGHIJKLMN",
SecretAccessKey: "OPQRSTUVWXYZ",
SessionToken: "abcdefghijklmn",
Bucket: "ssss",
},
OpenPitrixOptions: &openpitrix.OpenPitrixOptions{
APIServer: "http://api-gateway.openpitrix-system.svc",
Token: "ABCDEFGHIJKLMN",
},
MonitoringOptions: &prometheus.PrometheusOptions{
Endpoint: "http://prometheus.kubesphere-monitoring-system.svc",
SecondaryEndpoint: "http://prometheus.kubesphere-monitoring-system.svc",
},
}
return conf
}
func saveTestConfig(t *testing.T, conf *Config) {
content, err := yaml.Marshal(conf)
if err != nil {
t.Fatalf("error marshal config. %v", err)
}
err = ioutil.WriteFile(fmt.Sprintf("%s.yaml", DefaultConfigurationName), content, 0640)
if err != nil {
t.Fatalf("error write configuration file, %v", err)
}
}
func cleanTestConfig(t *testing.T) {
file := fmt.Sprintf("%s.yaml", DefaultConfigurationName)
if _, err := os.Stat(file); os.IsNotExist(err) {
t.Log("file not exists, skipping")
return
}
err := os.Remove(file)
if err != nil {
t.Fatalf("remove %s file failed", file)
}
}
func TestGet(t *testing.T) {
conf := newTestConfig()
saveTestConfig(t, conf)
err := Load()
if err != nil {
t.Fatal(err)
}
conf2 := Get()
if !reflect.DeepEqual(conf2, conf) {
t.Fatalf("Get %v\n expected %v\n", conf2, conf)
}
cleanTestConfig(t)
}

View File

@@ -1,86 +0,0 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package admin_jenkins
import (
"flag"
"github.com/golang/glog"
"kubesphere.io/kubesphere/pkg/gojenkins"
"sync"
)
var (
jenkinsInitMutex sync.Mutex
jenkinsClient *gojenkins.Jenkins
jenkinsAdminAddress string
jenkinsAdminUsername string
jenkinsAdminPassword string
jenkinsMaxConn int
)
const (
JenkinsAllUserRoleName = "kubesphere-user"
)
func init() {
flag.StringVar(&jenkinsAdminAddress, "jenkins-address", "http://ks-jenkins.kubesphere-devops-system.svc/", "data source name")
flag.StringVar(&jenkinsAdminUsername, "jenkins-username", "admin", "username of jenkins")
flag.StringVar(&jenkinsAdminPassword, "jenkins-password", "passw0rd", "password of jenkins")
flag.IntVar(&jenkinsMaxConn, "jenkins-max-conn", 20, "max conn to jenkins")
}
func GetJenkins() *gojenkins.Jenkins {
jenkins := gojenkins.CreateJenkins(nil, jenkinsAdminAddress, jenkinsMaxConn, jenkinsAdminUsername, jenkinsAdminPassword)
return jenkins
}
func Client() *gojenkins.Jenkins {
if jenkinsClient == nil {
jenkinsInitMutex.Lock()
defer jenkinsInitMutex.Unlock()
if jenkinsClient == nil {
jenkins := GetJenkins()
jenkins, err := jenkins.Init()
if err != nil {
glog.Errorf("failed to connect jenkins, %+v", err)
return nil
}
globalRole, err := jenkins.GetGlobalRole(JenkinsAllUserRoleName)
if err != nil {
glog.Errorf("failed to get jenkins role, %+v", err)
return nil
}
if globalRole == nil {
_, err := jenkins.AddGlobalRole(JenkinsAllUserRoleName, gojenkins.GlobalPermissionIds{
GlobalRead: true,
}, true)
if err != nil {
glog.Errorf("failed to create jenkins global role, %+v", err)
return nil
}
}
_, err = jenkins.AddProjectRole(JenkinsAllUserRoleName, "\\n\\s*\\r", gojenkins.ProjectPermissionIds{
SCMTag: true,
}, true)
if err != nil {
glog.Errorf("failed to create jenkins project role, %+v", err)
return nil
}
jenkinsClient = jenkins
}
}
return jenkinsClient
}

View File

@@ -0,0 +1,109 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package devops
import (
"fmt"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/gojenkins"
"sync"
)
const (
JenkinsAllUserRoleName = "kubesphere-user"
)
type DevopsClient struct {
jenkinsClient *gojenkins.Jenkins
}
func NewDevopsClient(options *DevopsOptions) (*DevopsClient, error) {
var d DevopsClient
jenkins := gojenkins.CreateJenkins(nil, options.Host, options.MaxConnections, options.Username, options.Password)
jenkins, err := jenkins.Init()
if err != nil {
klog.Errorf("failed to connecto to jenkins role, %+v", err)
return nil, err
}
d.jenkinsClient = jenkins
err = d.initializeJenkins()
if err != nil {
klog.Error(err)
return nil, err
}
return &d, nil
}
func NewDevopsClientOrDie(options *DevopsOptions) *DevopsClient {
jenkins := gojenkins.CreateJenkins(nil, options.Host, options.MaxConnections, options.Username, options.Password)
jenkins, err := jenkins.Init()
if err != nil {
klog.Errorf("failed to connecto to jenkins role, %+v", err)
panic(err)
}
d := &DevopsClient{
jenkinsClient: jenkins,
}
err = d.initializeJenkins()
if err != nil {
klog.Error(err)
panic(err)
}
return d
}
func (c *DevopsClient) Jenkins() *gojenkins.Jenkins {
return c.jenkinsClient
}
var mutex = sync.Mutex{}
func (c *DevopsClient) initializeJenkins() error {
mutex.Lock()
defer mutex.Unlock()
if c.jenkinsClient == nil {
return fmt.Errorf("jenkins intialization failed")
}
globalRole, err := c.jenkinsClient.GetGlobalRole(JenkinsAllUserRoleName)
if err != nil {
klog.Error(err)
return err
}
// Jenkins uninitialized, create global role
if globalRole == nil {
_, err := c.jenkinsClient.AddGlobalRole(JenkinsAllUserRoleName, gojenkins.GlobalPermissionIds{GlobalRead: true}, true)
if err != nil {
klog.Error(err)
return err
}
}
_, err = c.jenkinsClient.AddProjectRole(JenkinsAllUserRoleName, "\\n\\s*\\r", gojenkins.ProjectPermissionIds{SCMTag: true}, true)
if err != nil {
klog.Error(err)
return err
}
return nil
}

View File

@@ -0,0 +1,81 @@
package devops
import (
"fmt"
"github.com/spf13/pflag"
)
type DevopsOptions struct {
Host string `json:",omitempty" yaml:",omitempty" description:"Jenkins service host address"`
Username string `json:",omitempty" yaml:",omitempty" description:"Jenkins admin username"`
Password string `json:",omitempty" yaml:",omitempty" description:"Jenkins admin password"`
MaxConnections int `json:"maxConnections,omitempty" yaml:"maxConnections,omitempty" description:"Maximum connections allowed to connect to Jenkins"`
}
// NewDevopsOptions returns a `zero` instance
func NewDevopsOptions() *DevopsOptions {
return &DevopsOptions{
Host: "",
Username: "",
Password: "",
MaxConnections: 100,
}
}
func (s *DevopsOptions) ApplyTo(options *DevopsOptions) {
if options == nil {
return
}
if s.Host != "" {
options.Host = s.Host
}
if s.Username != "" {
options.Username = s.Username
}
if s.Password != "" {
options.Password = s.Password
}
if s.MaxConnections > 0 {
options.MaxConnections = s.MaxConnections
}
}
//
func (s *DevopsOptions) Validate() []error {
errors := []error{}
// devops is not needed, ignore rest options
if s.Host == "" {
return errors
}
if s.Username == "" || s.Password == "" {
errors = append(errors, fmt.Errorf("jenkins's username or password is empty"))
}
if s.MaxConnections <= 0 {
errors = append(errors, fmt.Errorf("jenkins's maximum connections should be greater than 0"))
}
return errors
}
func (s *DevopsOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.Host, "jenkins-host", s.Host, ""+
"Jenkins service host address. If left blank, means Jenkins "+
"is unnecessary.")
fs.StringVar(&s.Username, "jenkins-username", s.Username, ""+
"Username for access to Jenkins service. Leave it blank if there isn't any.")
fs.StringVar(&s.Password, "jenkins-password", s.Password, ""+
"Password for access to Jenkins service, used pair with username.")
fs.IntVar(&s.MaxConnections, "jenkins-max-connections", s.MaxConnections, ""+
"Maximum allowed connections to Jenkins. ")
}

View File

@@ -1,56 +0,0 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package devops_mysql
import (
"flag"
"github.com/gocraft/dbr"
"github.com/golang/glog"
"kubesphere.io/kubesphere/pkg/db"
"sync"
"time"
)
var (
dbClientOnce sync.Once
dsn string
dbClient *db.Database
)
func init() {
flag.StringVar(&dsn, "devops-database-connection", "root:password@tcp(openpitrix-db.openpitrix-system.svc:3306)/devops", "data source name")
}
var defaultEventReceiver = db.EventReceiver{}
func OpenDatabase() *db.Database {
dbClientOnce.Do(func() {
conn, err := dbr.Open("mysql", dsn+"?parseTime=1&multiStatements=1&charset=utf8mb4&collation=utf8mb4_unicode_ci", &defaultEventReceiver)
if err != nil {
glog.Fatal(err)
}
conn.SetMaxIdleConns(100)
conn.SetMaxOpenConns(100)
conn.SetConnMaxLifetime(10 * time.Second)
dbClient = &db.Database{
Session: conn.NewSession(nil),
}
err = dbClient.Ping()
if err != nil {
glog.Error(err)
}
})
return dbClient
}

View File

@@ -0,0 +1,315 @@
package client
import (
"fmt"
goredis "github.com/go-redis/redis"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/ldap"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/prometheus"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"sync"
)
type ClientSetNotEnabledError struct {
err error
}
func (e ClientSetNotEnabledError) Error() string {
return fmt.Sprintf("client set not enabled: %s", e.err.Error())
}
type ClientSetOptions struct {
mySQLOptions *mysql.MySQLOptions
redisOptions *redis.RedisOptions
kubernetesOptions *k8s.KubernetesOptions
devopsOptions *devops.DevopsOptions
sonarqubeOptions *sonarqube.SonarQubeOptions
ldapOptions *ldap.LdapOptions
s3Options *s2is3.S3Options
openPitrixOptions *openpitrix.OpenPitrixOptions
prometheusOptions *prometheus.PrometheusOptions
}
func NewClientSetOptions() *ClientSetOptions {
return &ClientSetOptions{
mySQLOptions: mysql.NewMySQLOptions(),
redisOptions: redis.NewRedisOptions(),
kubernetesOptions: k8s.NewKubernetesOptions(),
ldapOptions: ldap.NewLdapOptions(),
devopsOptions: devops.NewDevopsOptions(),
sonarqubeOptions: sonarqube.NewSonarQubeOptions(),
s3Options: s2is3.NewS3Options(),
openPitrixOptions: openpitrix.NewOpenPitrixOptions(),
prometheusOptions: prometheus.NewPrometheusOptions(),
}
}
func (c *ClientSetOptions) SetMySQLOptions(options *mysql.MySQLOptions) *ClientSetOptions {
c.mySQLOptions = options
return c
}
func (c *ClientSetOptions) SetRedisOptions(options *redis.RedisOptions) *ClientSetOptions {
c.redisOptions = options
return c
}
func (c *ClientSetOptions) SetKubernetesOptions(options *k8s.KubernetesOptions) *ClientSetOptions {
c.kubernetesOptions = options
return c
}
func (c *ClientSetOptions) SetDevopsOptions(options *devops.DevopsOptions) *ClientSetOptions {
c.devopsOptions = options
return c
}
func (c *ClientSetOptions) SetLdapOptions(options *ldap.LdapOptions) *ClientSetOptions {
c.ldapOptions = options
return c
}
func (c *ClientSetOptions) SetS3Options(options *s2is3.S3Options) *ClientSetOptions {
c.s3Options = options
return c
}
func (c *ClientSetOptions) SetOpenPitrixOptions(options *openpitrix.OpenPitrixOptions) *ClientSetOptions {
c.openPitrixOptions = options
return c
}
func (c *ClientSetOptions) SetPrometheusOptions(options *prometheus.PrometheusOptions) *ClientSetOptions {
c.prometheusOptions = options
return c
}
// ClientSet provide best of effort service to initialize clients,
// but there is no guarantee to return a valid client instance,
// so do validity check before use
type ClientSet struct {
csoptions *ClientSetOptions
stopCh <-chan struct{}
mySQLClient *mysql.MySQLClient
k8sClient *k8s.KubernetesClient
ldapClient *ldap.LdapClient
devopsClient *devops.DevopsClient
sonarQubeClient *sonarqube.SonarQubeClient
redisClient *redis.RedisClient
s3Client *s2is3.S3Client
prometheusClient *prometheus.PrometheusClient
openpitrixClient *openpitrix.OpenPitrixClient
}
var mutex sync.Mutex
// global clientsets instance
var sharedClientSet *ClientSet
func ClientSets() *ClientSet {
return sharedClientSet
}
func NewClientSetFactory(c *ClientSetOptions, stopCh <-chan struct{}) *ClientSet {
sharedClientSet = &ClientSet{csoptions: c, stopCh: stopCh}
if c.kubernetesOptions != nil {
sharedClientSet.k8sClient = k8s.NewKubernetesClientOrDie(c.kubernetesOptions)
}
return sharedClientSet
}
// lazy creating
func (cs *ClientSet) MySQL() (*mysql.Database, error) {
var err error
if cs.csoptions.mySQLOptions == nil || cs.csoptions.mySQLOptions.Host == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.mySQLClient != nil {
return cs.mySQLClient.Database(), nil
} else {
mutex.Lock()
defer mutex.Unlock()
if cs.mySQLClient == nil {
cs.mySQLClient, err = mysql.NewMySQLClient(cs.csoptions.mySQLOptions, cs.stopCh)
if err != nil {
return nil, err
}
}
return cs.mySQLClient.Database(), nil
}
}
func (cs *ClientSet) Redis() (*goredis.Client, error) {
var err error
if cs.csoptions.redisOptions == nil || cs.csoptions.redisOptions.Host == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.redisClient != nil {
return cs.redisClient.Redis(), nil
} else {
mutex.Lock()
defer mutex.Unlock()
if cs.redisClient == nil {
cs.redisClient, err = redis.NewRedisClient(cs.csoptions.redisOptions, cs.stopCh)
if err != nil {
return nil, err
}
}
return cs.redisClient.Redis(), nil
}
}
func (cs *ClientSet) Devops() (*devops.DevopsClient, error) {
var err error
if cs.csoptions.devopsOptions == nil || cs.csoptions.devopsOptions.Host == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.devopsClient != nil {
return cs.devopsClient, nil
} else {
mutex.Lock()
defer mutex.Unlock()
if cs.devopsClient == nil {
cs.devopsClient, err = devops.NewDevopsClient(cs.csoptions.devopsOptions)
if err != nil {
return nil, err
}
}
return cs.devopsClient, nil
}
}
func (cs *ClientSet) SonarQube() (*sonarqube.SonarQubeClient, error) {
var err error
if cs.csoptions.sonarqubeOptions == nil || cs.csoptions.sonarqubeOptions.Host == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.sonarQubeClient != nil {
return cs.sonarQubeClient, nil
} else {
mutex.Lock()
defer mutex.Unlock()
if cs.sonarQubeClient == nil {
cs.sonarQubeClient, err = sonarqube.NewSonarQubeClient(cs.csoptions.sonarqubeOptions)
if err != nil {
return nil, err
}
}
return cs.sonarQubeClient, nil
}
}
func (cs *ClientSet) Ldap() (*ldap.LdapClient, error) {
var err error
if cs.csoptions.ldapOptions == nil || cs.csoptions.ldapOptions.Host == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.ldapClient != nil {
return cs.ldapClient, nil
} else {
mutex.Lock()
defer mutex.Unlock()
if cs.ldapClient == nil {
cs.ldapClient, err = ldap.NewLdapClient(cs.csoptions.ldapOptions, cs.stopCh)
if err != nil {
return nil, err
}
}
return cs.ldapClient, nil
}
}
// since kubernetes client is required, we will
// create it on setup
func (cs *ClientSet) K8s() *k8s.KubernetesClient {
return cs.k8sClient
}
func (cs *ClientSet) S3() (*s2is3.S3Client, error) {
var err error
if cs.csoptions.s3Options == nil || cs.csoptions.s3Options.Endpoint == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.s3Client != nil {
return cs.s3Client, nil
} else {
mutex.Lock()
defer mutex.Unlock()
if cs.s3Client == nil {
cs.s3Client, err = s2is3.NewS3Client(cs.csoptions.s3Options)
if err != nil {
return nil, err
}
}
return cs.s3Client, nil
}
}
func (cs *ClientSet) OpenPitrix() (*openpitrix.OpenPitrixClient, error) {
var err error
if cs.csoptions.openPitrixOptions == nil || cs.csoptions.openPitrixOptions.APIServer == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.openpitrixClient != nil {
return cs.openpitrixClient, nil
} else {
cs.openpitrixClient, err = openpitrix.NewOpenPitrixClient(cs.csoptions.openPitrixOptions)
if err != nil {
return nil, err
}
return cs.openpitrixClient, nil
}
}
func (cs *ClientSet) Prometheus() (*prometheus.PrometheusClient, error) {
var err error
if cs.csoptions.prometheusOptions == nil || cs.csoptions.prometheusOptions.Endpoint == "" {
return nil, ClientSetNotEnabledError{}
}
if cs.prometheusClient != nil {
return cs.prometheusClient, nil
} else {
mutex.Lock()
defer mutex.Unlock()
if cs.prometheusClient == nil {
cs.prometheusClient, err = prometheus.NewPrometheusClient(cs.csoptions.prometheusOptions)
if err != nil {
return nil, err
}
}
return cs.prometheusClient, nil
}
}

View File

@@ -1,79 +0,0 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package k8s
import (
"flag"
"log"
"os"
"sync"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
var (
kubeConfigFile string
k8sClient *kubernetes.Clientset
k8sClientOnce sync.Once
KubeConfig *rest.Config
MasterURL string
)
func init() {
flag.StringVar(&kubeConfigFile, "kubeconfig-path", "", "path to kubeconfig file")
flag.StringVar(&MasterURL, "master-url", "", "kube-apiserver url, only needed when out of cluster")
}
func Client() *kubernetes.Clientset {
k8sClientOnce.Do(func() {
config, err := Config()
if err != nil {
log.Fatalln(err)
}
k8sClient = kubernetes.NewForConfigOrDie(config)
KubeConfig = config
})
return k8sClient
}
func Config() (kubeConfig *rest.Config, err error) {
if _, err = os.Stat(kubeConfigFile); err == nil {
kubeConfig, err = clientcmd.BuildConfigFromFlags(MasterURL, kubeConfigFile)
} else {
kubeConfig, err = rest.InClusterConfig()
}
if err != nil {
return nil, err
}
kubeConfig.QPS = 1e6
kubeConfig.Burst = 1e6
return kubeConfig, nil
}

View File

@@ -1,46 +0,0 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package k8s
import (
"log"
"sync"
ks "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
)
var (
ksClient *ks.Clientset
ksClientOnce sync.Once
)
func KsClient() *ks.Clientset {
ksClientOnce.Do(func() {
config, err := Config()
if err != nil {
log.Fatalln(err)
}
ksClient = ks.NewForConfigOrDie(config)
})
return ksClient
}

View File

@@ -0,0 +1,100 @@
package k8s
import (
s2i "github.com/kubesphere/s2ioperator/pkg/client/clientset/versioned"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
kubesphere "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
)
type KubernetesClient struct {
// kubernetes client interface
k8s *kubernetes.Clientset
// generated clientset
ks *kubesphere.Clientset
s2i *s2i.Clientset
master string
config *rest.Config
}
// NewKubernetesClient
func NewKubernetesClientOrDie(options *KubernetesOptions) *KubernetesClient {
config, err := clientcmd.BuildConfigFromFlags("", options.KubeConfig)
if err != nil {
panic(err)
}
config.QPS = options.QPS
config.Burst = options.Burst
k := &KubernetesClient{
k8s: kubernetes.NewForConfigOrDie(config),
ks: kubesphere.NewForConfigOrDie(config),
s2i: s2i.NewForConfigOrDie(config),
master: config.Host,
config: config,
}
if options.Master != "" {
k.master = options.Master
}
return k
}
func NewKubernetesClient(options *KubernetesOptions) (*KubernetesClient, error) {
config, err := clientcmd.BuildConfigFromFlags("", options.KubeConfig)
if err != nil {
return nil, err
}
config.QPS = options.QPS
config.Burst = options.Burst
var k KubernetesClient
k.k8s, err = kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}
k.ks, err = kubesphere.NewForConfig(config)
if err != nil {
return nil, err
}
k.s2i, err = s2i.NewForConfig(config)
if err != nil {
return nil, err
}
k.master = options.Master
k.config = config
return &k, nil
}
func (k *KubernetesClient) Kubernetes() kubernetes.Interface {
return k.k8s
}
func (k *KubernetesClient) KubeSphere() kubesphere.Interface {
return k.ks
}
func (k *KubernetesClient) S2i() s2i.Interface {
return k.s2i
}
// master address used to generate kubeconfig for downloading
func (k *KubernetesClient) Master() string {
return k.master
}
func (k *KubernetesClient) Config() *rest.Config {
return k.config
}

View File

@@ -0,0 +1,59 @@
package k8s
import (
"github.com/spf13/pflag"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
"os"
)
type KubernetesOptions struct {
// kubeconfig path, if not specified, will use
// in cluster way to create clientset
KubeConfig string `json:"kubeconfig" yaml:"kubeconfig"`
// kubernetes apiserver public address, used to generate kubeconfig
// for downloading, default to host defined in kubeconfig
// +optional
Master string `json:"master,omitempty" yaml:"master,omitempty"`
// kubernetes clientset qps
// +optional
QPS float32 `json:"qps,omitemtpy" yaml:"qps,omitempty"`
// kubernetes clientset burst
// +optional
Burst int `json:"burst,omitempty" yaml:"burst,omitempty"`
}
// NewKubernetesOptions returns a `zero` instance
func NewKubernetesOptions() *KubernetesOptions {
return &KubernetesOptions{
KubeConfig: "",
QPS: 1e6,
Burst: 1e6,
}
}
func (k *KubernetesOptions) Validate() []error {
errors := []error{}
if k.KubeConfig != "" {
if _, err := os.Stat(k.KubeConfig); err != nil {
errors = append(errors, err)
}
}
return errors
}
func (k *KubernetesOptions) ApplyTo(options *KubernetesOptions) {
reflectutils.Override(options, k)
}
func (k *KubernetesOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&k.KubeConfig, "kubeconfig", k.KubeConfig, ""+
"Path for kubernetes kubeconfig file, if left blank, will use "+
"in cluster way.")
fs.StringVar(&k.Master, "master", k.Master, ""+
"Used to generate kubeconfig for downloading, if not specified, will use host in kubeconfig.")
}

View File

@@ -1,46 +0,0 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package k8s
import (
"log"
"sync"
s2i "github.com/kubesphere/s2ioperator/pkg/client/clientset/versioned"
)
var (
s2iClient *s2i.Clientset
s2iClientOnce sync.Once
)
func S2iClient() *s2i.Clientset {
s2iClientOnce.Do(func() {
config, err := Config()
if err != nil {
log.Fatalln(err)
}
s2iClient = s2i.NewForConfigOrDie(config)
})
return s2iClient
}

View File

@@ -0,0 +1 @@
package kubesphere

View File

@@ -0,0 +1,87 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package ldap
import (
"github.com/go-ldap/ldap"
"k8s.io/klog"
)
type LdapClient struct {
pool Pool
options *LdapOptions
}
// panic if cannot connect to ldap service
func NewLdapClient(options *LdapOptions, stopCh <-chan struct{}) (*LdapClient, error) {
pool, err := NewChannelPool(8, 64, "kubesphere", func(s string) (ldap.Client, error) {
conn, err := ldap.Dial("tcp", options.Host)
if err != nil {
return nil, err
}
return conn, nil
}, []uint16{ldap.LDAPResultAdminLimitExceeded, ldap.ErrorNetwork})
if err != nil {
klog.Error(err)
pool.Close()
return nil, err
}
client := &LdapClient{
pool: pool,
options: options,
}
go func() {
<-stopCh
if client.pool != nil {
client.pool.Close()
}
}()
return client, nil
}
func (l *LdapClient) Ldap() ldap.Client {
if l.pool != nil {
conn, err := l.pool.Get()
if err != nil {
klog.Error(err)
return nil
}
err = conn.Bind(l.options.ManagerDN, l.options.ManagerPassword)
if err != nil {
conn.Close()
klog.Error(err)
return nil
}
return conn
}
return nil
}
func (l *LdapClient) GroupSearchBase() string {
return l.options.GroupSearchBase
}
func (l *LdapClient) UserSearchBase() string {
return l.options.UserSearchBase
}

View File

@@ -1,84 +0,0 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package ldap
import (
"flag"
"github.com/go-ldap/ldap"
"github.com/golang/glog"
"log"
"sync"
)
var (
once sync.Once
pool Pool
ldapHost string
ManagerDN string
ManagerPassword string
UserSearchBase string
GroupSearchBase string
poolSize int
)
func init() {
flag.StringVar(&ldapHost, "ldap-server", "localhost:389", "ldap server host")
flag.StringVar(&ManagerDN, "ldap-manager-dn", "cn=admin,dc=example,dc=org", "ldap manager dn")
flag.StringVar(&ManagerPassword, "ldap-manager-password", "admin", "ldap manager password")
flag.StringVar(&UserSearchBase, "ldap-user-search-base", "ou=Users,dc=example,dc=org", "ldap user search base")
flag.StringVar(&GroupSearchBase, "ldap-group-search-base", "ou=Groups,dc=example,dc=org", "ldap group search base")
flag.IntVar(&poolSize, "ldap-pool-size", 64, "ldap connection pool size")
}
func ldapClientPool() Pool {
once.Do(func() {
var err error
pool, err = NewChannelPool(8, poolSize, "kubesphere", func(s string) (ldap.Client, error) {
conn, err := ldap.Dial("tcp", ldapHost)
if err != nil {
return nil, err
}
return conn, nil
}, []uint16{ldap.LDAPResultTimeLimitExceeded, ldap.ErrorNetwork})
if err != nil {
log.Fatalln(err)
}
})
return pool
}
func Client() (ldap.Client, error) {
conn, err := ldapClientPool().Get()
if err != nil {
glog.Errorln("get ldap connection from pool", err)
return nil, err
}
err = conn.Bind(ManagerDN, ManagerPassword)
if err != nil {
conn.Close()
glog.Errorln("bind manager dn", err)
return nil, err
}
return conn, nil
}

View File

@@ -0,0 +1,53 @@
package ldap
import (
"github.com/spf13/pflag"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
)
type LdapOptions struct {
Host string `json:"host,omitempty" yaml:"host,omitempty"`
ManagerDN string `json:"managerDN,omitempty" yaml:"managerDN,omitempty"`
ManagerPassword string `json:"managerPassword,omitempty" yaml:"managerPassword,omitempty"`
UserSearchBase string `json:"userSearchBase,omitempty" yaml:"userSearchBase,omitempty"`
GroupSearchBase string `json:"groupSearchBase,omitempty" yaml:"groupSearchBase,omitempty"`
}
// NewLdapOptions return a default option
// which host field point to nowhere.
func NewLdapOptions() *LdapOptions {
return &LdapOptions{
Host: "",
ManagerDN: "cn=admin,dc=example,dc=org",
UserSearchBase: "ou=Users,dc=example,dc=org",
GroupSearchBase: "ou=Groups,dc=example,dc=org",
}
}
func (l *LdapOptions) Validate() []error {
errors := []error{}
return errors
}
func (l *LdapOptions) ApplyTo(options *LdapOptions) {
reflectutils.Override(options, l)
}
func (l *LdapOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&l.Host, "ldap-host", l.Host, ""+
"Ldap service host, if left blank, all of the following options will "+
"be ignored and ldap will be disabled.")
fs.StringVar(&l.ManagerDN, "ldap-manager-dn", l.ManagerDN, ""+
"Ldap manager account domain name.")
fs.StringVar(&l.ManagerPassword, "ldap-manager-password", l.ManagerPassword, ""+
"Ldap manager account password.")
fs.StringVar(&l.UserSearchBase, "ldap-user-search-base", l.UserSearchBase, ""+
"Ldap user search base.")
fs.StringVar(&l.GroupSearchBase, "ldap-group-search-base", l.GroupSearchBase, ""+
"Ldap group search base.")
}

View File

@@ -0,0 +1,109 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package mysql
import (
"strings"
"github.com/gocraft/dbr"
)
const (
placeholder = "?"
)
type EqCondition struct {
dbr.Builder
Column string
Value interface{}
}
// Copy From vendor/github.com/gocraft/dbr/condition.go:36
func buildCmp(d dbr.Dialect, buf dbr.Buffer, pred string, column string, value interface{}) error {
buf.WriteString(d.QuoteIdent(column))
buf.WriteString(" ")
buf.WriteString(pred)
buf.WriteString(" ")
buf.WriteString(placeholder)
buf.WriteValue(value)
return nil
}
// And creates AND from a list of conditions
func And(cond ...dbr.Builder) dbr.Builder {
return dbr.And(cond...)
}
// Or creates OR from a list of conditions
func Or(cond ...dbr.Builder) dbr.Builder {
return dbr.Or(cond...)
}
func escape(str string) string {
return strings.Map(func(r rune) rune {
switch r {
case '%', '\'', '^', '[', ']', '!', '_':
return ' '
}
return r
}, str)
}
func Like(column string, value string) dbr.Builder {
value = "%" + strings.TrimSpace(escape(value)) + "%"
return dbr.BuildFunc(func(d dbr.Dialect, buf dbr.Buffer) error {
return buildCmp(d, buf, "LIKE", column, value)
})
}
// Eq is `=`.
// When value is nil, it will be translated to `IS NULL`.
// When value is a slice, it will be translated to `IN`.
// Otherwise it will be translated to `=`.
func Eq(column string, value interface{}) dbr.Builder {
return &EqCondition{
Builder: dbr.Eq(column, value),
Column: column,
Value: value,
}
}
// Neq is `!=`.
// When value is nil, it will be translated to `IS NOT NULL`.
// When value is a slice, it will be translated to `NOT IN`.
// Otherwise it will be translated to `!=`.
func Neq(column string, value interface{}) dbr.Builder {
return dbr.Neq(column, value)
}
// Gt is `>`.
func Gt(column string, value interface{}) dbr.Builder {
return dbr.Gt(column, value)
}
// Gte is '>='.
func Gte(column string, value interface{}) dbr.Builder {
return dbr.Gte(column, value)
}
// Lt is '<'.
func Lt(column string, value interface{}) dbr.Builder {
return dbr.Lt(column, value)
}
// Lte is `<=`.
func Lte(column string, value interface{}) dbr.Builder {
return dbr.Lte(column, value)
}

View File

@@ -0,0 +1,88 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package mysql
import (
"testing"
"github.com/gocraft/dbr"
"github.com/gocraft/dbr/dialect"
"github.com/stretchr/testify/assert"
)
// Ref: https://github.com/gocraft/dbr/blob/5d59a8b3aa915660960329efb3af5513e7a0db07/condition_test.go
func TestCondition(t *testing.T) {
for _, test := range []struct {
cond dbr.Builder
query string
value []interface{}
}{
{
cond: Eq("col", 1),
query: "`col` = ?",
value: []interface{}{1},
},
{
cond: Eq("col", nil),
query: "`col` IS NULL",
value: nil,
},
{
cond: Eq("col", []int{}),
query: "0",
value: nil,
},
{
cond: Neq("col", 1),
query: "`col` != ?",
value: []interface{}{1},
},
{
cond: Neq("col", nil),
query: "`col` IS NOT NULL",
value: nil,
},
{
cond: Gt("col", 1),
query: "`col` > ?",
value: []interface{}{1},
},
{
cond: Gte("col", 1),
query: "`col` >= ?",
value: []interface{}{1},
},
{
cond: Lt("col", 1),
query: "`col` < ?",
value: []interface{}{1},
},
{
cond: Lte("col", 1),
query: "`col` <= ?",
value: []interface{}{1},
},
{
cond: And(Lt("a", 1), Or(Gt("b", 2), Neq("c", 3))),
query: "(`a` < ?) AND ((`b` > ?) OR (`c` != ?))",
value: []interface{}{1, 2, 3},
},
} {
buf := dbr.NewBuffer()
err := test.cond.Build(dialect.MySQL, buf)
assert.NoError(t, err)
assert.Equal(t, test.query, buf.String())
assert.Equal(t, test.value, buf.Value())
}
}

View File

@@ -0,0 +1,283 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package mysql
import (
"database/sql"
"fmt"
"strings"
_ "github.com/go-sql-driver/mysql"
"github.com/gocraft/dbr"
)
const (
DefaultSelectLimit = 200
)
func GetLimit(n uint64) uint64 {
if n < 0 {
n = 0
}
if n > DefaultSelectLimit {
n = DefaultSelectLimit
}
return n
}
func GetOffset(n uint64) uint64 {
if n < 0 {
n = 0
}
return n
}
type InsertHook func(query *InsertQuery)
type UpdateHook func(query *UpdateQuery)
type DeleteHook func(query *DeleteQuery)
type Database struct {
*dbr.Session
InsertHook InsertHook
UpdateHook UpdateHook
DeleteHook DeleteHook
}
type SelectQuery struct {
*dbr.SelectBuilder
JoinCount int // for join filter
}
type InsertQuery struct {
*dbr.InsertBuilder
Hook InsertHook
}
type DeleteQuery struct {
*dbr.DeleteBuilder
Hook DeleteHook
}
type UpdateQuery struct {
*dbr.UpdateBuilder
Hook UpdateHook
}
type UpsertQuery struct {
table string
*dbr.Session
whereConds map[string]string
upsertValues map[string]interface{}
}
// SelectQuery
// Example: Select().From().Where().Limit().Offset().OrderDir().Load()
// Select().From().Where().Limit().Offset().OrderDir().LoadOne()
// Select().From().Where().Count()
// SelectAll().From().Where().Limit().Offset().OrderDir().Load()
// SelectAll().From().Where().Limit().Offset().OrderDir().LoadOne()
// SelectAll().From().Where().Count()
func (db *Database) Select(columns ...string) *SelectQuery {
return &SelectQuery{db.Session.Select(columns...), 0}
}
func (db *Database) SelectBySql(query string, value ...interface{}) *SelectQuery {
return &SelectQuery{db.Session.SelectBySql(query, value...), 0}
}
func (db *Database) SelectAll(columns ...string) *SelectQuery {
return &SelectQuery{db.Session.Select("*"), 0}
}
func (b *SelectQuery) Join(table, on interface{}) *SelectQuery {
b.SelectBuilder.Join(table, on)
return b
}
func (b *SelectQuery) JoinAs(table string, alias string, on interface{}) *SelectQuery {
b.SelectBuilder.Join(dbr.I(table).As(alias), on)
return b
}
func (b *SelectQuery) From(table string) *SelectQuery {
b.SelectBuilder.From(table)
return b
}
func (b *SelectQuery) Where(query interface{}, value ...interface{}) *SelectQuery {
b.SelectBuilder.Where(query, value...)
return b
}
func (b *SelectQuery) GroupBy(col ...string) *SelectQuery {
b.SelectBuilder.GroupBy(col...)
return b
}
func (b *SelectQuery) Distinct() *SelectQuery {
b.SelectBuilder.Distinct()
return b
}
func (b *SelectQuery) Limit(n uint64) *SelectQuery {
n = GetLimit(n)
b.SelectBuilder.Limit(n)
return b
}
func (b *SelectQuery) Offset(n uint64) *SelectQuery {
n = GetLimit(n)
b.SelectBuilder.Offset(n)
return b
}
func (b *SelectQuery) OrderDir(col string, isAsc bool) *SelectQuery {
b.SelectBuilder.OrderDir(col, isAsc)
return b
}
func (b *SelectQuery) Load(value interface{}) (int, error) {
return b.SelectBuilder.Load(value)
}
func (b *SelectQuery) LoadOne(value interface{}) error {
return b.SelectBuilder.LoadOne(value)
}
func getColumns(dbrColumns []interface{}) string {
var columns []string
for _, column := range dbrColumns {
if c, ok := column.(string); ok {
columns = append(columns, c)
}
}
return strings.Join(columns, ", ")
}
func (b *SelectQuery) Count() (count uint32, err error) {
// cache SelectStmt
selectStmt := b.SelectStmt
limit := selectStmt.LimitCount
offset := selectStmt.OffsetCount
column := selectStmt.Column
isDistinct := selectStmt.IsDistinct
order := selectStmt.Order
b.SelectStmt.LimitCount = -1
b.SelectStmt.OffsetCount = -1
b.SelectStmt.Column = []interface{}{"COUNT(*)"}
b.SelectStmt.Order = []dbr.Builder{}
if isDistinct {
b.SelectStmt.Column = []interface{}{fmt.Sprintf("COUNT(DISTINCT %s)", getColumns(column))}
b.SelectStmt.IsDistinct = false
}
err = b.LoadOne(&count)
// fallback SelectStmt
selectStmt.LimitCount = limit
selectStmt.OffsetCount = offset
selectStmt.Column = column
selectStmt.IsDistinct = isDistinct
selectStmt.Order = order
b.SelectStmt = selectStmt
return
}
// InsertQuery
// Example: InsertInto().Columns().Record().Exec()
func (db *Database) InsertInto(table string) *InsertQuery {
return &InsertQuery{db.Session.InsertInto(table), db.InsertHook}
}
func (b *InsertQuery) Exec() (sql.Result, error) {
result, err := b.InsertBuilder.Exec()
if b.Hook != nil && err == nil {
defer b.Hook(b)
}
return result, err
}
func (b *InsertQuery) Columns(columns ...string) *InsertQuery {
b.InsertBuilder.Columns(columns...)
return b
}
func (b *InsertQuery) Record(structValue interface{}) *InsertQuery {
b.InsertBuilder.Record(structValue)
return b
}
// DeleteQuery
// Example: DeleteFrom().Where().Limit().Exec()
func (db *Database) DeleteFrom(table string) *DeleteQuery {
return &DeleteQuery{db.Session.DeleteFrom(table), db.DeleteHook}
}
func (b *DeleteQuery) Where(query interface{}, value ...interface{}) *DeleteQuery {
b.DeleteBuilder.Where(query, value...)
return b
}
func (b *DeleteQuery) Limit(n uint64) *DeleteQuery {
b.DeleteBuilder.Limit(n)
return b
}
func (b *DeleteQuery) Exec() (sql.Result, error) {
result, err := b.DeleteBuilder.Exec()
if b.Hook != nil && err == nil {
defer b.Hook(b)
}
return result, err
}
// UpdateQuery
// Example: Update().Set().Where().Exec()
func (db *Database) Update(table string) *UpdateQuery {
return &UpdateQuery{db.Session.Update(table), db.UpdateHook}
}
func (b *UpdateQuery) Exec() (sql.Result, error) {
result, err := b.UpdateBuilder.Exec()
if b.Hook != nil && err == nil {
defer b.Hook(b)
}
return result, err
}
func (b *UpdateQuery) Set(column string, value interface{}) *UpdateQuery {
b.UpdateBuilder.Set(column, value)
return b
}
func (b *UpdateQuery) SetMap(m map[string]interface{}) *UpdateQuery {
b.UpdateBuilder.SetMap(m)
return b
}
func (b *UpdateQuery) Where(query interface{}, value ...interface{}) *UpdateQuery {
b.UpdateBuilder.Where(query, value...)
return b
}
func (b *UpdateQuery) Limit(n uint64) *UpdateQuery {
b.UpdateBuilder.Limit(n)
return b
}

View File

@@ -0,0 +1,31 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package mysql
import (
"github.com/gocraft/dbr"
)
// package errors
var (
ErrNotFound = dbr.ErrNotFound
ErrNotSupported = dbr.ErrNotSupported
ErrTableNotSpecified = dbr.ErrTableNotSpecified
ErrColumnNotSpecified = dbr.ErrColumnNotSpecified
ErrInvalidPointer = dbr.ErrInvalidPointer
ErrPlaceholderCount = dbr.ErrPlaceholderCount
ErrInvalidSliceLength = dbr.ErrInvalidSliceLength
ErrCantConvertToTime = dbr.ErrCantConvertToTime
ErrInvalidTimestring = dbr.ErrInvalidTimestring
)

View File

@@ -0,0 +1,55 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package mysql
import (
"github.com/golang/glog"
)
// EventReceiver is a sentinel EventReceiver; use it if the caller doesn't supply one
type EventReceiver struct{}
// Event receives a simple notification when various events occur
func (n *EventReceiver) Event(eventName string) {
}
// EventKv receives a notification when various events occur along with
// optional key/value data
func (n *EventReceiver) EventKv(eventName string, kvs map[string]string) {
}
// EventErr receives a notification of an error if one occurs
func (n *EventReceiver) EventErr(eventName string, err error) error {
return err
}
// EventErrKv receives a notification of an error if one occurs along with
// optional key/value data
func (n *EventReceiver) EventErrKv(eventName string, err error, kvs map[string]string) error {
glog.Errorf("%+v", err)
glog.Errorf("%s: %+v", eventName, kvs)
return err
}
// Timing receives the time an event took to happen
func (n *EventReceiver) Timing(eventName string, nanoseconds int64) {
}
// TimingKv receives the time an event took to happen along with optional key/value data
func (n *EventReceiver) TimingKv(eventName string, nanoseconds int64, kvs map[string]string) {
// TODO: Change logger level to debug
glog.Infof("%s spend %.2fms: %+v", eventName, float32(nanoseconds)/1000000, kvs)
}

View File

@@ -0,0 +1,82 @@
/*
Copyright 2018 The KubeSphere 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.
*/
package mysql
import (
"fmt"
"github.com/gocraft/dbr"
"k8s.io/klog"
)
type MySQLClient struct {
database *Database
}
func NewMySQLClient(options *MySQLOptions, stopCh <-chan struct{}) (*MySQLClient, error) {
var m MySQLClient
conn, err := dbr.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/devops?parseTime=1&multiStatements=1&charset=utf8mb4&collation=utf8mb4_unicode_ci", options.Username, options.Password, options.Host), nil)
if err != nil {
klog.Error("unable to connect to mysql", err)
return nil, err
}
conn.SetMaxIdleConns(options.MaxIdleConnections)
conn.SetConnMaxLifetime(options.MaxConnectionLifeTime)
conn.SetMaxOpenConns(options.MaxOpenConnections)
m.database = &Database{
Session: conn.NewSession(nil),
}
go func() {
<-stopCh
if err := conn.Close(); err != nil {
klog.Warning("error happened during closing mysql connection", err)
}
}()
return &m, nil
}
func NewMySQLClientOrDie(options *MySQLOptions, stopCh <-chan struct{}) *MySQLClient {
var m MySQLClient
conn, err := dbr.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/devops?parseTime=1&multiStatements=1&charset=utf8mb4&collation=utf8mb4_unicode_ci", options.Username, options.Password, options.Host), nil)
if err != nil {
klog.Error("unable to connect to mysql", err)
panic(err)
}
conn.SetMaxIdleConns(options.MaxIdleConnections)
conn.SetConnMaxLifetime(options.MaxConnectionLifeTime)
conn.SetMaxOpenConns(options.MaxOpenConnections)
m.database = &Database{
Session: conn.NewSession(nil),
}
go func() {
<-stopCh
if err := conn.Close(); err != nil {
klog.Warning("error happened during closing mysql connection", err)
}
}()
return &m
}
func (m *MySQLClient) Database() *Database {
return m.database
}

View File

@@ -0,0 +1,43 @@
package mysql
import (
"github.com/spf13/pflag"
reflectutils "kubesphere.io/kubesphere/pkg/utils/reflectutils"
"time"
)
type MySQLOptions struct {
Host string `json:"host,omitempty" yaml:"host,omitempty" description:"MySQL service host address"`
Username string `json:"username,omitempty" yaml:"username,omitempty"`
Password string `json:"-" yaml:"password,omitempty"`
MaxIdleConnections int `json:"maxIdleConnections,omitempty" yaml:"maxIdleConnections,omitempty"`
MaxOpenConnections int `json:"maxOpenConnections,omitempty" yaml:"maxOpenConnections,omitempty"`
MaxConnectionLifeTime time.Duration `json:"maxConnectionLifeTime,omitempty" yaml:"maxConnectionLifeTime,omitempty"`
}
// NewMySQLOptions create a `zero` value instance
func NewMySQLOptions() *MySQLOptions {
return &MySQLOptions{}
}
func (m *MySQLOptions) Validate() []error {
errors := []error{}
return errors
}
func (m *MySQLOptions) ApplyTo(options *MySQLOptions) {
reflectutils.Override(options, m)
}
func (m *MySQLOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&m.Host, "mysql-host", m.Host, ""+
"MySQL service host address. If left blank, following options will be ignored.")
fs.StringVar(&m.Username, "mysql-username", m.Username, ""+
"Username for access to mysql service.")
fs.StringVar(&m.Password, "mysql-password", m.Password, ""+
"Password for access to mysql, should be used pair with password.")
}

View File

@@ -25,7 +25,6 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
"time"
) )
const ( const (
@@ -35,86 +34,9 @@ const (
StateSuffix = "-StatefulSet" StateSuffix = "-StatefulSet"
) )
type Cluster struct { func (c *OpenPitrixClient) GetAppInfo(appId string) (string, string, string, error) {
ClusterID string `json:"cluster_id"` url := fmt.Sprintf("%s/v1/apps?app_id=%s", c.apiServer, appId)
Name string `json:"name"` resp, err := c.makeHttpRequest("GET", url, "")
AppID string `json:"app_id"`
VersionID string `json:"version_id"`
Status string `json:"status"`
UpdateTime time.Time `json:"status_time"`
CreateTime time.Time `json:"create_time"`
RunTimeId string `json:"runtime_id"`
Description string `json:"description"`
ClusterRoleSets []ClusterRole `json:"cluster_role_set"`
}
type ClusterRole struct {
ClusterID string `json:"cluster_id"`
Role string `json:"role"`
}
type ClusterList struct {
Total int `json:"total_count"`
Clusters []Cluster `json:"cluster_set"`
}
type VersionList struct {
Total int `json:"total_count"`
Versions []version `json:"app_version_set"`
}
type version struct {
Name string `json:"name"`
VersionID string `json:"version_id"`
}
type runtime struct {
RuntimeID string `json:"runtime_id"`
Zone string `json:"zone"`
}
type runtimeList struct {
Total int `json:"total_count"`
Runtimes []runtime `json:"runtime_set"`
}
type app struct {
AppId string `json:"app_id"`
Name string `json:"name"`
ChartName string `json:"chart_name"`
RepoId string `json:"repo_id"`
}
type repo struct {
RepoId string `json:"repo_id"`
Name string `json:"name"`
Url string `json:"url"`
}
type appList struct {
Total int `json:"total_count"`
Apps []app `json:"app_set"`
}
type repoList struct {
Total int `json:"total_count"`
Repos []repo `json:"repo_set"`
}
type CreateClusterRequest struct {
AppId string `json:"app_id" description:"ID of app to run in cluster, e.g. app-AA3A3y3zEgEM"`
VersionId string `json:"version_id" description:"app version, e.g. appv-154gXYx5RKRp"`
RuntimeId string `json:"runtime_id" description:"ID of runtime, e.g. runtime-wWwXL0LzWqEr"`
Conf string `json:"conf" description:"conf a json string, include cpu, memory info of cluster"`
}
type DeleteClusterRequest struct {
ClusterId []string `json:"cluster_id" description:"cluster ID"`
}
func GetAppInfo(appId string) (string, string, string, error) {
url := fmt.Sprintf("%s/v1/apps?app_id=%s", openpitrixAPIServer, appId)
resp, err := makeHttpRequest("GET", url, "")
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
return Unknown, Unknown, Unknown, err return Unknown, Unknown, Unknown, err
@@ -134,14 +56,10 @@ func GetAppInfo(appId string) (string, string, string, error) {
return apps.Apps[0].ChartName, apps.Apps[0].RepoId, apps.Apps[0].AppId, nil return apps.Apps[0].ChartName, apps.Apps[0].RepoId, apps.Apps[0].AppId, nil
} }
func GetCluster(clusterId string) (*Cluster, error) { func (c *OpenPitrixClient) GetCluster(clusterId string) (*Cluster, error) {
if strings.HasSuffix(openpitrixAPIServer, "/") { url := fmt.Sprintf("%s/v1/clusters?cluster_id=%s", c.apiServer, clusterId)
openpitrixAPIServer = strings.TrimSuffix(openpitrixAPIServer, "/")
}
url := fmt.Sprintf("%s/v1/clusters?cluster_id=%s", openpitrixAPIServer, clusterId) resp, err := c.makeHttpRequest("GET", url, "")
resp, err := makeHttpRequest("GET", url, "")
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
return nil, err return nil, err
@@ -162,14 +80,11 @@ func GetCluster(clusterId string) (*Cluster, error) {
return &clusterList.Clusters[0], nil return &clusterList.Clusters[0], nil
} }
func ListClusters(runtimeId, searchWord, status string, limit, offset int) (*ClusterList, error) { func (c *OpenPitrixClient) ListClusters(runtimeId, searchWord, status string, limit, offset int) (*ClusterList, error) {
if strings.HasSuffix(openpitrixAPIServer, "/") {
openpitrixAPIServer = strings.TrimSuffix(openpitrixAPIServer, "/")
}
defaultStatus := "status=active&status=stopped&status=pending&status=ceased" defaultStatus := "status=active&status=stopped&status=pending&status=ceased"
url := fmt.Sprintf("%s/v1/clusters?limit=%s&offset=%s", openpitrixAPIServer, strconv.Itoa(limit), strconv.Itoa(offset)) url := fmt.Sprintf("%s/v1/clusters?limit=%s&offset=%s", c.apiServer, strconv.Itoa(limit), strconv.Itoa(offset))
if searchWord != "" { if searchWord != "" {
url = fmt.Sprintf("%s&search_word=%s", url, searchWord) url = fmt.Sprintf("%s&search_word=%s", url, searchWord)
@@ -185,7 +100,7 @@ func ListClusters(runtimeId, searchWord, status string, limit, offset int) (*Clu
url = fmt.Sprintf("%s&runtime_id=%s", url, runtimeId) url = fmt.Sprintf("%s&runtime_id=%s", url, runtimeId)
} }
resp, err := makeHttpRequest("GET", url, "") resp, err := c.makeHttpRequest("GET", url, "")
if err != nil { if err != nil {
glog.Errorf("request %s failed, reason: %s", url, err) glog.Errorf("request %s failed, reason: %s", url, err)
return nil, err return nil, err
@@ -201,9 +116,9 @@ func ListClusters(runtimeId, searchWord, status string, limit, offset int) (*Clu
return &clusterList, nil return &clusterList, nil
} }
func GetRepo(repoId string) (string, error) { func (c *OpenPitrixClient) GetRepo(repoId string) (string, error) {
url := fmt.Sprintf("%s/v1/repos?repo_id=%s", openpitrixAPIServer, repoId) url := fmt.Sprintf("%s/v1/repos?repo_id=%s", c.apiServer, repoId)
resp, err := makeHttpRequest("GET", url, "") resp, err := c.makeHttpRequest("GET", url, "")
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
return Unknown, err return Unknown, err
@@ -223,9 +138,9 @@ func GetRepo(repoId string) (string, error) {
return repos.Repos[0].Name, nil return repos.Repos[0].Name, nil
} }
func GetVersion(versionId string) (string, error) { func (c *OpenPitrixClient) GetVersion(versionId string) (string, error) {
versionUrl := fmt.Sprintf("%s/v1/app_versions?version_id=%s", openpitrixAPIServer, versionId) versionUrl := fmt.Sprintf("%s/v1/app_versions?version_id=%s", c.apiServer, versionId)
resp, err := makeHttpRequest("GET", versionUrl, "") resp, err := c.makeHttpRequest("GET", versionUrl, "")
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
return Unknown, err return Unknown, err
@@ -244,10 +159,10 @@ func GetVersion(versionId string) (string, error) {
return versions.Versions[0].Name, nil return versions.Versions[0].Name, nil
} }
func GetRuntime(runtimeId string) (string, error) { func (c *OpenPitrixClient) GetRuntime(runtimeId string) (string, error) {
versionUrl := fmt.Sprintf("%s/v1/runtimes?runtime_id=%s", openpitrixAPIServer, runtimeId) versionUrl := fmt.Sprintf("%s/v1/runtimes?runtime_id=%s", c.apiServer, runtimeId)
resp, err := makeHttpRequest("GET", versionUrl, "") resp, err := c.makeHttpRequest("GET", versionUrl, "")
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
return Unknown, err return Unknown, err
@@ -267,9 +182,9 @@ func GetRuntime(runtimeId string) (string, error) {
return runtimes.Runtimes[0].Zone, nil return runtimes.Runtimes[0].Zone, nil
} }
func CreateCluster(request CreateClusterRequest) error { func (c *OpenPitrixClient) CreateCluster(request CreateClusterRequest) error {
versionUrl := fmt.Sprintf("%s/v1/clusters/create", openpitrixAPIServer) versionUrl := fmt.Sprintf("%s/v1/clusters/create", c.apiServer)
data, err := json.Marshal(request) data, err := json.Marshal(request)
@@ -278,7 +193,7 @@ func CreateCluster(request CreateClusterRequest) error {
return err return err
} }
data, err = makeHttpRequest("POST", versionUrl, string(data)) data, err = c.makeHttpRequest("POST", versionUrl, string(data))
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
@@ -288,9 +203,9 @@ func CreateCluster(request CreateClusterRequest) error {
return nil return nil
} }
func DeleteCluster(request DeleteClusterRequest) error { func (c *OpenPitrixClient) DeleteCluster(request DeleteClusterRequest) error {
versionUrl := fmt.Sprintf("%s/v1/clusters/delete", openpitrixAPIServer) versionUrl := fmt.Sprintf("%s/v1/clusters/delete", c.apiServer)
data, err := json.Marshal(request) data, err := json.Marshal(request)
@@ -299,7 +214,7 @@ func DeleteCluster(request DeleteClusterRequest) error {
return err return err
} }
data, err = makeHttpRequest("POST", versionUrl, string(data)) data, err = c.makeHttpRequest("POST", versionUrl, string(data))
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
@@ -309,7 +224,7 @@ func DeleteCluster(request DeleteClusterRequest) error {
return nil return nil
} }
func makeHttpRequest(method, url, data string) ([]byte, error) { func (c *OpenPitrixClient) makeHttpRequest(method, url, data string) ([]byte, error) {
var req *http.Request var req *http.Request
var err error var err error
@@ -319,7 +234,7 @@ func makeHttpRequest(method, url, data string) ([]byte, error) {
req, err = http.NewRequest(method, url, strings.NewReader(data)) req, err = http.NewRequest(method, url, strings.NewReader(data))
} }
req.Header.Add("Authorization", openpitrixProxyToken) req.Header.Add("Authorization", c.token)
if err != nil { if err != nil {
glog.Error(err) glog.Error(err)
@@ -329,7 +244,7 @@ func makeHttpRequest(method, url, data string) ([]byte, error) {
resp, err := http.DefaultClient.Do(req) resp, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {
err := fmt.Errorf("Request to %s failed, method: %s,token: %s, reason: %s ", url, method, openpitrixProxyToken, err) err := fmt.Errorf("Request to %s failed, method: %s,token: %s, reason: %s ", url, method, c.apiServer, err)
glog.Error(err) glog.Error(err)
return nil, err return nil, err
} }

View File

@@ -20,105 +20,64 @@ package openpitrix
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"flag"
"fmt" "fmt"
"github.com/golang/glog"
"io/ioutil" "io/ioutil"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"net/http" "net/http"
"strings" "strings"
"sync" "time"
) )
var ( func NewOpenPitrixClient(options *OpenPitrixOptions) (*OpenPitrixClient, error) {
openpitrixAPIServer string return &OpenPitrixClient{
openpitrixProxyToken string client: &http.Client{
once sync.Once Timeout: time.Duration(3) * time.Second,
c client },
) apiServer: options.APIServer,
token: options.Token,
type RunTime struct { }, nil
RuntimeId string `json:"runtime_id"`
RuntimeUrl string `json:"runtime_url"`
Name string `json:"name"`
Provider string `json:"provider"`
Zone string `json:"zone"`
RuntimeCredential string `json:"runtime_credential"`
} }
type Interface interface { func (c *OpenPitrixClient) CreateRuntime(runtime *RunTime) error {
CreateRuntime(runtime *RunTime) error
DeleteRuntime(runtimeId string) error
}
type cluster struct {
Status string `json:"status"`
ClusterId string `json:"cluster_id"`
}
type Error struct {
status int
message string
}
func (e Error) Error() string {
return fmt.Sprintf("status: %d,message: %s", e.status, e.message)
}
type client struct {
client http.Client
}
func init() {
flag.StringVar(&openpitrixAPIServer, "openpitrix-api-server", "http://openpitrix-api-gateway.openpitrix-system.svc:9100", "openpitrix api server")
flag.StringVar(&openpitrixProxyToken, "openpitrix-proxy-token", "", "openpitrix proxy token")
}
func Client() Interface {
once.Do(func() {
c = client{client: http.Client{}}
})
return c
}
func (c client) CreateRuntime(runtime *RunTime) error {
data, err := json.Marshal(runtime) data, err := json.Marshal(runtime)
if err != nil { if err != nil {
return err return err
} }
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/runtimes", openpitrixAPIServer), bytes.NewReader(data)) req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/runtimes", c.apiServer), bytes.NewReader(data))
if err != nil { if err != nil {
return err return err
} }
req.Header.Add("Content-Type", "application/json") req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", openpitrixProxyToken) req.Header.Add("Authorization", c.token)
resp, err := c.client.Do(req) resp, err := c.client.Do(req)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
data, err = ioutil.ReadAll(resp.Body) data, err = ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return err return err
} }
if resp.StatusCode > http.StatusOK { if resp.StatusCode > http.StatusOK {
err = Error{resp.StatusCode, string(data)} err = Error{resp.StatusCode, string(data)}
glog.Error(err) klog.Error(err)
return err return err
} }
return nil return nil
} }
func (c client) deleteClusters(clusters []cluster) error { func (c *OpenPitrixClient) deleteClusters(clusters []cluster) error {
clusterId := make([]string, 0) clusterId := make([]string, 0)
for _, cluster := range clusters { for _, cluster := range clusters {
@@ -137,16 +96,16 @@ func (c client) deleteClusters(clusters []cluster) error {
ClusterId: clusterId, ClusterId: clusterId,
} }
data, _ := json.Marshal(deleteRequest) data, _ := json.Marshal(deleteRequest)
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/clusters/delete", openpitrixAPIServer), bytes.NewReader(data)) req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/clusters/delete", c.apiServer), bytes.NewReader(data))
if err != nil { if err != nil {
return err return err
} }
req.Header.Add("Authorization", openpitrixProxyToken) req.Header.Add("Authorization", c.token)
resp, err := c.client.Do(req) resp, err := c.client.Do(req)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return err return err
} }
@@ -154,44 +113,44 @@ func (c client) deleteClusters(clusters []cluster) error {
data, err = ioutil.ReadAll(resp.Body) data, err = ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return err return err
} }
if resp.StatusCode > http.StatusOK { if resp.StatusCode > http.StatusOK {
err = Error{resp.StatusCode, string(data)} err = Error{resp.StatusCode, string(data)}
glog.Error(err) klog.Error(err)
return err return err
} }
return nil return nil
} }
func (c client) listClusters(runtimeId string) ([]cluster, error) { func (c *OpenPitrixClient) listClusters(runtimeId string) ([]cluster, error) {
limit := 200 limit := 200
offset := 0 offset := 0
clusters := make([]cluster, 0) clusters := make([]cluster, 0)
for { for {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v1/clusters?runtime_id=%s&limit=%d&offset=%d", openpitrixAPIServer, runtimeId, limit, offset), nil) req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v1/clusters?runtime_id=%s&limit=%d&offset=%d", c.apiServer, runtimeId, limit, offset), nil)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
req.Header.Add("Authorization", openpitrixProxyToken) req.Header.Add("Authorization", c.token)
resp, err := c.client.Do(req) resp, err := c.client.Do(req)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
data, err := ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
@@ -199,7 +158,7 @@ func (c client) listClusters(runtimeId string) ([]cluster, error) {
if resp.StatusCode > http.StatusOK { if resp.StatusCode > http.StatusOK {
err = Error{resp.StatusCode, string(data)} err = Error{resp.StatusCode, string(data)}
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
listClusterResponse := struct { listClusterResponse := struct {
@@ -209,7 +168,7 @@ func (c client) listClusters(runtimeId string) ([]cluster, error) {
err = json.Unmarshal(data, &listClusterResponse) err = json.Unmarshal(data, &listClusterResponse)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
@@ -225,18 +184,18 @@ func (c client) listClusters(runtimeId string) ([]cluster, error) {
return clusters, nil return clusters, nil
} }
func (c client) DeleteRuntime(runtimeId string) error { func (c *OpenPitrixClient) DeleteRuntime(runtimeId string) error {
clusters, err := c.listClusters(runtimeId) clusters, err := c.listClusters(runtimeId)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return err return err
} }
err = c.deleteClusters(clusters) err = c.deleteClusters(clusters)
if err != nil { if err != nil {
glog.Error(err) klog.Error(err)
return err return err
} }

View File

@@ -0,0 +1,43 @@
package openpitrix
import (
"fmt"
"github.com/spf13/pflag"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
)
type OpenPitrixOptions struct {
APIServer string `json:"apiServer,omitempty" yaml:"apiServer,omitempty"`
Token string `json:"token,omitempty" yaml:"token,omitempty"`
}
func NewOpenPitrixOptions() *OpenPitrixOptions {
return &OpenPitrixOptions{
APIServer: "",
Token: "",
}
}
func (s *OpenPitrixOptions) ApplyTo(options *OpenPitrixOptions) {
reflectutils.Override(s, options)
}
func (s *OpenPitrixOptions) Validate() []error {
errs := []error{}
if s.APIServer != "" {
if s.Token == "" {
errs = append(errs, fmt.Errorf("OpenPitrix access token cannot be empty"))
}
}
return errs
}
func (s *OpenPitrixOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.APIServer, "openpitrix-apiserver", s.APIServer, ""+
"OpenPitrix api gateway endpoint, if left blank, following options will be ignored.")
fs.StringVar(&s.Token, "openpitrix-token", s.Token, ""+
"OpenPitrix api access token.")
}

View File

@@ -0,0 +1,117 @@
package openpitrix
import (
"fmt"
"net/http"
"time"
)
type Cluster struct {
ClusterID string `json:"cluster_id"`
Name string `json:"name"`
AppID string `json:"app_id"`
VersionID string `json:"version_id"`
Status string `json:"status"`
UpdateTime time.Time `json:"status_time"`
CreateTime time.Time `json:"create_time"`
RunTimeId string `json:"runtime_id"`
Description string `json:"description"`
ClusterRoleSets []ClusterRole `json:"cluster_role_set"`
}
type ClusterRole struct {
ClusterID string `json:"cluster_id"`
Role string `json:"role"`
}
type ClusterList struct {
Total int `json:"total_count"`
Clusters []Cluster `json:"cluster_set"`
}
type VersionList struct {
Total int `json:"total_count"`
Versions []version `json:"app_version_set"`
}
type version struct {
Name string `json:"name"`
VersionID string `json:"version_id"`
}
type runtime struct {
RuntimeID string `json:"runtime_id"`
Zone string `json:"zone"`
}
type runtimeList struct {
Total int `json:"total_count"`
Runtimes []runtime `json:"runtime_set"`
}
type app struct {
AppId string `json:"app_id"`
Name string `json:"name"`
ChartName string `json:"chart_name"`
RepoId string `json:"repo_id"`
}
type repo struct {
RepoId string `json:"repo_id"`
Name string `json:"name"`
Url string `json:"url"`
}
type appList struct {
Total int `json:"total_count"`
Apps []app `json:"app_set"`
}
type repoList struct {
Total int `json:"total_count"`
Repos []repo `json:"repo_set"`
}
type CreateClusterRequest struct {
AppId string `json:"app_id" description:"ID of app to run in cluster, e.g. app-AA3A3y3zEgEM"`
VersionId string `json:"version_id" description:"app version, e.g. appv-154gXYx5RKRp"`
RuntimeId string `json:"runtime_id" description:"ID of runtime, e.g. runtime-wWwXL0LzWqEr"`
Conf string `json:"conf" description:"conf a json string, include cpu, memory info of cluster"`
}
type DeleteClusterRequest struct {
ClusterId []string `json:"cluster_id" description:"cluster ID"`
}
type RunTime struct {
RuntimeId string `json:"runtime_id"`
RuntimeUrl string `json:"runtime_url"`
Name string `json:"name"`
Provider string `json:"provider"`
Zone string `json:"zone"`
RuntimeCredential string `json:"runtime_credential"`
}
type Interface interface {
CreateRuntime(runtime *RunTime) error
DeleteRuntime(runtimeId string) error
}
type cluster struct {
Status string `json:"status"`
ClusterId string `json:"cluster_id"`
}
type Error struct {
status int
message string
}
func (e Error) Error() string {
return fmt.Sprintf("status: %d,message: %s", e.status, e.message)
}
type OpenPitrixClient struct {
client *http.Client
apiServer string
token string
}

View File

@@ -0,0 +1,37 @@
package prometheus
import (
"github.com/spf13/pflag"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
)
type PrometheusOptions struct {
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
SecondaryEndpoint string `json:"secondaryEndpoint,omitempty" yaml:"secondaryEndpoint,omitempty"`
}
func NewPrometheusOptions() *PrometheusOptions {
return &PrometheusOptions{
Endpoint: "",
SecondaryEndpoint: "",
}
}
func (s *PrometheusOptions) Validate() []error {
errs := []error{}
return errs
}
func (s *PrometheusOptions) ApplyTo(options *PrometheusOptions) {
reflectutils.Override(s, options)
}
func (s *PrometheusOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.Endpoint, "prometheus-endpoint", s.Endpoint, ""+
"Prometheus service endpoint which stores KubeSphere monitoring data, if left "+
"blank, will use builtin metrics-server as data source.")
fs.StringVar(&s.SecondaryEndpoint, "prometheus-secondary-endpoint", s.SecondaryEndpoint, ""+
"Prometheus secondary service endpoint, if left empty and endpoint is set, will use endpoint instead.")
}

View File

@@ -0,0 +1,67 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package prometheus
import (
"github.com/golang/glog"
"io/ioutil"
"net/http"
"time"
)
type PrometheusClient struct {
client *http.Client
endpoint string
secondaryEndpoint string
}
func NewPrometheusClient(options *PrometheusOptions) (*PrometheusClient, error) {
return &PrometheusClient{
client: &http.Client{
Timeout: time.Duration(3) * time.Second,
},
endpoint: options.Endpoint,
secondaryEndpoint: options.SecondaryEndpoint,
}, nil
}
func (c *PrometheusClient) SendMonitoringRequest(queryType string, params string) string {
return c.sendMonitoringRequest(c.endpoint, queryType, params)
}
func (c *PrometheusClient) SendSecondaryMonitoringRequest(queryType string, params string) string {
return c.sendMonitoringRequest(c.secondaryEndpoint, queryType, params)
}
func (c *PrometheusClient) sendMonitoringRequest(endpoint string, queryType string, params string) string {
epurl := endpoint + queryType + params
response, err := c.client.Get(epurl)
if err != nil {
glog.Error(err)
} else {
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
glog.Error(err)
}
return string(contents)
}
return ""
}

View File

@@ -1,203 +0,0 @@
/*
Copyright 2019 The KubeSphere 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.
*/
package prometheus
import (
"flag"
"io/ioutil"
"kubesphere.io/kubesphere/pkg/informers"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/emicklei/go-restful"
"github.com/golang/glog"
)
const (
DefaultQueryStep = "10m"
DefaultQueryTimeout = "10s"
RangeQueryType = "query_range?"
DefaultQueryType = "query?"
)
// Kubesphere sets up two Prometheus servers to balance monitoring workloads
var (
PrometheusEndpoint string // For monitoring node, namespace, pod ... level resources
SecondaryPrometheusEndpoint string // For monitoring components including etcd, apiserver, coredns, etc.
)
func init() {
flag.StringVar(&PrometheusEndpoint, "prometheus-endpoint", "http://prometheus-k8s.kubesphere-monitoring-system.svc:9090/api/v1/", "For physical and k8s resource monitoring, including node, namespace, pod, etc.")
flag.StringVar(&SecondaryPrometheusEndpoint, "secondary-prometheus-endpoint", "http://prometheus-k8s-system.kubesphere-monitoring-system.svc:9090/api/v1/", "For k8s component monitoring, including etcd, apiserver, coredns, etc.")
}
type MonitoringRequestParams struct {
Params url.Values
QueryType string
SortMetricName string
SortType string
PageNum string
LimitNum string
Tp string
MetricsFilter string
ResourcesFilter string
MetricsName string
WorkloadName string
NodeId string
WsName string
NsName string
PodName string
PVCName string
StorageClassName string
ContainerName string
WorkloadKind string
ComponentName string
}
var client = &http.Client{}
func SendMonitoringRequest(prometheusEndpoint string, queryType string, params string) string {
epurl := prometheusEndpoint + queryType + params
response, err := client.Get(epurl)
if err != nil {
glog.Error(err)
} else {
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
glog.Error(err)
}
return string(contents)
}
return ""
}
func ParseMonitoringRequestParams(request *restful.Request) *MonitoringRequestParams {
instantTime := strings.Trim(request.QueryParameter("time"), " ")
start := strings.Trim(request.QueryParameter("start"), " ")
end := strings.Trim(request.QueryParameter("end"), " ")
step := strings.Trim(request.QueryParameter("step"), " ")
timeout := strings.Trim(request.QueryParameter("timeout"), " ")
sortMetricName := strings.Trim(request.QueryParameter("sort_metric"), " ")
sortType := strings.Trim(request.QueryParameter("sort_type"), " ")
pageNum := strings.Trim(request.QueryParameter("page"), " ")
limitNum := strings.Trim(request.QueryParameter("limit"), " ")
tp := strings.Trim(request.QueryParameter("type"), " ")
metricsFilter := strings.Trim(request.QueryParameter("metrics_filter"), " ")
resourcesFilter := strings.Trim(request.QueryParameter("resources_filter"), " ")
metricsName := strings.Trim(request.QueryParameter("metrics_name"), " ")
workloadName := strings.Trim(request.PathParameter("workload"), " ")
nodeId := strings.Trim(request.PathParameter("node"), " ")
wsName := strings.Trim(request.PathParameter("workspace"), " ")
nsName := strings.Trim(request.PathParameter("namespace"), " ")
podName := strings.Trim(request.PathParameter("pod"), " ")
pvcName := strings.Trim(request.PathParameter("pvc"), " ")
storageClassName := strings.Trim(request.PathParameter("storageclass"), " ")
containerName := strings.Trim(request.PathParameter("container"), " ")
workloadKind := strings.Trim(request.PathParameter("kind"), " ")
componentName := strings.Trim(request.PathParameter("component"), " ")
var requestParams = MonitoringRequestParams{
SortMetricName: sortMetricName,
SortType: sortType,
PageNum: pageNum,
LimitNum: limitNum,
Tp: tp,
MetricsFilter: metricsFilter,
ResourcesFilter: resourcesFilter,
MetricsName: metricsName,
WorkloadName: workloadName,
NodeId: nodeId,
WsName: wsName,
NsName: nsName,
PodName: podName,
PVCName: pvcName,
StorageClassName: storageClassName,
ContainerName: containerName,
WorkloadKind: workloadKind,
ComponentName: componentName,
}
if timeout == "" {
timeout = DefaultQueryTimeout
}
if step == "" {
step = DefaultQueryStep
}
// Whether query or query_range request
u := url.Values{}
if start != "" && end != "" {
u.Set("start", convertTimeGranularity(start))
u.Set("end", convertTimeGranularity(end))
u.Set("step", step)
u.Set("timeout", timeout)
// range query start time must be greater than the namespace creation time
if nsName != "" {
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
ns, err := nsLister.Get(nsName)
if err == nil {
queryStartTime := u.Get("start")
nsCreationTime := strconv.FormatInt(ns.CreationTimestamp.Unix(), 10)
if nsCreationTime > queryStartTime {
u.Set("start", nsCreationTime)
}
}
}
requestParams.QueryType = RangeQueryType
requestParams.Params = u
return &requestParams
}
if instantTime != "" {
u.Set("time", instantTime)
u.Set("timeout", timeout)
requestParams.QueryType = DefaultQueryType
requestParams.Params = u
return &requestParams
} else {
u.Set("timeout", timeout)
requestParams.QueryType = DefaultQueryType
requestParams.Params = u
return &requestParams
}
}
func convertTimeGranularity(ts string) string {
timeFloat, err := strconv.ParseFloat(ts, 64)
if err != nil {
glog.Errorf("convert second timestamp %s to minute timestamp failed", ts)
return strconv.FormatInt(int64(time.Now().Unix()), 10)
}
timeInt := int64(timeFloat)
// convert second timestamp to minute timestamp
secondTime := time.Unix(timeInt, 0).Truncate(time.Minute).Unix()
return strconv.FormatInt(secondTime, 10)
}

View File

@@ -0,0 +1,57 @@
package redis
import (
"fmt"
"github.com/spf13/pflag"
"kubesphere.io/kubesphere/pkg/utils/net"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
)
type RedisOptions struct {
Host string
Port int
Password string
DB int
}
// NewRedisOptions returns options points to nowhere,
// because redis is not required for some components
func NewRedisOptions() *RedisOptions {
return &RedisOptions{
Host: "",
Port: 6379,
Password: "",
DB: 0,
}
}
func (r *RedisOptions) Validate() []error {
errors := make([]error, 0)
if r.Host != "" {
if !net.IsValidPort(r.Port) {
errors = append(errors, fmt.Errorf("--redis-port is out of range"))
}
}
return errors
}
func (r *RedisOptions) ApplyTo(options *RedisOptions) {
reflectutils.Override(options, r)
}
func (r *RedisOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&r.Host, "--redis-host", r.Host, ""+
"Redis service host address. If left blank, means redis is unnecessary, "+
"redis will be disabled")
fs.IntVar(&r.Port, "--redis-port", r.Port, ""+
"Redis service port number.")
fs.StringVar(&r.Password, "--redis-password", r.Password, ""+
"Redis service password if necessary, default to empty")
fs.IntVar(&r.DB, "--redis-db", r.DB, ""+
"Redis service database index, default to 0.")
}

View File

@@ -18,48 +18,49 @@
package redis package redis
import ( import (
"flag" "fmt"
"log"
"os"
"os/signal"
"sync"
"syscall"
"github.com/go-redis/redis" "github.com/go-redis/redis"
"k8s.io/klog"
) )
var ( type RedisClient struct {
redisHost string client *redis.Client
redisPassword string
redisDB int
redisClientOnce sync.Once
redisClient *redis.Client
)
func init() {
flag.StringVar(&redisHost, "redis-server", "localhost:6379", "redis server host")
flag.StringVar(&redisPassword, "redis-password", "", "redis password")
flag.IntVar(&redisDB, "redis-db", 0, "redis db")
} }
func Client() *redis.Client { func NewRedisClientOrDie(options *RedisOptions, stopCh <-chan struct{}) *RedisClient {
client, err := NewRedisClient(options, stopCh)
if err != nil {
panic(err)
}
redisClientOnce.Do(func() { return client
redisClient = redis.NewClient(&redis.Options{ }
Addr: redisHost,
Password: redisPassword, func NewRedisClient(option *RedisOptions, stopCh <-chan struct{}) (*RedisClient, error) {
DB: redisDB, var r RedisClient
})
if err := redisClient.Ping().Err(); err != nil { r.client = redis.NewClient(&redis.Options{
log.Fatalln(err) Addr: fmt.Sprintf("%s:%d", option.Host, option.Port),
} Password: option.Password,
c := make(chan os.Signal, 0) DB: option.DB,
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
redisClient.Close()
}()
}) })
return redisClient if err := r.client.Ping().Err(); err != nil {
klog.Error("unable to reach redis host", err)
r.client.Close()
return nil, err
}
go func() {
<-stopCh
if err := r.client.Close(); err != nil {
klog.Error(err)
}
}()
return &r, nil
}
func (r *RedisClient) Redis() *redis.Client {
return r.client
} }

View File

@@ -0,0 +1,61 @@
package s2is3
import (
"github.com/spf13/pflag"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
)
type S3Options struct {
Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"`
Region string `json:"region,omitempty" yaml:"region,omitempty"`
DisableSSL bool `json:"disableSSL,omitempty" yaml:"disableSSL,omitempty"`
ForcePathStyle bool `json:"forcePathStyle,omitempty" yaml:"forePathStyle,omitempty"`
AccessKeyID string `json:"accessKeyID,omitempty" yaml:"accessKeyID,omitempty"`
SecretAccessKey string `json:"secretAccessKey,omitempty" yaml:"secretAccessKey,omitempty"`
SessionToken string `json:"sessionToken,omitempty" yaml:"sessionToken,omitempty"`
Bucket string `json:"bucket,omitempty" yaml:"bucket,omitempty"`
}
func NewS3Options() *S3Options {
return &S3Options{
Endpoint: "",
Region: "",
DisableSSL: true,
ForcePathStyle: true,
AccessKeyID: "",
SecretAccessKey: "",
SessionToken: "",
Bucket: "",
}
}
func (s *S3Options) Validate() []error {
errors := []error{}
return errors
}
func (s *S3Options) ApplyTo(options *S3Options) {
reflectutils.Override(options, s)
}
func (s *S3Options) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.Endpoint, "s3-endpoint", s.Endpoint, ""+
"Endpoint to access to s3 object storage service, if left blank, the following options "+
"will be ignored.")
fs.StringVar(&s.Region, "s3-region", s.Region, ""+
"Region of s3 that will access to, like us-east-1.")
fs.StringVar(&s.AccessKeyID, "s3-access-key-id", "AKIAIOSFODNN7EXAMPLE", "access key of s2i s3")
fs.StringVar(&s.SecretAccessKey, "s3-secret-access-key", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "secret access key of s2i s3")
fs.StringVar(&s.SessionToken, "s3-session-token", s.SessionToken, "session token of s2i s3")
fs.StringVar(&s.Bucket, "s3-bucket", "s2i-binaries", "bucket name of s2i s3")
fs.BoolVar(&s.DisableSSL, "s3-disable-SSL", s.DisableSSL, "disable ssl")
fs.BoolVar(&s.ForcePathStyle, "s3-force-path-style", true, "force path style")
}

View File

@@ -1,83 +1,79 @@
package s2is3 package s2is3
import ( import (
"flag"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3"
"k8s.io/klog" "k8s.io/klog"
"sync"
) )
var ( type S3Client struct {
s3Region string s3Client *s3.S3
s3Endpoint string s3Session *session.Session
s3DisableSSL bool bucket string
s3ForcePathStyle bool
s3AccessKeyID string
s3SecretAccessKey string
s3SessionToken string
s3Bucket string
)
var (
s2iS3 *s3.S3
s2iS3Session *session.Session
sessionInitMutex sync.Mutex
clientInitMutex sync.Mutex
)
func init() {
flag.StringVar(&s3Region, "s2i-s3-region", "us-east-1", "region of s2i s3")
flag.StringVar(&s3Endpoint, "s2i-s3-endpoint", "http://ks-minio.kubesphere-system.svc", "endpoint of s2i s3")
flag.StringVar(&s3AccessKeyID, "s2i-s3-access-key-id", "AKIAIOSFODNN7EXAMPLE", "access key of s2i s3")
flag.StringVar(&s3SecretAccessKey, "s2i-s3-secret-access-key", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "secret access key of s2i s3")
flag.StringVar(&s3SessionToken, "s2i-s3-session-token", "", "session token of s2i s3")
flag.StringVar(&s3Bucket, "s2i-s3-bucket", "s2i-binaries", "bucket name of s2i s3")
flag.BoolVar(&s3DisableSSL, "s2i-s3-disable-SSL", true, "disable ssl")
flag.BoolVar(&s3ForcePathStyle, "s2i-s3-force-path-style", true, "force path style")
} }
func Client() *s3.S3 { func NewS3Client(options *S3Options) (*S3Client, error) {
if s2iS3 != nil { cred := credentials.NewStaticCredentials(options.AccessKeyID, options.SecretAccessKey, options.SessionToken)
return s2iS3
config := aws.Config{
Region: aws.String(options.Region),
Endpoint: aws.String(options.Endpoint),
DisableSSL: aws.Bool(options.DisableSSL),
S3ForcePathStyle: aws.Bool(options.ForcePathStyle),
Credentials: cred,
} }
clientInitMutex.Lock()
defer clientInitMutex.Unlock() s, err := session.NewSession(&config)
if s2iS3Session == nil {
if sess := Session(); sess != nil {
klog.Error("failed to connect to s2i s3")
return nil
}
}
s2iS3 = s3.New(s2iS3Session)
return s2iS3
}
func Session() *session.Session {
if s2iS3Session != nil {
return s2iS3Session
}
sessionInitMutex.Lock()
defer sessionInitMutex.Unlock()
creds := credentials.NewStaticCredentials(
s3AccessKeyID, s3SecretAccessKey, s3SessionToken,
)
config := &aws.Config{
Region: aws.String(s3Region),
Endpoint: aws.String(s3Endpoint),
DisableSSL: aws.Bool(s3DisableSSL),
S3ForcePathStyle: aws.Bool(s3ForcePathStyle),
Credentials: creds,
}
sess, err := session.NewSession(config)
if err != nil { if err != nil {
klog.Errorf("failed to connect to s2i s3: %+v", err) klog.Error(err)
return nil return nil, err
} }
s2iS3Session = sess
return s2iS3Session var c S3Client
c.s3Client = s3.New(s)
c.s3Session = s
c.bucket = options.Bucket
return &c, nil
} }
func Bucket() *string { // NewS3ClientOrDie creates S3Client and panics if there is an error
return aws.String(s3Bucket) func NewS3ClientOrDie(options *S3Options) *S3Client {
cred := credentials.NewStaticCredentials(options.AccessKeyID, options.SecretAccessKey, options.SessionToken)
config := aws.Config{
Region: aws.String(options.Region),
Endpoint: aws.String(options.Endpoint),
DisableSSL: aws.Bool(options.DisableSSL),
S3ForcePathStyle: aws.Bool(options.ForcePathStyle),
Credentials: cred,
}
s, err := session.NewSession(&config)
if err != nil {
panic(err)
}
client := s3.New(s)
return &S3Client{
s3Client: client,
s3Session: s,
bucket: options.Bucket,
}
}
func (s *S3Client) Client() *s3.S3 {
return s.s3Client
}
func (s *S3Client) Session() *session.Session {
return s.s3Session
}
func (s *S3Client) Bucket() *string {
return aws.String(s.bucket)
} }

View File

@@ -0,0 +1,59 @@
package servicemesh
import "github.com/spf13/pflag"
type ServiceMeshOptions struct {
// istio pilot discovery service url
IstioPilotHost string `json:"istioPilotHost,omitempty" yaml:"istioPilotHost,omitempty"`
// jaeger query service url
JaegerQueryHost string `json:"jaegerQueryHost,omitempty" yaml:"jaegerQueryHost,omitempty"`
// prometheus service url for servicemesh metrics
ServicemeshPrometheusHost string `json:"servicemeshPrometheusHost,omitempty" yaml:"servicemeshPrometheusHost,omitempty"`
}
// NewServiceMeshOptions returns a `zero` instance
func NewServiceMeshOptions() *ServiceMeshOptions {
return &ServiceMeshOptions{
IstioPilotHost: "",
JaegerQueryHost: "",
ServicemeshPrometheusHost: "",
}
}
func (s *ServiceMeshOptions) Validate() []error {
errors := []error{}
return errors
}
func (s *ServiceMeshOptions) ApplyTo(options *ServiceMeshOptions) {
if options == nil {
return
}
if s.ServicemeshPrometheusHost != "" {
options.ServicemeshPrometheusHost = s.ServicemeshPrometheusHost
}
if s.JaegerQueryHost != "" {
options.JaegerQueryHost = s.JaegerQueryHost
}
if s.IstioPilotHost != "" {
options.IstioPilotHost = s.IstioPilotHost
}
}
func (s *ServiceMeshOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.IstioPilotHost, "istio-pilot-host", s.IstioPilotHost, ""+
"istio pilot discovery service url")
fs.StringVar(&s.JaegerQueryHost, "jaeger-query-host", s.JaegerQueryHost, ""+
"jaeger query service url")
fs.StringVar(&s.ServicemeshPrometheusHost, "servicemesh-prometheus-host", s.ServicemeshPrometheusHost, ""+
"prometheus service for servicemesh")
}

View File

@@ -0,0 +1,49 @@
package sonarqube
import (
"github.com/spf13/pflag"
)
type SonarQubeOptions struct {
Host string `json:",omitempty" yaml:",omitempty" description:"SonarQube service host address"`
Token string `json:",omitempty" yaml:",omitempty" description:"SonarQube service token"`
}
func NewSonarQubeOptions() *SonarQubeOptions {
return &SonarQubeOptions{
Host: "",
Token: "",
}
}
func NewDefaultSonarQubeOptions() *SonarQubeOptions {
return NewSonarQubeOptions()
}
func (s *SonarQubeOptions) Validate() []error {
errors := []error{}
return errors
}
func (s *SonarQubeOptions) ApplyTo(options *SonarQubeOptions) {
if options == nil {
return
}
if s.Host != "" {
options.Host = s.Host
}
if s.Token != "" {
options.Token = s.Token
}
}
func (s *SonarQubeOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.Host, "sonarqube-host", s.Host, ""+
"Sonarqube service address if enabled.")
fs.StringVar(&s.Token, "sonarqube-token", s.Token, ""+
"Sonarqube service access token.")
}

View File

@@ -1,49 +0,0 @@
package sonarqube
import (
"flag"
"github.com/golang/glog"
"github.com/kubesphere/sonargo/sonar"
"strings"
"sync"
)
var (
sonarAddress string
sonarToken string
sonarOnce sync.Once
sonarClient *sonargo.Client
)
func init() {
flag.StringVar(&sonarAddress, "sonar-address", "", "sonar server host")
flag.StringVar(&sonarToken, "sonar-token", "", "sonar token")
}
func Client() *sonargo.Client {
sonarOnce.Do(func() {
if sonarAddress == "" {
sonarClient = nil
glog.Info("skip sonar init")
return
}
if !strings.HasSuffix(sonarAddress, "/") {
sonarAddress += "/"
}
client, err := sonargo.NewClientWithToken(sonarAddress+"api/", sonarToken)
if err != nil {
glog.Error("failed to connect to sonar")
return
}
_, _, err = client.Projects.Search(nil)
if err != nil {
glog.Errorf("failed to search sonar projects [%+v]", err)
return
}
glog.Info("init sonar client success")
sonarClient = client
})
return sonarClient
}

View File

@@ -0,0 +1,54 @@
package sonarqube
import (
"fmt"
"github.com/kubesphere/sonargo/sonar"
"k8s.io/klog"
"strings"
)
type SonarQubeClient struct {
client *sonargo.Client
}
func NewSonarQubeClient(options *SonarQubeOptions) (*SonarQubeClient, error) {
var endpoint string
if strings.HasSuffix(options.Host, "/") {
endpoint = fmt.Sprintf("%sapi/", options.Host)
} else {
endpoint = fmt.Sprintf("%s/api/", options.Host)
}
sonar, err := sonargo.NewClientWithToken(endpoint, options.Token)
if err != nil {
klog.Errorf("failed to connect to sonarqube service, %+v", err)
return nil, err
}
return &SonarQubeClient{client: sonar}, err
}
func NewSonarQubeClientOrDie(options *SonarQubeOptions) *SonarQubeClient {
var endpoint string
if strings.HasSuffix(options.Host, "/") {
endpoint = fmt.Sprintf("%sapi/", options.Host)
} else {
endpoint = fmt.Sprintf("%s/api/", options.Host)
}
sonar, err := sonargo.NewClientWithToken(endpoint, options.Token)
if err != nil {
klog.Errorf("failed to connect to sonarqube service, %+v", err)
panic(err)
}
return &SonarQubeClient{client: sonar}
}
// return sonarqube client
// Also we can wrap some methods to avoid direct use sonar client
func (s *SonarQubeClient) SonarQube() *sonargo.Client {
return s.client
}

View File

@@ -3,10 +3,10 @@
package tools package tools
import ( import (
_ "k8s.io/kube-openapi/cmd/openapi-gen/"
_ "k8s.io/code-generator/cmd/client-gen" _ "k8s.io/code-generator/cmd/client-gen"
_ "k8s.io/code-generator/cmd/deepcopy-gen"
_ "k8s.io/code-generator/cmd/informer-gen" _ "k8s.io/code-generator/cmd/informer-gen"
_ "k8s.io/code-generator/cmd/lister-gen" _ "k8s.io/code-generator/cmd/lister-gen"
_ "k8s.io/code-generator/cmd/deepcopy-gen" _ "k8s.io/kube-openapi/cmd/openapi-gen/"
_ "sigs.k8s.io/controller-tools/cmd/controller-gen" _ "sigs.k8s.io/controller-tools/cmd/controller-gen"
) )

6
pkg/utils/net/net.go Normal file
View File

@@ -0,0 +1,6 @@
package net
// 0 is considered as a non valid port
func IsValidPort(port int) bool {
return port > 0 && port < 65535
}

View File

@@ -13,7 +13,9 @@ limitations under the License.
package reflectutils package reflectutils
import "reflect" import (
"reflect"
)
func In(value interface{}, container interface{}) bool { func In(value interface{}, container interface{}) bool {
containerValue := reflect.ValueOf(container) containerValue := reflect.ValueOf(container)
@@ -33,3 +35,24 @@ func In(value interface{}, container interface{}) bool {
} }
return false return false
} }
func Override(left interface{}, right interface{}) {
if left == nil || right == nil {
return
}
if reflect.ValueOf(left).Type().Kind() != reflect.Ptr ||
reflect.ValueOf(right).Type().Kind() != reflect.Ptr {
return
}
old := reflect.ValueOf(left).Elem()
new := reflect.ValueOf(right).Elem()
for i := 0; i < old.NumField(); i++ {
val := new.Field(i).Interface()
if !reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface()) {
old.Field(i).Set(reflect.ValueOf(val))
}
}
}

22
pkg/utils/term/term.go Normal file
View File

@@ -0,0 +1,22 @@
package term
import (
"fmt"
"github.com/docker/docker/pkg/term"
"io"
)
// TerminalSize returns the current width and height of the user's terminal. If it isn't a terminal,
// nil is returned. On error, zero values are returned for width and height.
// Usually w must be the stdout of the process. Stderr won't work.
func TerminalSize(w io.Writer) (int, int, error) {
outFd, isTerminal := term.GetFdInfo(w)
if !isTerminal {
return 0, 0, fmt.Errorf("given writer is no terminal")
}
winsize, err := term.GetWinsize(outFd)
if err != nil {
return 0, 0, err
}
return int(winsize.Width), int(winsize.Height), nil
}

View File

@@ -3,9 +3,9 @@
package tools package tools
import ( import (
_ "k8s.io/kube-openapi/cmd/openapi-gen/"
_ "k8s.io/code-generator/cmd/client-gen" _ "k8s.io/code-generator/cmd/client-gen"
_ "k8s.io/code-generator/cmd/deepcopy-gen"
_ "k8s.io/code-generator/cmd/informer-gen" _ "k8s.io/code-generator/cmd/informer-gen"
_ "k8s.io/code-generator/cmd/lister-gen" _ "k8s.io/code-generator/cmd/lister-gen"
_ "k8s.io/code-generator/cmd/deepcopy-gen" _ "k8s.io/kube-openapi/cmd/openapi-gen/"
) )

Some files were not shown because too many files have changed in this diff Show More