This is a huge commit, it does following things:
1. refactor kubesphere dependency service client creation, we can disable dependency by config 2. dependencies can be configured by configuration file 3. refactor cmd package using cobra.Command, so we can use hypersphere to invoke command sepearately. Later we only need to build one image to contains all kubesphere core components. One command to rule them all! 4. live reloading configuration currently not implemented
This commit is contained in:
@@ -21,7 +21,12 @@ before_script:
|
||||
- bash hack/install_kubebuilder.sh
|
||||
|
||||
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:
|
||||
skip_cleanup: true
|
||||
|
||||
8
Makefile
8
Makefile
@@ -39,7 +39,7 @@ define ALL_HELP_INFO
|
||||
# debugging tools like delve.
|
||||
endef
|
||||
.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
|
||||
ks-apiserver: test
|
||||
@@ -57,9 +57,13 @@ ks-iam: test
|
||||
controller-manager: test
|
||||
hack/gobuild.sh cmd/controller-manager
|
||||
|
||||
# Build hypersphere binary
|
||||
hypersphere: test
|
||||
hack/gobuild.sh cmd/hypersphere
|
||||
|
||||
# Run go fmt against code
|
||||
fmt: generate
|
||||
go fmt ./pkg/... ./cmd/...
|
||||
gofmt -w ./pkg ./cmd ./tools ./api
|
||||
|
||||
# Run go vet against code
|
||||
vet: generate
|
||||
|
||||
18
build/hypersphere/Dockerfile
Normal file
18
build/hypersphere/Dockerfile
Normal 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"]
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/controller/destinationrule"
|
||||
"kubesphere.io/kubesphere/pkg/controller/job"
|
||||
"kubesphere.io/kubesphere/pkg/controller/s2ibinary"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/controller/s2irun"
|
||||
|
||||
//"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)
|
||||
|
||||
s2iBinaryController := s2ibinary.NewController(kubesphereclient, kubeClient, kubesphereInformer.Devops().V1alpha1().S2iBinaries())
|
||||
s2iBinaryController := s2ibinary.NewController(kubesphereclient,
|
||||
kubeClient,
|
||||
kubesphereInformer.Devops().V1alpha1().S2iBinaries())
|
||||
|
||||
s2iRunController := s2irun.NewController(kubesphereclient, s2iclient, kubeClient,
|
||||
kubesphereInformer.Devops().V1alpha1().S2iBinaries(),
|
||||
|
||||
63
cmd/controller-manager/app/options/options.go
Normal file
63
cmd/controller-manager/app/options/options.go
Normal 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
|
||||
}
|
||||
153
cmd/controller-manager/app/server.go
Normal file
153
cmd/controller-manager/app/server.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"k8s.io/klog"
|
||||
"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"
|
||||
"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() {
|
||||
flag.Parse()
|
||||
command := app.NewControllerManagerCommand()
|
||||
|
||||
cfg, err := k8s.Config()
|
||||
if err != nil {
|
||||
klog.Error(err, "failed to build kubeconfig")
|
||||
if err := command.Execute(); err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
72
cmd/hypersphere/hypersphere.go
Normal file
72
cmd/hypersphere/hypersphere.go
Normal 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
|
||||
}
|
||||
@@ -1,45 +1,66 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"github.com/spf13/pflag"
|
||||
"flag"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/klog"
|
||||
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 {
|
||||
GenericServerRunOptions *genericoptions.ServerRunOptions
|
||||
|
||||
// istio pilot discovery service url
|
||||
IstioPilotServiceURL string
|
||||
KubernetesOptions *k8s.KubernetesOptions
|
||||
|
||||
// jaeger query service url
|
||||
JaegerQueryServiceUrl string
|
||||
DevopsOptions *devops.DevopsOptions
|
||||
|
||||
// prometheus service url for servicemesh metrics
|
||||
ServicemeshPrometheusServiceUrl string
|
||||
SonarQubeOptions *sonarqube.SonarQubeOptions
|
||||
|
||||
// openpitrix api gateway service url
|
||||
OpenPitrixServer string
|
||||
ServiceMeshOptions *servicemesh.ServiceMeshOptions
|
||||
|
||||
// openpitrix service token
|
||||
OpenPitrixProxyToken string
|
||||
MySQLOptions *mysql.MySQLOptions
|
||||
|
||||
MonitoringOptions *prometheus.PrometheusOptions
|
||||
}
|
||||
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
|
||||
s := ServerRunOptions{
|
||||
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
|
||||
IstioPilotServiceURL: "http://istio-pilot.istio-system.svc:8080/version",
|
||||
JaegerQueryServiceUrl: "http://jaeger-query.istio-system.svc:16686/jaeger",
|
||||
KubernetesOptions: k8s.NewKubernetesOptions(),
|
||||
DevopsOptions: devops.NewDevopsOptions(),
|
||||
SonarQubeOptions: sonarqube.NewSonarQubeOptions(),
|
||||
ServiceMeshOptions: servicemesh.NewServiceMeshOptions(),
|
||||
MySQLOptions: mysql.NewMySQLOptions(),
|
||||
MonitoringOptions: prometheus.NewPrometheusOptions(),
|
||||
}
|
||||
|
||||
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.StringVar(&s.JaegerQueryServiceUrl, "jaeger-query-service-url", "http://jaeger-query.istio-system.svc:16686/jaeger", "jaeger query service url")
|
||||
fs.StringVar(&s.ServicemeshPrometheusServiceUrl, "servicemesh-prometheus-service-url", "http://prometheus-k8s-system.kubesphere-monitoring-system.svc:9090", "prometheus service for servicemesh")
|
||||
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
|
||||
}
|
||||
|
||||
14
cmd/ks-apiserver/app/options/validation.go
Normal file
14
cmd/ks-apiserver/app/options/validation.go
Normal 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
|
||||
}
|
||||
@@ -18,113 +18,110 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
goflag "flag"
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
"github.com/json-iterator/go"
|
||||
kconfig "github.com/kiali/kiali/config"
|
||||
"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/pkg/apiserver/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/servicemesh/tracing"
|
||||
"kubesphere.io/kubesphere/pkg/filter"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/devops"
|
||||
logging "kubesphere.io/kubesphere/pkg/models/log"
|
||||
"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"
|
||||
"log"
|
||||
apiserverconfig "kubesphere.io/kubesphere/pkg/server/config"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/utils/signals"
|
||||
"kubesphere.io/kubesphere/pkg/utils/term"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var jsonIter = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
func NewAPIServerCommand() *cobra.Command {
|
||||
s := options.NewServerRunOptions()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "ks-apiserver",
|
||||
Long: `The KubeSphere API server validates and configures data
|
||||
for the api objects. The API Server services REST operations and provides the frontend to the
|
||||
Long: `The KubeSphere API server validates and configures data for the api objects.
|
||||
The API Server services REST operations and provides the frontend to the
|
||||
cluster's shared state through which all other components interact.`,
|
||||
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())
|
||||
cmd.Flags().AddGoFlagSet(goflag.CommandLine)
|
||||
glog.CopyStandardLogTo("INFO")
|
||||
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 Run(s *options.ServerRunOptions) error {
|
||||
func Run(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
||||
|
||||
pflag.VisitAll(func(flag *pflag.Flag) {
|
||||
log.Printf("FLAG: --%s=%q", flag.Name, flag.Value)
|
||||
})
|
||||
|
||||
var err error
|
||||
|
||||
waitForResourceSync()
|
||||
|
||||
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)
|
||||
}
|
||||
err := CreateClientSet(apiserverconfig.Get(), stopCh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WaitForResourceSync(stopCh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
initializeAdminJenkins()
|
||||
initializeDevOpsDatabase()
|
||||
initializeESClientConfig()
|
||||
initializeServicemeshConfig(s)
|
||||
|
||||
if s.GenericServerRunOptions.InsecurePort != 0 {
|
||||
log.Printf("Server listening on %d.", s.GenericServerRunOptions.InsecurePort)
|
||||
err = http.ListenAndServe(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort), container)
|
||||
initializeESClientConfig()
|
||||
|
||||
err = CreateAPIServer(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.GenericServerRunOptions.SecurePort != 0 && len(s.GenericServerRunOptions.TlsCertFile) > 0 && len(s.GenericServerRunOptions.TlsPrivateKey) > 0 {
|
||||
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()
|
||||
return nil
|
||||
}
|
||||
|
||||
func initializeServicemeshConfig(s *options.ServerRunOptions) {
|
||||
// Initialize kiali config
|
||||
config := kconfig.NewConfig()
|
||||
|
||||
tracing.JaegerQueryUrl = s.JaegerQueryServiceUrl
|
||||
tracing.JaegerQueryUrl = s.ServiceMeshOptions.JaegerQueryHost
|
||||
|
||||
// Exclude system namespaces
|
||||
config.API.Namespaces.Exclude = []string{"istio-system", "kubesphere*", "kube*"}
|
||||
config.InCluster = true
|
||||
|
||||
// Set default prometheus service url
|
||||
config.ExternalServices.PrometheusServiceURL = s.ServicemeshPrometheusServiceUrl
|
||||
config.ExternalServices.PrometheusServiceURL = s.ServiceMeshOptions.ServicemeshPrometheusHost
|
||||
config.ExternalServices.PrometheusCustomMetricsURL = config.ExternalServices.PrometheusServiceURL
|
||||
|
||||
// Set istio pilot discovery service url
|
||||
config.ExternalServices.Istio.UrlServiceVersion = s.IstioPilotServiceURL
|
||||
config.ExternalServices.Istio.UrlServiceVersion = s.ServiceMeshOptions.IstioPilotHost
|
||||
|
||||
kconfig.Set(config)
|
||||
}
|
||||
@@ -134,7 +131,7 @@ func initializeESClientConfig() {
|
||||
// List all outputs
|
||||
outputs, err := logging.GetFluentbitOutputFromConfigMap()
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
klog.Errorln(err)
|
||||
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.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()
|
||||
informerFactory.Core().V1().Nodes().Lister()
|
||||
informerFactory.Core().V1().ResourceQuotas().Lister()
|
||||
informerFactory.Core().V1().Pods().Lister()
|
||||
informerFactory.Core().V1().Services().Lister()
|
||||
informerFactory.Core().V1().PersistentVolumeClaims().Lister()
|
||||
informerFactory.Core().V1().Secrets().Lister()
|
||||
informerFactory.Core().V1().ConfigMaps().Lister()
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings"},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles"},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterrolebindings"},
|
||||
|
||||
informerFactory.Apps().V1().ControllerRevisions().Lister()
|
||||
informerFactory.Apps().V1().StatefulSets().Lister()
|
||||
informerFactory.Apps().V1().Deployments().Lister()
|
||||
informerFactory.Apps().V1().DaemonSets().Lister()
|
||||
informerFactory.Apps().V1().ReplicaSets().Lister()
|
||||
{Group: "apps", Version: "v1", Resource: "deployments"},
|
||||
{Group: "apps", Version: "v1", Resource: "daemonsets"},
|
||||
{Group: "apps", Version: "v1", Resource: "replicasets"},
|
||||
{Group: "apps", Version: "v1", Resource: "statefulsets"},
|
||||
{Group: "apps", Version: "v1", Resource: "controllerrevisions"},
|
||||
|
||||
informerFactory.Batch().V1().Jobs().Lister()
|
||||
informerFactory.Batch().V1beta1().CronJobs().Lister()
|
||||
informerFactory.Extensions().V1beta1().Ingresses().Lister()
|
||||
informerFactory.Autoscaling().V2beta2().HorizontalPodAutoscalers().Lister()
|
||||
{Group: "batch", Version: "v1", Resource: "jobs"},
|
||||
{Group: "batch", Version: "v1beta1", Resource: "cronjobs"},
|
||||
|
||||
informerFactory.Start(stopChan)
|
||||
informerFactory.WaitForCacheSync(stopChan)
|
||||
{Group: "extensions", Version: "v1beta1", Resource: "ingresses"},
|
||||
|
||||
{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.Devops().V1alpha1().S2iBuilderTemplates().Lister()
|
||||
s2iInformerFactory.Devops().V1alpha1().S2iRuns().Lister()
|
||||
s2iInformerFactory.Devops().V1alpha1().S2iBuilders().Lister()
|
||||
|
||||
s2iInformerFactory.Start(stopChan)
|
||||
s2iInformerFactory.WaitForCacheSync(stopChan)
|
||||
s2iGVRs := []schema.GroupVersionResource{
|
||||
{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.Tenant().V1alpha1().Workspaces().Lister()
|
||||
ksInformerFactory.Devops().V1alpha1().S2iBinaries().Lister()
|
||||
|
||||
ksInformerFactory.Start(stopChan)
|
||||
ksInformerFactory.WaitForCacheSync(stopChan)
|
||||
ksGVRs := []schema.GroupVersionResource{
|
||||
{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
|
||||
}
|
||||
|
||||
@@ -29,10 +29,8 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
"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/signals"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
@@ -72,9 +70,6 @@ func Run(s *options.ServerRunOptions) error {
|
||||
|
||||
waitForResourceSync()
|
||||
|
||||
initializeAdminJenkins()
|
||||
initializeDevOpsDatabase()
|
||||
|
||||
err = iam.Init(s.AdminEmail, s.AdminPassword, expireTime, s.AuthRateLimit)
|
||||
jwtutil.Setup(s.JWTSecret)
|
||||
|
||||
@@ -127,11 +122,3 @@ func waitForResourceSync() {
|
||||
ksInformerFactory.WaitForCacheSync(stopChan)
|
||||
log.Println("resources sync success")
|
||||
}
|
||||
|
||||
func initializeAdminJenkins() {
|
||||
admin_jenkins.Client()
|
||||
}
|
||||
|
||||
func initializeDevOpsDatabase() {
|
||||
devops_mysql.OpenDatabase()
|
||||
}
|
||||
|
||||
36
go.mod
36
go.mod
@@ -24,7 +24,6 @@ require (
|
||||
github.com/coreos/etcd v3.3.13+incompatible // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // 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/dgrijalva/jwt-go v3.2.0+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/golang/example v0.0.0-20170904185048-46695d81d1fa
|
||||
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/gofuzz v1.0.0 // indirect
|
||||
github.com/google/uuid v1.1.1
|
||||
@@ -68,15 +65,12 @@ require (
|
||||
github.com/gophercloud/gophercloud v0.3.0 // indirect
|
||||
github.com/gorilla/mux v1.7.1 // 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/hashicorp/go-version v1.2.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.1 // indirect
|
||||
github.com/igm/sockjs-go v2.0.1+incompatible // indirect
|
||||
github.com/imdario/mergo v0.3.7 // 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/kelseyhightower/envconfig v1.4.0 // indirect
|
||||
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/russross/blackfriday v1.5.2 // 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/speps/go-hashids v2.0.0+incompatible
|
||||
github.com/spf13/cobra v0.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/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // 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.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/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
|
||||
google.golang.org/appengine v1.5.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 // indirect
|
||||
@@ -145,15 +133,15 @@ require (
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
k8s.io/api v0.0.0-20181213150558-05914d821849
|
||||
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/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/component-base v0.0.0-20190831075413-37a093468564
|
||||
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/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/controller-runtime v0.1.10
|
||||
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/apache/thrift => github.com/apache/thrift v0.12.0
|
||||
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/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/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/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.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-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/hcl => github.com/hashicorp/hcl 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/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/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/magiconair/properties => github.com/magiconair/properties v1.8.0
|
||||
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/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/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/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/reflect2 => github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742
|
||||
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/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-toml => github.com/pelletier/go-toml v1.2.0
|
||||
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/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/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/cast => github.com/spf13/cast v1.3.0
|
||||
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/viper => github.com/spf13/viper 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/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/ugorji/go => github.com/ugorji/go v1.1.4
|
||||
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/xordataexchange/crypt => github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77
|
||||
go.etcd.io/bbolt => go.etcd.io/bbolt v1.3.3
|
||||
go.opencensus.io => go.opencensus.io v0.20.2
|
||||
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/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/component-base => k8s.io/component-base v0.0.0-20190831075413-37a093468564
|
||||
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/kubernetes => k8s.io/kubernetes v1.13.6
|
||||
k8s.io/utils => k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5
|
||||
|
||||
24
go.sum
24
go.sum
@@ -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/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/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/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
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/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
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/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
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/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/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/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
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/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/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/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/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/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/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
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/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
|
||||
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/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
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/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
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/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/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/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
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/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/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/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/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/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
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/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/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/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68=
|
||||
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ=
|
||||
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/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
|
||||
k8s.io/kubernetes v1.13.6 h1:eUAUryzMLFmi4ZY8kMOUtLG5lHp2PUx5WOmy4RVaobk=
|
||||
|
||||
@@ -9,7 +9,7 @@ TAG=latest
|
||||
# check if build was triggered by a travis cronjob
|
||||
if [[ -z "$TRAVIS_EVENT_TYPE" ]]; then
|
||||
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)
|
||||
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-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/hypersphere/Dockerfile -t $REPO/hypersphere:$TAG .
|
||||
docker build -f ./pkg/db/Dockerfile -t $REPO/ks-devops:flyway-$TAG ./pkg/db/
|
||||
|
||||
# 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-account:$TAG
|
||||
docker push $REPO/ks-controller-manager:$TAG
|
||||
docker push $REPO/hypersphere:$TAG
|
||||
docker push $REPO/ks-devops:flyway-$TAG
|
||||
|
||||
@@ -168,7 +168,7 @@ func addWebService(c *restful.Container) error {
|
||||
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("queryTime", "the time to use for query")).
|
||||
ReturnsError(http.StatusOK, "ok", workloadHealthResponse{}).
|
||||
Returns(http.StatusOK, "ok", workloadHealthResponse{}).
|
||||
Writes(workloadHealthResponse{})).Produces(restful.MIME_JSON)
|
||||
|
||||
// Get app health
|
||||
|
||||
@@ -20,8 +20,14 @@ package monitoring
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"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) {
|
||||
@@ -41,7 +47,7 @@ func MonitorSpecificPodOnSpecificNode(request *restful.Request, response *restfu
|
||||
}
|
||||
|
||||
func MonitorPod(request *restful.Request, response *restful.Response) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
podName := requestParams.PodName
|
||||
if 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) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
rawMetrics := metrics.GetContainerLevelMetrics(requestParams)
|
||||
// sorting
|
||||
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) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
|
||||
rawMetrics := metrics.GetWorkloadLevelMetrics(requestParams)
|
||||
|
||||
@@ -107,7 +113,7 @@ func MonitorWorkload(request *restful.Request, response *restful.Response) {
|
||||
|
||||
func MonitorAllWorkspaces(request *restful.Request, response *restful.Response) {
|
||||
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
|
||||
tp := requestParams.Tp
|
||||
if tp == "statistics" {
|
||||
@@ -129,7 +135,7 @@ func MonitorAllWorkspaces(request *restful.Request, response *restful.Response)
|
||||
}
|
||||
|
||||
func MonitorSpecificWorkspace(request *restful.Request, response *restful.Response) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
|
||||
tp := requestParams.Tp
|
||||
if tp == "rank" {
|
||||
@@ -164,7 +170,7 @@ func MonitorSpecificNamespace(request *restful.Request, response *restful.Respon
|
||||
}
|
||||
|
||||
func MonitorNamespace(request *restful.Request, response *restful.Response) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
// multiple
|
||||
rawMetrics := metrics.GetNamespaceLevelMetrics(requestParams)
|
||||
|
||||
@@ -176,13 +182,23 @@ func MonitorNamespace(request *restful.Request, response *restful.Response) {
|
||||
}
|
||||
|
||||
func MonitorCluster(request *restful.Request, response *restful.Response) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
|
||||
metricName := requestParams.MetricsName
|
||||
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
|
||||
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"})
|
||||
|
||||
response.WriteAsJson(res)
|
||||
@@ -202,13 +218,22 @@ func MonitorSpecificNode(request *restful.Request, response *restful.Response) {
|
||||
}
|
||||
|
||||
func MonitorNode(request *restful.Request, response *restful.Response) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
|
||||
metricName := requestParams.MetricsName
|
||||
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
|
||||
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: ""})
|
||||
// The raw node-exporter result doesn't include ip address information
|
||||
// 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) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
pvcName := requestParams.PVCName
|
||||
if 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) {
|
||||
requestParams := prometheus.ParseMonitoringRequestParams(request)
|
||||
requestParams := ParseMonitoringRequestParams(request)
|
||||
|
||||
if requestParams.MetricsFilter == "" {
|
||||
requestParams.MetricsFilter = requestParams.ComponentName + "_.*"
|
||||
@@ -273,3 +298,113 @@ func MonitorComponent(request *restful.Request, response *restful.Response) {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
log "k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
servicemeshinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh/v1alpha2"
|
||||
servicemeshlisters "kubesphere.io/kubesphere/pkg/client/listers/servicemesh/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -38,8 +38,6 @@ const (
|
||||
maxRetries = 15
|
||||
)
|
||||
|
||||
var log = logf.Log.WithName("application-controller")
|
||||
|
||||
type ApplicationController struct {
|
||||
client clientset.Interface
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
log "k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
"reflect"
|
||||
@@ -35,14 +36,9 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
"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
|
||||
* 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)
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
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) {
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -161,7 +157,7 @@ func (r *ReconcileClusterRoleBinding) updateRoleBindings(clusterRoleBinding *rba
|
||||
|
||||
if !reflect.DeepEqual(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)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -16,10 +16,10 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
log "k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
|
||||
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
|
||||
"time"
|
||||
|
||||
@@ -49,8 +49,6 @@ const (
|
||||
maxRetries = 15
|
||||
)
|
||||
|
||||
var log = logf.Log.WithName("destinationrule-controller")
|
||||
|
||||
type DestinationRuleController struct {
|
||||
client clientset.Interface
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
batchv1informers "k8s.io/client-go/informers/batch/v1"
|
||||
batchv1listers "k8s.io/client-go/listers/batch/v1"
|
||||
log "k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
|
||||
"time"
|
||||
|
||||
@@ -51,8 +51,6 @@ const (
|
||||
revisionsAnnotationKey = "revisions"
|
||||
)
|
||||
|
||||
var log = logf.Log.WithName("job-controller")
|
||||
|
||||
type JobController struct {
|
||||
client clientset.Interface
|
||||
eventBroadcaster record.EventBroadcaster
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/apis/core"
|
||||
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
@@ -356,6 +357,10 @@ func (r *ReconcileNamespace) checkAndCreateRoleBindings(namespace *corev1.Namesp
|
||||
|
||||
// Create openpitrix runtime
|
||||
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 != "" {
|
||||
return nil
|
||||
@@ -363,7 +368,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace)
|
||||
|
||||
cm := &corev1.ConfigMap{}
|
||||
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 {
|
||||
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"]}
|
||||
|
||||
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)
|
||||
return err
|
||||
}
|
||||
@@ -387,7 +392,12 @@ func (r *ReconcileNamespace) deleteRuntime(namespace *corev1.Namespace) error {
|
||||
for i := float64(0); i < maxRetries; i++ {
|
||||
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) {
|
||||
return nil
|
||||
|
||||
@@ -71,9 +71,9 @@ var _ = Describe("Wsnetworkpolicy", func() {
|
||||
wsnp := newWorkspaceNP(testName)
|
||||
wsnp.Spec.PolicyTypes = []k8snetwork.PolicyType{k8snetwork.PolicyTypeIngress}
|
||||
wsnp.Spec.Ingress = []v1alpha1.WorkspaceNetworkPolicyIngressRule{
|
||||
v1alpha1.WorkspaceNetworkPolicyIngressRule{
|
||||
{
|
||||
From: []v1alpha1.WorkspaceNetworkPolicyPeer{
|
||||
v1alpha1.WorkspaceNetworkPolicyPeer{
|
||||
{
|
||||
WorkspaceSelector: &metav1.LabelSelector{
|
||||
MatchLabels: label,
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog"
|
||||
"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"
|
||||
"time"
|
||||
|
||||
@@ -210,12 +210,16 @@ func (c *S2iBinaryController) syncHandler(key string) 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{
|
||||
Bucket: s2is3.Bucket(),
|
||||
Bucket: s3Client.Bucket(),
|
||||
Key: aws.String(fmt.Sprintf("%s-%s", s2ibin.Namespace, s2ibin.Name)),
|
||||
}
|
||||
_, err := s3client.DeleteObject(input)
|
||||
_, err = s3Client.Client().DeleteObject(input)
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
|
||||
@@ -16,9 +16,9 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
log "k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"kubesphere.io/kubesphere/pkg/controller/virtualservice/util"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
|
||||
istioclient "github.com/knative/pkg/client/clientset/versioned"
|
||||
istioinformers "github.com/knative/pkg/client/informers/externalversions/istio/v1alpha3"
|
||||
@@ -46,8 +46,6 @@ const (
|
||||
maxRetries = 15
|
||||
)
|
||||
|
||||
var log = logf.Log.WithName("virtualservice-controller")
|
||||
|
||||
type VirtualServiceController struct {
|
||||
client clientset.Interface
|
||||
|
||||
@@ -152,7 +150,7 @@ func (v *VirtualServiceController) Run(workers int, stopCh <-chan struct{}) erro
|
||||
defer utilruntime.HandleCrash()
|
||||
defer v.queue.ShutDown()
|
||||
|
||||
log.Info("starting virtualservice controller")
|
||||
log.V(0).Info("starting virtualservice controller")
|
||||
defer log.Info("shutting down virtualservice controller")
|
||||
|
||||
if !cache.WaitForCacheSync(stopCh, v.serviceSynced, v.virtualServiceSynced, v.destinationRuleSynced, v.strategySynced) {
|
||||
|
||||
@@ -18,15 +18,12 @@
|
||||
package informers
|
||||
|
||||
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"
|
||||
"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
|
||||
@@ -35,31 +32,31 @@ var (
|
||||
k8sOnce sync.Once
|
||||
s2iOnce sync.Once
|
||||
ksOnce sync.Once
|
||||
informerFactory informers.SharedInformerFactory
|
||||
s2iInformerFactory s2iInformers.SharedInformerFactory
|
||||
ksInformerFactory ksInformers.SharedInformerFactory
|
||||
informerFactory k8sinformers.SharedInformerFactory
|
||||
s2iInformerFactory s2iinformers.SharedInformerFactory
|
||||
ksInformerFactory ksinformers.SharedInformerFactory
|
||||
)
|
||||
|
||||
func SharedInformerFactory() informers.SharedInformerFactory {
|
||||
func SharedInformerFactory() k8sinformers.SharedInformerFactory {
|
||||
k8sOnce.Do(func() {
|
||||
k8sClient := k8s.Client()
|
||||
informerFactory = informers.NewSharedInformerFactory(k8sClient, defaultResync)
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
informerFactory = k8sinformers.NewSharedInformerFactory(k8sClient, defaultResync)
|
||||
})
|
||||
return informerFactory
|
||||
}
|
||||
|
||||
func S2iSharedInformerFactory() s2iInformers.SharedInformerFactory {
|
||||
func S2iSharedInformerFactory() s2iinformers.SharedInformerFactory {
|
||||
s2iOnce.Do(func() {
|
||||
k8sClient := k8s.S2iClient()
|
||||
s2iInformerFactory = s2iInformers.NewSharedInformerFactory(k8sClient, defaultResync)
|
||||
k8sClient := client.ClientSets().K8s().S2i()
|
||||
s2iInformerFactory = s2iinformers.NewSharedInformerFactory(k8sClient, defaultResync)
|
||||
})
|
||||
return s2iInformerFactory
|
||||
}
|
||||
|
||||
func KsSharedInformerFactory() ksInformers.SharedInformerFactory {
|
||||
func KsSharedInformerFactory() ksinformers.SharedInformerFactory {
|
||||
ksOnce.Do(func() {
|
||||
k8sClient := k8s.KsClient()
|
||||
ksInformerFactory = ksInformers.NewSharedInformerFactory(k8sClient, defaultResync)
|
||||
k8sClient := client.ClientSets().K8s().KubeSphere()
|
||||
ksInformerFactory = ksinformers.NewSharedInformerFactory(k8sClient, defaultResync)
|
||||
})
|
||||
return ksInformerFactory
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"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"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -63,7 +63,11 @@ type workLoads struct {
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@@ -76,13 +80,13 @@ func ListApplication(runtimeId string, conditions *params.Conditions, limit, off
|
||||
app.ClusterID = item.ClusterID
|
||||
app.UpdateTime = item.UpdateTime
|
||||
app.Status = item.Status
|
||||
versionInfo, _ := openpitrix.GetVersion(item.VersionID)
|
||||
versionInfo, _ := openPitrixClient.GetVersion(item.VersionID)
|
||||
app.Version = versionInfo
|
||||
app.VersionId = item.VersionID
|
||||
runtimeInfo, _ := openpitrix.GetRuntime(item.RunTimeId)
|
||||
runtimeInfo, _ := openPitrixClient.GetRuntime(item.RunTimeId)
|
||||
app.Runtime = runtimeInfo
|
||||
app.RuntimeId = item.RunTimeId
|
||||
appInfo, _, appId, _ := openpitrix.GetAppInfo(item.AppID)
|
||||
appInfo, _, appId, _ := openPitrixClient.GetAppInfo(item.AppID)
|
||||
app.App = appInfo
|
||||
app.AppId = appId
|
||||
app.Description = item.Description
|
||||
@@ -94,8 +98,11 @@ func ListApplication(runtimeId string, conditions *params.Conditions, limit, off
|
||||
}
|
||||
|
||||
func GetApp(clusterId string) (*Application, error) {
|
||||
|
||||
item, err := openpitrix.GetCluster(clusterId)
|
||||
openPitrixClient, err := client.ClientSets().OpenPitrix()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
item, err := openPitrixClient.GetCluster(clusterId)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
@@ -109,19 +116,19 @@ func GetApp(clusterId string) (*Application, error) {
|
||||
app.UpdateTime = item.UpdateTime
|
||||
app.CreateTime = item.CreateTime
|
||||
app.Status = item.Status
|
||||
versionInfo, _ := openpitrix.GetVersion(item.VersionID)
|
||||
versionInfo, _ := openPitrixClient.GetVersion(item.VersionID)
|
||||
app.Version = versionInfo
|
||||
app.VersionId = item.VersionID
|
||||
|
||||
runtimeInfo, _ := openpitrix.GetRuntime(item.RunTimeId)
|
||||
runtimeInfo, _ := openPitrixClient.GetRuntime(item.RunTimeId)
|
||||
app.Runtime = runtimeInfo
|
||||
app.RuntimeId = item.RunTimeId
|
||||
appInfo, repoId, appId, _ := openpitrix.GetAppInfo(item.AppID)
|
||||
appInfo, repoId, appId, _ := openPitrixClient.GetAppInfo(item.AppID)
|
||||
app.App = appInfo
|
||||
app.AppId = appId
|
||||
app.Description = item.Description
|
||||
|
||||
app.RepoName, _ = openpitrix.GetRepo(repoId)
|
||||
app.RepoName, _ = openPitrixClient.GetRepo(repoId)
|
||||
|
||||
workloads, err := getWorkLoads(app.Runtime, item.ClusterRoleSets)
|
||||
if err != nil {
|
||||
@@ -195,7 +202,7 @@ func getWorkLoads(namespace string, clusterRoles []openpitrix.ClusterRole) (*wor
|
||||
}
|
||||
|
||||
func getLabels(namespace string, workloads *workLoads) *[]map[string]string {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
|
||||
var workloadLables []map[string]string
|
||||
if workloads == nil {
|
||||
@@ -242,7 +249,7 @@ func getSvcs(namespace string, workLoadLabels *[]map[string]string) []v1.Service
|
||||
if len(*workLoadLabels) == 0 {
|
||||
return nil
|
||||
}
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
var services []v1.Service
|
||||
for _, label := range *workLoadLabels {
|
||||
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 {
|
||||
openPitrixClient, err := client.ClientSets().OpenPitrix()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ns, err := informers.SharedInformerFactory().Core().V1().Namespaces().Lister().Get(namespace)
|
||||
if err != nil {
|
||||
glog.Errorf("deploy application failed: %+v", err)
|
||||
@@ -313,9 +325,14 @@ func DeployApplication(namespace string, app openpitrix.CreateClusterRequest) er
|
||||
} else {
|
||||
return fmt.Errorf("runtime not init: namespace %s", namespace)
|
||||
}
|
||||
return openpitrix.CreateCluster(app)
|
||||
return openPitrixClient.CreateCluster(app)
|
||||
}
|
||||
|
||||
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}})
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package components
|
||||
|
||||
import (
|
||||
"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/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
|
||||
@@ -93,7 +93,7 @@ func GetSystemHealthStatus() (*models.HealthStatus, error) {
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -16,9 +16,10 @@ package devops
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fatih/structs"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/db"
|
||||
"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/stringutils"
|
||||
)
|
||||
@@ -126,7 +127,7 @@ var JenkinsOwnerProjectPermissionIds = &gojenkins.ProjectPermissionIds{
|
||||
}
|
||||
|
||||
var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
ProjectOwner: gojenkins.ProjectPermissionIds{
|
||||
ProjectOwner: {
|
||||
CredentialCreate: true,
|
||||
CredentialDelete: true,
|
||||
CredentialManageDomains: true,
|
||||
@@ -146,7 +147,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
RunUpdate: true,
|
||||
SCMTag: true,
|
||||
},
|
||||
ProjectMaintainer: gojenkins.ProjectPermissionIds{
|
||||
ProjectMaintainer: {
|
||||
CredentialCreate: true,
|
||||
CredentialDelete: true,
|
||||
CredentialManageDomains: true,
|
||||
@@ -166,7 +167,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
RunUpdate: true,
|
||||
SCMTag: true,
|
||||
},
|
||||
ProjectDeveloper: gojenkins.ProjectPermissionIds{
|
||||
ProjectDeveloper: {
|
||||
CredentialCreate: false,
|
||||
CredentialDelete: false,
|
||||
CredentialManageDomains: false,
|
||||
@@ -186,7 +187,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
RunUpdate: true,
|
||||
SCMTag: false,
|
||||
},
|
||||
ProjectReporter: gojenkins.ProjectPermissionIds{
|
||||
ProjectReporter: {
|
||||
CredentialCreate: false,
|
||||
CredentialDelete: false,
|
||||
CredentialManageDomains: false,
|
||||
@@ -209,7 +210,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
}
|
||||
|
||||
var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
ProjectOwner: gojenkins.ProjectPermissionIds{
|
||||
ProjectOwner: {
|
||||
CredentialCreate: true,
|
||||
CredentialDelete: true,
|
||||
CredentialManageDomains: true,
|
||||
@@ -229,7 +230,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
RunUpdate: true,
|
||||
SCMTag: true,
|
||||
},
|
||||
ProjectMaintainer: gojenkins.ProjectPermissionIds{
|
||||
ProjectMaintainer: {
|
||||
CredentialCreate: true,
|
||||
CredentialDelete: true,
|
||||
CredentialManageDomains: true,
|
||||
@@ -249,7 +250,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
RunUpdate: true,
|
||||
SCMTag: true,
|
||||
},
|
||||
ProjectDeveloper: gojenkins.ProjectPermissionIds{
|
||||
ProjectDeveloper: {
|
||||
CredentialCreate: false,
|
||||
CredentialDelete: false,
|
||||
CredentialManageDomains: false,
|
||||
@@ -269,7 +270,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
|
||||
RunUpdate: true,
|
||||
SCMTag: false,
|
||||
},
|
||||
ProjectReporter: gojenkins.ProjectPermissionIds{
|
||||
ProjectReporter: {
|
||||
CredentialCreate: false,
|
||||
CredentialDelete: false,
|
||||
CredentialManageDomains: false,
|
||||
@@ -311,9 +312,18 @@ func CheckProjectUserInRole(username, projectId string, roles []string) error {
|
||||
if username == KS_ADMIN {
|
||||
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{}
|
||||
err := dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
err = dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
Where(db.And(
|
||||
db.Eq(DevOpsProjectMembershipUsernameColumn, username),
|
||||
@@ -331,9 +341,17 @@ func GetProjectUserRole(username, projectId string) (string, error) {
|
||||
if username == KS_ADMIN {
|
||||
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{}
|
||||
err := dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
err = dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
Where(db.And(
|
||||
db.Eq(DevOpsProjectMembershipUsernameColumn, username),
|
||||
|
||||
@@ -23,11 +23,11 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
log "github.com/golang/glog"
|
||||
"github.com/emicklei/go-restful"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
|
||||
log "k8s.io/klog"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -40,15 +40,13 @@ const (
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetPipelineUrl, projectName, pipelineName)
|
||||
log.Infof("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -60,8 +58,12 @@ func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e
|
||||
}
|
||||
|
||||
func SearchPipelines(req *http.Request) ([]byte, error) {
|
||||
baseUrl := jenkins.Server + SearchPipelineUrl + req.URL.RawQuery
|
||||
log.Infof("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
baseUrl := devops.Jenkins().Server + SearchPipelineUrl + req.URL.RawQuery
|
||||
|
||||
res, err := sendJenkinsRequest(baseUrl, req)
|
||||
if err != nil {
|
||||
@@ -73,9 +75,12 @@ func SearchPipelines(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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchRunUrl, projectName, pipelineName, branchName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
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)
|
||||
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchStepLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetStepLogUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -136,12 +158,15 @@ func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *ht
|
||||
}
|
||||
|
||||
return resBody, header, err
|
||||
|
||||
}
|
||||
|
||||
func GetSCMServers(scmId string, req *http.Request) ([]byte, error) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetSCMServersUrl, scmId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetSCMServersUrl, scmId)
|
||||
req.Method = http.MethodGet
|
||||
resBody, err := sendJenkinsRequest(baseUrl, req)
|
||||
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) {
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
requestBody, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
@@ -169,6 +199,7 @@ func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
|
||||
log.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var servers []*SCMServer
|
||||
_ = json.Unmarshal(byteServers, &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))
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+CreateSCMServersUrl, scmId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
|
||||
baseUrl := fmt.Sprintf(devops.Jenkins().Server+CreateSCMServersUrl, scmId)
|
||||
|
||||
req.Method = http.MethodPost
|
||||
resBody, err := sendJenkinsRequest(baseUrl, req)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+ValidateUrl, scmId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
baseUrl := fmt.Sprintf(devops.Jenkins().Server+ValidateUrl, scmId)
|
||||
|
||||
req.Method = http.MethodPut
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetSCMOrgUrl+req.URL.RawQuery, scmId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetOrgRepoUrl+req.URL.RawQuery, scmId, organizationId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+StopBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+StopPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+ReplayBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+ReplayPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchRunLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetRunLogUrl+req.URL.RawQuery, projectName, pipelineName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchUrl, projectName, pipelineName)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+CheckBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+CheckPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetConsoleLogUrl+req.URL.RawQuery, projectName, pipelineName)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+ScanBranchUrl+req.URL.RawQuery, projectName, pipelineName)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+RunBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+RunPipelineUrl+req.URL.RawQuery, projectName, pipelineName)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -477,8 +580,12 @@ func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e
|
||||
}
|
||||
|
||||
func GetCrumb(req *http.Request) ([]byte, error) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server + GetCrumbUrl)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
baseUrl := fmt.Sprintf(devops.Jenkins().Server + GetCrumbUrl)
|
||||
|
||||
res, err := sendJenkinsRequest(baseUrl, req)
|
||||
if err != nil {
|
||||
@@ -490,8 +597,12 @@ func GetCrumb(req *http.Request) ([]byte, error) {
|
||||
}
|
||||
|
||||
func CheckScriptCompile(projectName, pipelineName string, req *http.Request) ([]byte, error) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+CheckScriptCompileUrl, projectName, pipelineName)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -503,6 +614,13 @@ func CheckScriptCompile(projectName, pipelineName string, req *http.Request) ([]
|
||||
}
|
||||
|
||||
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 cron = new(CronData)
|
||||
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)
|
||||
}
|
||||
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
newurl, err := url.Parse(baseUrl)
|
||||
newUrl, err := url.Parse(baseUrl)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
newurl.RawQuery = newurl.Query().Encode()
|
||||
newUrl.RawQuery = newUrl.Query().Encode()
|
||||
|
||||
reqJenkins := &http.Request{
|
||||
Method: http.MethodGet,
|
||||
URL: newurl,
|
||||
URL: newUrl,
|
||||
Header: req.Header,
|
||||
}
|
||||
|
||||
client := &http.Client{Timeout: 30 * time.Second}
|
||||
|
||||
resp, err := client.Do(reqJenkins)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
|
||||
if resp != nil && resp.StatusCode != http.StatusOK {
|
||||
resBody, _ := getRespBody(resp)
|
||||
return &CheckCronRes{
|
||||
Result: "error",
|
||||
@@ -569,6 +687,7 @@ func CheckCron(projectName string, req *http.Request) (*CheckCronRes, error) {
|
||||
}
|
||||
|
||||
func parseCronJobTime(msg string) (string, string, error) {
|
||||
|
||||
times := strings.Split(msg, ";")
|
||||
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetPipelineRunUrl, projectName, pipelineName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeUrl, projectName, pipelineName, branchName)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server+GetNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -658,8 +797,12 @@ func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Req
|
||||
}
|
||||
|
||||
func ToJenkinsfile(req *http.Request) ([]byte, error) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server + ToJenkinsfileUrl)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJenkinsfileUrl)
|
||||
|
||||
res, err := sendJenkinsRequest(baseUrl, req)
|
||||
if err != nil {
|
||||
@@ -671,8 +814,12 @@ func ToJenkinsfile(req *http.Request) ([]byte, error) {
|
||||
}
|
||||
|
||||
func ToJson(req *http.Request) ([]byte, error) {
|
||||
baseUrl := fmt.Sprintf(jenkins.Server + ToJsonUrl)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJsonUrl)
|
||||
|
||||
res, err := sendJenkinsRequest(baseUrl, req)
|
||||
if err != nil {
|
||||
@@ -684,8 +831,12 @@ func ToJson(req *http.Request) ([]byte, error) {
|
||||
}
|
||||
|
||||
func GetNotifyCommit(req *http.Request) ([]byte, error) {
|
||||
baseUrl := fmt.Sprint(jenkins.Server, GetNotifyCommitUrl, req.URL.RawQuery)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
baseUrl := fmt.Sprint(devops.Jenkins().Server, GetNotifyCommitUrl, req.URL.RawQuery)
|
||||
req.Method = "GET"
|
||||
|
||||
res, err := sendJenkinsRequest(baseUrl, req)
|
||||
@@ -698,8 +849,12 @@ func GetNotifyCommit(req *http.Request) ([]byte, error) {
|
||||
}
|
||||
|
||||
func GithubWebhook(req *http.Request) ([]byte, error) {
|
||||
baseUrl := fmt.Sprint(jenkins.Server, GithubWebhookUrl, req.URL.RawQuery)
|
||||
log.Info("Jenkins-url: " + baseUrl)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
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)
|
||||
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) {
|
||||
getNodesUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
|
||||
log.Info("getNodesUrl: " + getNodesUrl)
|
||||
var wg sync.WaitGroup
|
||||
var nodesDetails []NodesDetail
|
||||
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) {
|
||||
getNodesUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId)
|
||||
log.Info("getNodesUrl: " + getNodesUrl)
|
||||
var wg sync.WaitGroup
|
||||
var nodesDetails []NodesDetail
|
||||
stepChan := make(chan *NodesStepsIndex, channelMaxCapacity)
|
||||
|
||||
@@ -24,25 +24,25 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/db"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins/utils"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CreateProjectCredential(projectId, username string, credentialRequest *JenkinsCredential) (string, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
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 {
|
||||
glog.Errorf("%+v", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch credentialRequest.Type {
|
||||
case CredentialTypeUsernamePassword:
|
||||
if credentialRequest.UsernamePasswordCredential == nil {
|
||||
@@ -144,12 +144,12 @@ func CreateProjectCredential(projectId, username string, credentialRequest *Jenk
|
||||
}
|
||||
|
||||
func UpdateProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
jenkinsCredential, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
|
||||
credentialId,
|
||||
projectId)
|
||||
@@ -238,20 +238,25 @@ func UpdateProjectCredential(projectId, credentialId string, credentialRequest *
|
||||
}
|
||||
|
||||
func DeleteProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
dbClient := devops_mysql.OpenDatabase()
|
||||
_, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
dbClient, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
_, err = jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
|
||||
credentialId,
|
||||
projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
id, err := jenkinsClient.DeleteCredentialInFolder(credentialRequest.Domain, credentialId, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
@@ -277,13 +282,16 @@ func DeleteProjectCredential(projectId, credentialId string, credentialRequest *
|
||||
}
|
||||
|
||||
func GetProjectCredential(projectId, credentialId, domain, getContent string) (*JenkinsCredential, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
dbClient, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
dbClient := devops_mysql.OpenDatabase()
|
||||
jenkinsResponse, err := jenkinsClient.GetCredentialInFolder(domain,
|
||||
credentialId,
|
||||
projectId)
|
||||
@@ -352,13 +360,16 @@ func GetProjectCredential(projectId, credentialId, domain, getContent string) (*
|
||||
}
|
||||
|
||||
func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
dbClient, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
dbClient := devops_mysql.OpenDatabase()
|
||||
jenkinsCredentialResponses, err := jenkinsClient.GetCredentialsInFolder(domain, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
@@ -380,9 +391,13 @@ func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, erro
|
||||
}
|
||||
|
||||
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)
|
||||
_, err := dbClient.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...).
|
||||
_, err = dbClient.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...).
|
||||
Record(projectCredential).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
@@ -392,12 +407,13 @@ func insertCredentialToDb(projectId, credentialId, domain, username string) erro
|
||||
}
|
||||
|
||||
func checkJenkinsCredentialExists(projectId, domain, credentialId string) error {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
credential, err := jenkinsClient.GetCredentialInFolder(domain, credentialId, projectId)
|
||||
if credential != nil {
|
||||
err := fmt.Errorf("credential id [%s] has been used", credential.Id)
|
||||
|
||||
@@ -19,14 +19,17 @@ import (
|
||||
"github.com/gocraft/dbr"
|
||||
"github.com/golang/glog"
|
||||
"kubesphere.io/kubesphere/pkg/db"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetProject(projectId string) (*DevOpsProject, error) {
|
||||
dbconn := devops_mysql.OpenDatabase()
|
||||
dbconn, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
project := &DevOpsProject{}
|
||||
err := dbconn.Select(DevOpsProjectColumns...).
|
||||
err = dbconn.Select(DevOpsProjectColumns...).
|
||||
From(DevOpsProjectTableName).
|
||||
Where(db.Eq(DevOpsProjectIdColumn, projectId)).
|
||||
LoadOne(project)
|
||||
@@ -43,7 +46,11 @@ func GetProject(projectId string) (*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)
|
||||
if !govalidator.IsNull(project.Description) {
|
||||
query.Set(DevOpsProjectDescriptionColumn, project.Description)
|
||||
@@ -65,7 +72,7 @@ func UpdateProject(project *DevOpsProject) (*DevOpsProject, error) {
|
||||
}
|
||||
}
|
||||
newProject := &DevOpsProject{}
|
||||
err := dbconn.Select(DevOpsProjectColumns...).
|
||||
err = dbconn.Select(DevOpsProjectColumns...).
|
||||
From(DevOpsProjectTableName).
|
||||
Where(db.Eq(DevOpsProjectIdColumn, project.ProjectId)).
|
||||
LoadOne(newProject)
|
||||
|
||||
@@ -14,22 +14,24 @@ package devops
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/klog"
|
||||
"net/http"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/gocraft/dbr"
|
||||
"github.com/golang/glog"
|
||||
"kubesphere.io/kubesphere/pkg/db"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins/utils"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
)
|
||||
|
||||
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)
|
||||
var sqconditions []dbr.Builder
|
||||
sqconditions = append(sqconditions, db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId))
|
||||
@@ -59,14 +61,14 @@ func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy
|
||||
} else {
|
||||
query.Where(sqconditions[0])
|
||||
}
|
||||
_, err := query.Load(&memberships)
|
||||
_, err = query.Load(&memberships)
|
||||
if err != nil && err != dbr.ErrNotFound {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
count, err := query.Count()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
result := make([]interface{}, 0)
|
||||
@@ -78,35 +80,46 @@ func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy
|
||||
}
|
||||
|
||||
func GetProjectMember(projectId, username string) (*DevOpsProjectMembership, error) {
|
||||
dbconn := devops_mysql.OpenDatabase()
|
||||
dbconn, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
member := &DevOpsProjectMembership{}
|
||||
err := dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
err = dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
Where(db.And(db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
|
||||
db.Eq(DevOpsProjectMembershipUsernameColumn, username))).
|
||||
LoadOne(&member)
|
||||
if err != nil && err != dbr.ErrNotFound {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if err == dbr.ErrNotFound {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusNotFound, err.Error())
|
||||
}
|
||||
return member, nil
|
||||
}
|
||||
|
||||
func AddProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) {
|
||||
dbconn := devops_mysql.OpenDatabase()
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
dbconn, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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")
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
|
||||
membership := &DevOpsProjectMembership{}
|
||||
err := dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
err = dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
Where(db.And(
|
||||
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 err == nil {
|
||||
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())
|
||||
}
|
||||
|
||||
if err != nil && err != db.ErrNotFound {
|
||||
glog.Errorf("%+v", err)
|
||||
if err != db.ErrNotFound {
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
globalRole, err := jenkinsClient.GetGlobalRole(JenkinsAllUserRoleName)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
if globalRole == nil {
|
||||
@@ -133,33 +146,33 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
|
||||
GlobalRead: true,
|
||||
}, true)
|
||||
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())
|
||||
}
|
||||
}
|
||||
err = globalRole.AssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
err = projectRole.AssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
err = pipelineRole.AssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
projectMembership := NewDevOpsProjectMemberShip(member.Username, projectId, member.Role, operator)
|
||||
@@ -168,15 +181,15 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
|
||||
Columns(DevOpsProjectMembershipColumns...).
|
||||
Record(projectMembership).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
err = projectRole.UnAssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
err = pipelineRole.UnAssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), 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) {
|
||||
dbconn := devops_mysql.OpenDatabase()
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
dbconn, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
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{}
|
||||
err := dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
err = dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
Where(db.And(
|
||||
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
|
||||
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
|
||||
)).LoadOne(oldMembership)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
err = oldProjectRole.UnAssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
err = oldPipelineRole.UnAssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
err = projectRole.AssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
err = pipelineRole.AssignRole(member.Username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
_, err = dbconn.Update(DevOpsProjectMembershipTableName).
|
||||
Set(DevOpsProjectMembershipRoleColumn, member.Role).
|
||||
Where(db.And(
|
||||
@@ -252,9 +281,10 @@ func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMember
|
||||
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
|
||||
)).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
responseMembership := &DevOpsProjectMembership{}
|
||||
err = dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
@@ -263,35 +293,42 @@ func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMember
|
||||
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
|
||||
)).LoadOne(responseMembership)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return responseMembership, nil
|
||||
}
|
||||
|
||||
func DeleteProjectMember(projectId, username string) (string, error) {
|
||||
dbconn := devops_mysql.OpenDatabase()
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
dbconn, err := cs.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
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{}
|
||||
err := dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
err = dbconn.Select(DevOpsProjectMembershipColumns...).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
Where(db.And(
|
||||
db.Eq(DevOpsProjectMembershipUsernameColumn, username),
|
||||
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
|
||||
)).LoadOne(oldMembership)
|
||||
if err != nil && err != db.ErrNotFound {
|
||||
glog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if err == db.ErrNotFound {
|
||||
glog.Warningf("user [%s] not found in project", username)
|
||||
return username, nil
|
||||
if err != nil {
|
||||
if err != db.ErrNotFound {
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
} else if err == db.ErrNotFound {
|
||||
klog.Warningf("user [%s] not found in project", username)
|
||||
return username, nil
|
||||
}
|
||||
}
|
||||
|
||||
if oldMembership.Role == ProjectOwner {
|
||||
count, err := dbconn.Select(DevOpsProjectMembershipProjectIdColumn).
|
||||
From(DevOpsProjectMembershipTableName).
|
||||
@@ -299,34 +336,35 @@ func DeleteProjectMember(projectId, username string) (string, error) {
|
||||
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
|
||||
db.Eq(DevOpsProjectMembershipRoleColumn, ProjectOwner))).Count()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if count == 1 {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
err = oldProjectRole.UnAssignRole(username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
err = oldPipelineRole.UnAssignRole(username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
@@ -336,7 +374,7 @@ func DeleteProjectMember(projectId, username string) (string, error) {
|
||||
db.Eq(DevOpsProjectMembershipUsernameColumn, username),
|
||||
)).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return username, nil
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
"github.com/golang/glog"
|
||||
"github.com/kubesphere/sonargo/sonar"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -175,7 +175,7 @@ type RemoteTrigger struct {
|
||||
}
|
||||
|
||||
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)
|
||||
output := strings.Join(lines, "\n")
|
||||
return output
|
||||
@@ -1077,7 +1077,12 @@ func toCrontab(millis int64) string {
|
||||
}
|
||||
|
||||
func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
|
||||
sonarClient := sonarqube.Client()
|
||||
|
||||
sonarClient, err := client.ClientSets().SonarQube()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
actions := build.GetActions()
|
||||
sonarStatuses := make([]*SonarStatus, 0)
|
||||
for _, action := range actions {
|
||||
@@ -1086,7 +1091,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
|
||||
taskOptions := &sonargo.CeTaskOption{
|
||||
Id: action.SonarTaskId,
|
||||
}
|
||||
ceTask, _, err := sonarClient.Ce.Task(taskOptions)
|
||||
ceTask, _, err := sonarClient.SonarQube().Ce.Task(taskOptions)
|
||||
if err != nil {
|
||||
glog.Errorf("get sonar task error [%+v]", err)
|
||||
continue
|
||||
@@ -1097,7 +1102,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
|
||||
AdditionalFields: SonarAdditionalFields,
|
||||
MetricKeys: SonarMetricKeys,
|
||||
}
|
||||
measures, _, err := sonarClient.Measures.Component(measuresComponentOption)
|
||||
measures, _, err := sonarClient.SonarQube().Measures.Component(measuresComponentOption)
|
||||
if err != nil {
|
||||
glog.Errorf("get sonar task error [%+v]", err)
|
||||
continue
|
||||
@@ -1112,7 +1117,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
|
||||
S: "FILE_LINE",
|
||||
Facets: "severities,types",
|
||||
}
|
||||
issuesSearch, _, err := sonarClient.Issues.Search(issuesSearchOption)
|
||||
issuesSearch, _, err := sonarClient.SonarQube().Issues.Search(issuesSearchOption)
|
||||
sonarStatus.Issues = issuesSearch
|
||||
jenkinsAction := action
|
||||
sonarStatus.JenkinsAction = &jenkinsAction
|
||||
|
||||
@@ -16,43 +16,43 @@ package devops
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins/utils"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
switch pipeline.Type {
|
||||
case NoScmPipelineType:
|
||||
|
||||
config, err := createPipelineConfigXml(pipeline.Pipeline)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
job, err := jenkinsClient.GetJob(pipeline.Pipeline.Name, projectId)
|
||||
if job != nil {
|
||||
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())
|
||||
}
|
||||
|
||||
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
_, err = jenkinsClient.CreateJobInFolder(config, pipeline.Pipeline.Name, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
|
||||
case MultiBranchPipelineType:
|
||||
config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
|
||||
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)
|
||||
if job != nil {
|
||||
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())
|
||||
}
|
||||
|
||||
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
_, err = jenkinsClient.CreateJobInFolder(config, pipeline.MultiBranchPipeline.Name, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
@@ -87,52 +87,52 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
|
||||
|
||||
default:
|
||||
err := fmt.Errorf("error unsupport job type")
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteProjectPipeline(projectId string, pipelineId string) (string, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
_, err := jenkinsClient.DeleteJob(pipelineId, projectId)
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
_, err = jenkinsClient.DeleteJob(pipelineId, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
return pipelineId, nil
|
||||
}
|
||||
|
||||
func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeline) (string, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
switch pipeline.Type {
|
||||
case NoScmPipelineType:
|
||||
|
||||
config, err := createPipelineConfigXml(pipeline.Pipeline)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
job, err := jenkinsClient.GetJob(pipelineId, projectId)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
err = job.UpdateConfig(config)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
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)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
|
||||
return "", restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -149,13 +149,13 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
|
||||
job, err := jenkinsClient.GetJob(pipelineId, projectId)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
err = job.UpdateConfig(config)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
@@ -163,33 +163,33 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
|
||||
|
||||
default:
|
||||
err := fmt.Errorf("error unsupport job type")
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return "", restful.NewError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
job, err := jenkinsClient.GetJob(pipelineId, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
switch job.Raw.Class {
|
||||
case "org.jenkinsci.plugins.workflow.job.WorkflowJob":
|
||||
config, err := job.GetConfig()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
pipeline, err := parsePipelineConfigXml(config)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
pipeline.Name = pipelineId
|
||||
@@ -201,12 +201,12 @@ func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error)
|
||||
case "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject":
|
||||
config, err := job.GetConfig()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
pipeline, err := parseMultiBranchPipelineConfigXml(config)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
pipeline.Name = pipelineId
|
||||
@@ -216,50 +216,50 @@ func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error)
|
||||
}, nil
|
||||
default:
|
||||
err := fmt.Errorf("error unsupport job type")
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusBadRequest, err.Error())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func GetPipelineSonar(projectId, pipelineId string) ([]*SonarStatus, error) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
job, err := jenkinsClient.GetJob(pipelineId, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
build, err := job.GetLastBuild()
|
||||
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())
|
||||
} else if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sonarStatus, err := getBuildSonarResults(build)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if len(sonarStatus) == 0 {
|
||||
build, err := job.GetLastCompletedBuild()
|
||||
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())
|
||||
} else if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, nil
|
||||
}
|
||||
sonarStatus, err = getBuildSonarResults(build)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
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) {
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
devops, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
jenkinsClient := devops.Jenkins()
|
||||
|
||||
job, err := jenkinsClient.GetJob(branchId, projectId, pipelineId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
build, err := job.GetLastBuild()
|
||||
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())
|
||||
} else if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
sonarStatus, err := getBuildSonarResults(build)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
if len(sonarStatus) == 0 {
|
||||
build, err := job.GetLastCompletedBuild()
|
||||
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())
|
||||
} else if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, nil
|
||||
}
|
||||
sonarStatus, err = getBuildSonarResults(build)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,17 @@ import (
|
||||
|
||||
func Test_NoScmPipelineConfig(t *testing.T) {
|
||||
inputs := []*NoScmPipeline{
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
},
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
},
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -55,7 +55,7 @@ func Test_NoScmPipelineConfig(t *testing.T) {
|
||||
|
||||
func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
|
||||
inputs := []*NoScmPipeline{
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -63,7 +63,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
|
||||
"3", "5",
|
||||
},
|
||||
},
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -71,7 +71,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
|
||||
"3", "",
|
||||
},
|
||||
},
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -79,7 +79,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
|
||||
"", "21321",
|
||||
},
|
||||
},
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -106,7 +106,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
|
||||
|
||||
func Test_NoScmPipelineConfig_Param(t *testing.T) {
|
||||
inputs := []*NoScmPipeline{
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -119,7 +119,7 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -169,7 +169,7 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
|
||||
|
||||
func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
|
||||
inputs := []*NoScmPipeline{
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -178,7 +178,7 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
|
||||
},
|
||||
},
|
||||
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -186,7 +186,7 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
|
||||
Token: "abc",
|
||||
},
|
||||
},
|
||||
&NoScmPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
Jenkinsfile: "node{echo 'hello'}",
|
||||
@@ -218,28 +218,28 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
|
||||
func Test_MultiBranchPipelineConfig(t *testing.T) {
|
||||
|
||||
inputs := []*MultiBranchPipeline{
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "git",
|
||||
GitSource: &GitSource{},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "github",
|
||||
GitHubSource: &GithubSource{},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
SourceType: "single_svn",
|
||||
SingleSvnSource: &SingleSvnSource{},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -266,7 +266,7 @@ func Test_MultiBranchPipelineConfig(t *testing.T) {
|
||||
func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
|
||||
|
||||
inputs := []*MultiBranchPipeline{
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -296,7 +296,7 @@ func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
|
||||
|
||||
func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
|
||||
inputs := []*MultiBranchPipeline{
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -326,7 +326,7 @@ func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
|
||||
func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
|
||||
inputs := []*MultiBranchPipeline{
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -340,7 +340,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
DiscoverBranches: true,
|
||||
},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -361,7 +361,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -383,7 +383,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
},
|
||||
},
|
||||
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -398,7 +398,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
Includes: "tag/*",
|
||||
},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -432,7 +432,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
|
||||
func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
|
||||
|
||||
inputs := []*MultiBranchPipeline{
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -448,7 +448,7 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -493,7 +493,7 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
|
||||
func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
|
||||
|
||||
inputs := []*MultiBranchPipeline{
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -505,7 +505,7 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
|
||||
RegexFilter: ".*",
|
||||
},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -546,7 +546,7 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
|
||||
func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
|
||||
|
||||
inputs := []*MultiBranchPipeline{
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -569,7 +569,7 @@ func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
|
||||
DeleteActionJobsToTrigger: "ddd",
|
||||
},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
@@ -591,7 +591,7 @@ func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
|
||||
CreateActionJobsToTrigger: "abc",
|
||||
},
|
||||
},
|
||||
&MultiBranchPipeline{
|
||||
{
|
||||
Name: "",
|
||||
Description: "for test",
|
||||
ScriptPath: "Jenkinsfile",
|
||||
|
||||
@@ -13,8 +13,7 @@ import (
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/s2is3"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"reflect"
|
||||
@@ -26,6 +25,11 @@ const (
|
||||
)
|
||||
|
||||
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()
|
||||
if err != nil {
|
||||
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.FileName = fileHeader.Filename
|
||||
copy.Spec.DownloadURL = fmt.Sprintf(GetS2iBinaryURL, namespace, name, copy.Spec.FileName)
|
||||
s3session := s2is3.Session()
|
||||
|
||||
s3session := s3Client.Session()
|
||||
if s3session == nil {
|
||||
err := fmt.Errorf("could not connect to s2i s3")
|
||||
klog.Error(err)
|
||||
@@ -82,7 +87,7 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
|
||||
uploader.LeavePartsOnError = true
|
||||
})
|
||||
_, err = uploader.Upload(&s3manager.UploadInput{
|
||||
Bucket: s2is3.Bucket(),
|
||||
Bucket: s3Client.Bucket(),
|
||||
Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)),
|
||||
Body: binFile,
|
||||
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 = 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 {
|
||||
klog.Error(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) {
|
||||
s3Client, err := client.ClientSets().S3()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
origin, err := informers.KsSharedInformerFactory().Devops().V1alpha1().S2iBinaries().Lister().S2iBinaries(namespace).Get(name)
|
||||
if err != nil {
|
||||
klog.Errorf("%+v", err)
|
||||
@@ -146,14 +156,9 @@ func DownloadS2iBinary(namespace, name, fileName string) (string, error) {
|
||||
klog.Error(err)
|
||||
return "", err
|
||||
}
|
||||
s3Client := s2is3.Client()
|
||||
if s3Client == nil {
|
||||
err := fmt.Errorf("could not get s3 client")
|
||||
klog.Error(err)
|
||||
return "", err
|
||||
}
|
||||
req, _ := s3Client.GetObjectRequest(&s3.GetObjectInput{
|
||||
Bucket: s2is3.Bucket(),
|
||||
|
||||
req, _ := s3Client.Client().GetObjectRequest(&s3.GetObjectInput{
|
||||
Bucket: s3Client.Bucket(),
|
||||
Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)),
|
||||
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) {
|
||||
copy := s2ibin.DeepCopy()
|
||||
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 {
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
@@ -188,7 +193,7 @@ func SetS2iBinaryStatusWithRetry(s2ibin *v1alpha1.S2iBinary, status string) (*v1
|
||||
return err
|
||||
}
|
||||
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 {
|
||||
klog.Error(err)
|
||||
return err
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/kubectl"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"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/sliceutil"
|
||||
"sort"
|
||||
@@ -650,7 +650,7 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
|
||||
found, err := clusterRoleBindingLister.Get(username)
|
||||
|
||||
if apierrors.IsNotFound(err) {
|
||||
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
|
||||
_, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
|
||||
if err != nil {
|
||||
glog.Errorln("create cluster role binding", err)
|
||||
return err
|
||||
@@ -665,14 +665,14 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
|
||||
deletePolicy := metav1.DeletePropagationForeground
|
||||
gracePeriodSeconds := int64(0)
|
||||
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 {
|
||||
glog.Errorln("delete cluster role binding", err)
|
||||
return err
|
||||
}
|
||||
maxRetries := 3
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
@@ -684,7 +684,7 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
|
||||
|
||||
if !k8sutil.ContainsUser(found.Subjects, username) {
|
||||
found.Subjects = clusterRoleBinding.Subjects
|
||||
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(found)
|
||||
_, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(found)
|
||||
if err != nil {
|
||||
glog.Errorln("update cluster role binding", err)
|
||||
return err
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"io/ioutil"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/db"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
@@ -30,10 +31,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/kubeconfig"
|
||||
"kubesphere.io/kubesphere/pkg/models/kubectl"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/redis"
|
||||
clientset "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"net/http"
|
||||
@@ -45,9 +43,8 @@ import (
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/go-ldap/ldap"
|
||||
"github.com/golang/glog"
|
||||
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"
|
||||
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap"
|
||||
|
||||
@@ -81,25 +78,22 @@ func Init(email, password string, expireTime time.Duration, authRateLimit string
|
||||
adminPassword = password
|
||||
tokenExpireTime = expireTime
|
||||
maxAuthFailed, authTimeInterval = parseAuthRateLimit(authRateLimit)
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
err = checkAndCreateDefaultUser(conn)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("create default users", err)
|
||||
klog.Errorln("create default users", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = checkAndCreateDefaultGroup(conn)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("create default groups", err)
|
||||
klog.Errorln("create default groups", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -117,28 +111,28 @@ func parseAuthRateLimit(authRateLimit string) (int, time.Duration) {
|
||||
maxCount, _ = strconv.Atoi(groups[1])
|
||||
timeInterval, _ = time.ParseDuration(groups[2])
|
||||
} else {
|
||||
glog.Warning("invalid auth rate limit", authRateLimit)
|
||||
klog.Warning("invalid auth rate limit", authRateLimit)
|
||||
}
|
||||
|
||||
return maxCount, timeInterval
|
||||
}
|
||||
|
||||
func checkAndCreateDefaultGroup(conn ldap.Client) error {
|
||||
func checkAndCreateDefaultGroup(conn *ldapclient.LdapClient) error {
|
||||
|
||||
groupSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.GroupSearchBase,
|
||||
conn.GroupSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
"(&(objectClass=posixGroup))",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
_, err := conn.Search(groupSearchRequest)
|
||||
_, err := conn.Ldap().Search(groupSearchRequest)
|
||||
|
||||
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
|
||||
err = createGroupsBaseDN(conn)
|
||||
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
|
||||
}
|
||||
|
||||
func checkAndCreateDefaultUser(conn ldap.Client) error {
|
||||
func checkAndCreateDefaultUser(conn *ldapclient.LdapClient) error {
|
||||
|
||||
userSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.UserSearchBase,
|
||||
conn.GroupSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
"(&(objectClass=inetOrgPerson))",
|
||||
[]string{"uid"},
|
||||
nil,
|
||||
)
|
||||
|
||||
result, err := conn.Search(userSearchRequest)
|
||||
result, err := conn.Ldap().Search(userSearchRequest)
|
||||
|
||||
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
|
||||
err = createUserBaseDN(conn)
|
||||
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) {
|
||||
_, err = CreateUser(&user.User)
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -201,36 +195,33 @@ func containsUser(entries []*ldap.Entry, user initUser) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func createUserBaseDN(conn ldap.Client) error {
|
||||
func createUserBaseDN(conn *ldapclient.LdapClient) error {
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
groupsCreateRequest := ldap.NewAddRequest(ldapclient.UserSearchBase, nil)
|
||||
groupsCreateRequest := ldap.NewAddRequest(conn.UserSearchBase(), nil)
|
||||
groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"})
|
||||
groupsCreateRequest.Attribute("ou", []string{"Users"})
|
||||
return conn.Add(groupsCreateRequest)
|
||||
return conn.Ldap().Add(groupsCreateRequest)
|
||||
}
|
||||
|
||||
func createGroupsBaseDN(conn ldap.Client) error {
|
||||
groupsCreateRequest := ldap.NewAddRequest(ldapclient.GroupSearchBase, nil)
|
||||
func createGroupsBaseDN(conn *ldapclient.LdapClient) error {
|
||||
groupsCreateRequest := ldap.NewAddRequest(conn.GroupSearchBase(), nil)
|
||||
groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"})
|
||||
groupsCreateRequest.Attribute("ou", []string{"Groups"})
|
||||
return conn.Add(groupsCreateRequest)
|
||||
return conn.Ldap().Add(groupsCreateRequest)
|
||||
}
|
||||
|
||||
// User login
|
||||
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()
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(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")
|
||||
}
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
userSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.UserSearchBase,
|
||||
conn.UserSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", username, username),
|
||||
[]string{"uid", "mail"},
|
||||
nil,
|
||||
)
|
||||
|
||||
result, err := conn.Search(userSearchRequest)
|
||||
result, err := conn.Ldap().Search(userSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -270,10 +258,10 @@ func Login(username string, password string, ip string) (*models.Token, error) {
|
||||
dn := result.Entries[0].DN
|
||||
|
||||
// bind as the user to verify their password
|
||||
err = conn.Bind(dn, password)
|
||||
err = conn.Ldap().Bind(dn, password)
|
||||
|
||||
if err != nil {
|
||||
glog.Infoln("auth failed", username, err)
|
||||
klog.Infoln("auth failed", username, err)
|
||||
|
||||
if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) {
|
||||
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) {
|
||||
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.LTrim(fmt.Sprintf("kubesphere:users:%s:login-log", uid), -10, -1)
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
@@ -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) {
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
pageControl := ldap.NewControlPaging(1000)
|
||||
|
||||
@@ -356,17 +348,17 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi
|
||||
|
||||
for {
|
||||
userSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.UserSearchBase,
|
||||
conn.UserSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
filter,
|
||||
[]string{"uid", "mail", "description", "preferredLanguage", "createTimestamp"},
|
||||
[]ldap.Control{pageControl},
|
||||
)
|
||||
|
||||
response, err := conn.Search(userSearchRequest)
|
||||
response, err := conn.Ldap().Search(userSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("search user", err)
|
||||
klog.Errorln("search user", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -461,26 +453,24 @@ func DescribeUser(username string) (*models.User, error) {
|
||||
// Get user info only included email description & lang
|
||||
func GetUserInfo(username string) (*models.User, error) {
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
userSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.UserSearchBase,
|
||||
conn.UserSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf("(&(objectClass=inetOrgPerson)(uid=%s))", username),
|
||||
[]string{"mail", "description", "preferredLanguage", "createTimestamp"},
|
||||
nil,
|
||||
)
|
||||
|
||||
result, err := conn.Search(userSearchRequest)
|
||||
result, err := conn.Ldap().Search(userSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("search user", err)
|
||||
klog.Errorln("search user", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -500,23 +490,22 @@ func GetUserInfo(username string) (*models.User, error) {
|
||||
}
|
||||
|
||||
func GetUserGroups(username string) ([]string, error) {
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
groupSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.GroupSearchBase,
|
||||
conn.GroupSearchBase(),
|
||||
ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf("(&(objectClass=posixGroup)(memberUid=%s))", username),
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
|
||||
result, err := conn.Search(groupSearchRequest)
|
||||
result, err := conn.Ldap().Search(groupSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -533,7 +522,12 @@ func GetUserGroups(username string) ([]string, error) {
|
||||
}
|
||||
|
||||
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 {
|
||||
return ""
|
||||
@@ -547,13 +541,22 @@ func getLastLoginTime(username string) string {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
return ""
|
||||
@@ -570,53 +573,54 @@ func getAvatar(username string) string {
|
||||
|
||||
func DeleteUser(username string) error {
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
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.Del(deleteRequest); err != nil {
|
||||
glog.Errorln("delete user", err)
|
||||
if err = conn.Ldap().Del(deleteRequest); err != nil {
|
||||
klog.Errorln("delete user", err)
|
||||
return err
|
||||
}
|
||||
|
||||
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 {
|
||||
glog.Errorln("delete user kubeconfig failed", username, err)
|
||||
klog.Errorln("delete user kubeconfig failed", username, err)
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
return restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
devopsDb, err := clientset.ClientSets().MySQL()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dp, err := clientset.ClientSets().Devops()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jenkinsClient := dp.Jenkins()
|
||||
|
||||
_, err = devopsDb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
|
||||
Where(db.And(
|
||||
db.Eq(devops.DevOpsProjectMembershipUsernameColumn, username),
|
||||
)).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = jenkinsClient.DeleteUserInProject(username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -646,17 +650,17 @@ func deleteRoleBindings(username string) error {
|
||||
length2 := len(roleBinding.Subjects)
|
||||
|
||||
if length2 == 0 {
|
||||
deletePolicy := meta_v1.DeletePropagationForeground
|
||||
err = k8s.Client().RbacV1().RoleBindings(roleBinding.Namespace).Delete(roleBinding.Name, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
deletePolicy := metav1.DeletePropagationForeground
|
||||
err = clientset.ClientSets().K8s().Kubernetes().RbacV1().RoleBindings(roleBinding.Namespace).Delete(roleBinding.Name, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
|
||||
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 {
|
||||
_, err = k8s.Client().RbacV1().RoleBindings(roleBinding.Namespace).Update(roleBinding)
|
||||
_, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().RoleBindings(roleBinding.Namespace).Update(roleBinding)
|
||||
|
||||
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 {
|
||||
// delete if it's not workspace role binding
|
||||
if isWorkspaceRoleBinding(clusterRoleBinding) {
|
||||
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
|
||||
_, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
|
||||
} else {
|
||||
deletePolicy := meta_v1.DeletePropagationForeground
|
||||
err = k8s.Client().RbacV1().ClusterRoleBindings().Delete(clusterRoleBinding.Name, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
deletePolicy := metav1.DeletePropagationForeground
|
||||
err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Delete(clusterRoleBinding.Name, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
}
|
||||
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 {
|
||||
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
|
||||
_, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
|
||||
|
||||
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) {
|
||||
|
||||
// bind root DN
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
// search for the given username
|
||||
userSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.UserSearchBase,
|
||||
conn.UserSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", check, check),
|
||||
[]string{"uid", "mail"},
|
||||
nil,
|
||||
)
|
||||
|
||||
result, err := conn.Search(userSearchRequest)
|
||||
result, err := conn.Ldap().Search(userSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("search user", err)
|
||||
klog.Errorln("search user", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -740,26 +743,24 @@ func CreateUser(user *models.User) (*models.User, error) {
|
||||
user.Password = strings.TrimSpace(user.Password)
|
||||
user.Description = strings.TrimSpace(user.Description)
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
userSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.UserSearchBase,
|
||||
conn.UserSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", user.Username, user.Email),
|
||||
[]string{"uid", "mail"},
|
||||
nil,
|
||||
)
|
||||
|
||||
result, err := conn.Search(userSearchRequest)
|
||||
result, err := conn.Ldap().Search(userSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("search user", err)
|
||||
klog.Errorln("search user", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -770,13 +771,13 @@ func CreateUser(user *models.User) (*models.User, error) {
|
||||
maxUid, err := getMaxUid(conn)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("get max uid", err)
|
||||
klog.Errorln("get max uid", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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("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
|
||||
@@ -794,14 +795,14 @@ func CreateUser(user *models.User) (*models.User, error) {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
err = conn.Add(userCreateRequest)
|
||||
err = conn.Ldap().Add(userCreateRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("create user", err)
|
||||
klog.Errorln("create user", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -813,7 +814,7 @@ func CreateUser(user *models.User) (*models.User, error) {
|
||||
err := CreateClusterRoleBinding(user.Username, user.ClusterRole)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("create cluster role binding filed", err)
|
||||
klog.Errorln("create cluster role binding filed", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -821,14 +822,14 @@ func CreateUser(user *models.User) (*models.User, error) {
|
||||
return DescribeUser(user.Username)
|
||||
}
|
||||
|
||||
func getMaxUid(conn ldap.Client) (int, error) {
|
||||
userSearchRequest := ldap.NewSearchRequest(ldapclient.UserSearchBase,
|
||||
func getMaxUid(conn *ldapclient.LdapClient) (int, error) {
|
||||
userSearchRequest := ldap.NewSearchRequest(conn.UserSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
"(&(objectClass=inetOrgPerson))",
|
||||
[]string{"uidNumber"},
|
||||
nil)
|
||||
|
||||
result, err := conn.Search(userSearchRequest)
|
||||
result, err := conn.Ldap().Search(userSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -850,15 +851,15 @@ func getMaxUid(conn ldap.Client) (int, error) {
|
||||
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,
|
||||
"(&(objectClass=posixGroup))",
|
||||
[]string{"gidNumber"},
|
||||
nil)
|
||||
|
||||
result, err := conn.Search(groupSearchRequest)
|
||||
result, err := conn.Ldap().Search(groupSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -882,38 +883,36 @@ func getMaxGid(conn ldap.Client) (int, error) {
|
||||
|
||||
func UpdateUser(user *models.User) (*models.User, error) {
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
dn := fmt.Sprintf("uid=%s,%s", user.Username, ldapclient.UserSearchBase)
|
||||
dn := fmt.Sprintf("uid=%s,%s", user.Username, conn.UserSearchBase())
|
||||
userModifyRequest := ldap.NewModifyRequest(dn, nil)
|
||||
if user.Email != "" {
|
||||
userSearchRequest := ldap.NewSearchRequest(
|
||||
ldapclient.UserSearchBase,
|
||||
conn.UserSearchBase(),
|
||||
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf("(&(objectClass=inetOrgPerson)(mail=%s))", user.Email),
|
||||
[]string{"uid", "mail"},
|
||||
nil,
|
||||
)
|
||||
result, err := conn.Search(userSearchRequest)
|
||||
result, err := conn.Ldap().Search(userSearchRequest)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
if len(result.Entries) > 1 {
|
||||
err = ldap.NewError(ldap.ErrorDebugging, fmt.Errorf("email is duplicated: %s", user.Email))
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
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))
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
userModifyRequest.Replace("mail", []string{user.Email})
|
||||
@@ -935,27 +934,30 @@ func UpdateUser(user *models.User) (*models.User, error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = conn.Modify(userModifyRequest)
|
||||
err = conn.Ldap().Modify(userModifyRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = CreateClusterRoleBinding(user.Username, user.ClusterRole)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("create cluster role binding filed", err)
|
||||
klog.Errorln("create cluster role binding filed", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// clear auth failed record
|
||||
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()
|
||||
|
||||
@@ -969,19 +971,19 @@ func UpdateUser(user *models.User) (*models.User, error) {
|
||||
func DeleteGroup(path string) error {
|
||||
|
||||
// bind root DN
|
||||
conn, err := ldapclient.Client()
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
searchBase, cn := splitPath(path)
|
||||
|
||||
groupDeleteRequest := ldap.NewDelRequest(fmt.Sprintf("cn=%s,%s", cn, searchBase), nil)
|
||||
err = conn.Del(groupDeleteRequest)
|
||||
err = conn.Ldap().Del(groupDeleteRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("delete user group", err)
|
||||
klog.Errorln("delete user group", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -990,18 +992,16 @@ func DeleteGroup(path string) error {
|
||||
|
||||
func CreateGroup(group *models.Group) (*models.Group, error) {
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
maxGid, err := getMaxGid(conn)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("get max gid", err)
|
||||
klog.Errorln("get max gid", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1026,10 +1026,10 @@ func CreateGroup(group *models.Group) (*models.Group, error) {
|
||||
groupCreateRequest.Attribute("memberUid", group.Members)
|
||||
}
|
||||
|
||||
err = conn.Add(groupCreateRequest)
|
||||
err = conn.Ldap().Add(groupCreateRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("create group", err)
|
||||
klog.Errorln("create group", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1041,11 +1041,11 @@ func CreateGroup(group *models.Group) (*models.Group, error) {
|
||||
func UpdateGroup(group *models.Group) (*models.Group, error) {
|
||||
|
||||
// bind root DN
|
||||
conn, err := ldapclient.Client()
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
old, err := DescribeGroup(group.Path)
|
||||
|
||||
@@ -1073,10 +1073,10 @@ func UpdateGroup(group *models.Group) (*models.Group, error) {
|
||||
groupUpdateRequest.Replace("memberUid", group.Members)
|
||||
}
|
||||
|
||||
err = conn.Modify(groupUpdateRequest)
|
||||
err = conn.Ldap().Modify(groupUpdateRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("update group", err)
|
||||
klog.Errorln("update group", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1086,17 +1086,15 @@ func UpdateGroup(group *models.Group) (*models.Group, error) {
|
||||
func ChildList(path string) ([]models.Group, error) {
|
||||
|
||||
// bind root DN
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
var groupSearchRequest *ldap.SearchRequest
|
||||
if path == "" {
|
||||
groupSearchRequest = ldap.NewSearchRequest(ldapclient.GroupSearchBase,
|
||||
groupSearchRequest = ldap.NewSearchRequest(conn.GroupSearchBase(),
|
||||
ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false,
|
||||
"(&(objectClass=posixGroup))",
|
||||
[]string{"cn", "gidNumber", "memberUid", "description"},
|
||||
@@ -1110,7 +1108,7 @@ func ChildList(path string) ([]models.Group, error) {
|
||||
nil)
|
||||
}
|
||||
|
||||
result, err := conn.Search(groupSearchRequest)
|
||||
result, err := conn.Ldap().Search(groupSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1133,7 +1131,7 @@ func ChildList(path string) ([]models.Group, error) {
|
||||
[]string{""},
|
||||
nil)
|
||||
|
||||
result, err = conn.Search(childSearchRequest)
|
||||
result, err = conn.Ldap().Search(childSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1158,13 +1156,11 @@ func DescribeGroup(path string) (*models.Group, error) {
|
||||
|
||||
searchBase, cn := splitPath(path)
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
conn, err := clientset.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
defer conn.Ldap().Close()
|
||||
|
||||
groupSearchRequest := ldap.NewSearchRequest(searchBase,
|
||||
ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false,
|
||||
@@ -1172,10 +1168,10 @@ func DescribeGroup(path string) (*models.Group, error) {
|
||||
[]string{"cn", "gidNumber", "memberUid", "description"},
|
||||
nil)
|
||||
|
||||
result, err := conn.Search(groupSearchRequest)
|
||||
result, err := conn.Ldap().Search(groupSearchRequest)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("search group", err)
|
||||
klog.Errorln("search group", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ package iam
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
@@ -44,6 +44,10 @@ func convertDNToPath(dn string) string {
|
||||
}
|
||||
|
||||
func splitPath(path string) (searchBase string, cn string) {
|
||||
ldapClient, err := client.ClientSets().Ldap()
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
paths := strings.Split(path, ":")
|
||||
length := len(paths)
|
||||
@@ -60,12 +64,12 @@ func splitPath(path string) (searchBase string, cn string) {
|
||||
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 {
|
||||
searchBase = fmt.Sprintf("cn=%s,%s", paths[0], ldapclient.GroupSearchBase)
|
||||
searchBase = fmt.Sprintf("cn=%s,%s", paths[0], ldapClient.GroupSearchBase())
|
||||
cn = paths[1]
|
||||
} else {
|
||||
searchBase = ldapclient.GroupSearchBase
|
||||
searchBase = ldapClient.GroupSearchBase()
|
||||
if paths[0] == "" {
|
||||
cn = "*"
|
||||
} else {
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"math/big"
|
||||
rd "math/rand"
|
||||
"time"
|
||||
@@ -217,7 +217,7 @@ func createKubeConfig(username string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
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}
|
||||
tmpKubeConfig.Clusters = append(tmpKubeConfig.Clusters, tmpCluster)
|
||||
|
||||
@@ -244,7 +244,7 @@ func createKubeConfig(username string) (string, error) {
|
||||
}
|
||||
|
||||
func CreateKubeConfig(username string) error {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
configName := fmt.Sprintf("kubeconfig-%s", username)
|
||||
_, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
|
||||
|
||||
@@ -255,7 +255,7 @@ func CreateKubeConfig(username string) error {
|
||||
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}
|
||||
_, err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(&configMap)
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
@@ -269,7 +269,7 @@ func CreateKubeConfig(username string) error {
|
||||
}
|
||||
|
||||
func GetKubeConfig(username string) (string, error) {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
configName := fmt.Sprintf("kubeconfig-%s", username)
|
||||
configMap, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
|
||||
if err != nil {
|
||||
@@ -284,10 +284,7 @@ func GetKubeConfig(username string) (string, error) {
|
||||
glog.Error(err)
|
||||
return "", err
|
||||
}
|
||||
masterURL := k8s.KubeConfig.Host
|
||||
if host := k8s.MasterURL; host != "" {
|
||||
masterURL = host
|
||||
}
|
||||
masterURL := client.ClientSets().K8s().Master()
|
||||
for i, cluster := range kubeConfig.Clusters {
|
||||
cluster.Cluster.Server = masterURL
|
||||
kubeConfig.Clusters[i] = cluster
|
||||
@@ -301,7 +298,7 @@ func GetKubeConfig(username string) (string, error) {
|
||||
}
|
||||
|
||||
func DelKubeConfig(username string) error {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
configName := fmt.Sprintf("kubeconfig-%s", username)
|
||||
_, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
|
||||
@@ -21,7 +21,7 @@ package kubectl
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"math/rand"
|
||||
"os"
|
||||
|
||||
@@ -49,7 +49,7 @@ func init() {
|
||||
}
|
||||
|
||||
func GetKubectlPod(username string) (models.PodInfo, error) {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
deployName := fmt.Sprintf("kubectl-%s", username)
|
||||
deploy, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
@@ -97,7 +97,7 @@ func selectCorrectPod(namespace string, pods []v1.Pod) (kubectlPod v1.Pod, err e
|
||||
}
|
||||
|
||||
func CreateKubectlDeploy(username string) error {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
deployName := fmt.Sprintf("kubectl-%s", username)
|
||||
configName := fmt.Sprintf("kubeconfig-%s", username)
|
||||
_, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
|
||||
@@ -140,7 +140,7 @@ func CreateKubectlDeploy(username string) error {
|
||||
}
|
||||
|
||||
func DelKubectlDeploy(username string) error {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
deployName := fmt.Sprintf("kubectl-%s", username)
|
||||
_, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
|
||||
@@ -20,6 +20,7 @@ package metrics
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
|
||||
"net/url"
|
||||
@@ -36,7 +37,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"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
|
||||
@@ -136,10 +137,15 @@ func getAllWorkspaceNames(formatedMetric *FormatedMetric) map[string]int {
|
||||
|
||||
func getAllWorkspaces() map[string]int {
|
||||
|
||||
client, err := cs.ClientSets().Prometheus()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
paramValues := make(url.Values)
|
||||
paramValues.Set("query", WorkspaceNamespaceLabelRule)
|
||||
params := paramValues.Encode()
|
||||
res := client.SendMonitoringRequest(client.PrometheusEndpoint, client.DefaultQueryType, params)
|
||||
res := client.SendSecondaryMonitoringRequest(DefaultQueryType, params)
|
||||
|
||||
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
|
||||
wlName := monitoringRequest.WorkloadName
|
||||
@@ -244,7 +256,7 @@ func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.Monitor
|
||||
paramValues := monitoringRequest.Params
|
||||
params := makeRequestParamString(rule, paramValues)
|
||||
|
||||
res := client.SendMonitoringRequest(client.PrometheusEndpoint, client.DefaultQueryType, params)
|
||||
res := client.SendMonitoringRequest(DefaultQueryType, params)
|
||||
|
||||
podNamesFilter := getPodNameRegexInWorkload(res, podsFilter)
|
||||
|
||||
@@ -255,7 +267,7 @@ func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.Monitor
|
||||
return queryType, params, rule == ""
|
||||
}
|
||||
|
||||
func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
|
||||
func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
|
||||
queryType := monitoringRequest.QueryType
|
||||
|
||||
paramValues := monitoringRequest.Params
|
||||
@@ -266,7 +278,7 @@ func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRe
|
||||
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
|
||||
|
||||
paramValues := monitoringRequest.Params
|
||||
@@ -276,7 +288,7 @@ func AssemblePodMetricRequestInfo(monitoringRequest *client.MonitoringRequestPar
|
||||
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
|
||||
|
||||
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)
|
||||
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
|
||||
metricsStr := client.SendMonitoringRequest(queryType, params)
|
||||
res := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelContainerName: ""})
|
||||
return res
|
||||
}
|
||||
|
||||
func AssembleContainerMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
|
||||
func AssembleContainerMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
|
||||
queryType := monitoringRequest.QueryType
|
||||
|
||||
paramValues := monitoringRequest.Params
|
||||
@@ -335,7 +353,7 @@ func AssembleContainerMetricRequestInfo(monitoringRequest *client.MonitoringRequ
|
||||
return queryType, params
|
||||
}
|
||||
|
||||
func AssembleNamespaceMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
|
||||
func AssembleNamespaceMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
|
||||
queryType := monitoringRequest.QueryType
|
||||
|
||||
paramValues := monitoringRequest.Params
|
||||
@@ -345,7 +363,7 @@ func AssembleNamespaceMetricRequestInfo(monitoringRequest *client.MonitoringRequ
|
||||
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
|
||||
|
||||
paramValues := monitoringRequest.Params
|
||||
@@ -356,7 +374,7 @@ func AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest *client.Mon
|
||||
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, "|") + ")$"
|
||||
|
||||
@@ -368,7 +386,7 @@ func AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest *client.Monito
|
||||
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 = "^()$"
|
||||
|
||||
if namespaceList != nil {
|
||||
@@ -418,7 +436,7 @@ func filterNamespace(nsFilter string, namespaceList []string) []string {
|
||||
return newNSlist
|
||||
}
|
||||
|
||||
func MonitorAllWorkspaces(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
|
||||
func MonitorAllWorkspaces(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
|
||||
metricsFilter := monitoringRequest.MetricsFilter
|
||||
if strings.Trim(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()
|
||||
var wg sync.WaitGroup
|
||||
var ch = make(chan *FormatedMetric, ChannelMaxCapacity)
|
||||
@@ -494,7 +518,7 @@ func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, w
|
||||
go func(metricName string) {
|
||||
|
||||
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})
|
||||
wg.Done()
|
||||
}(metricName)
|
||||
@@ -521,7 +545,12 @@ func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, w
|
||||
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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -536,7 +565,7 @@ func GetClusterLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *
|
||||
wg.Add(1)
|
||||
go func(metricName string) {
|
||||
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"})
|
||||
wg.Done()
|
||||
}(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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -575,7 +609,7 @@ func GetNodeLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *For
|
||||
wg.Add(1)
|
||||
go func(metricName string) {
|
||||
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: ""})
|
||||
wg.Done()
|
||||
}(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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -638,7 +678,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
go func(metricName string, namespace string) {
|
||||
|
||||
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})
|
||||
wgForOneMetric.Done()
|
||||
}(metricName, ns)
|
||||
@@ -682,7 +722,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
wg.Add(1)
|
||||
go func(metricName string, workspace string) {
|
||||
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})
|
||||
wg.Done()
|
||||
}(metricName, workspace)
|
||||
@@ -699,7 +739,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
|
||||
go func(metricName string) {
|
||||
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"})
|
||||
|
||||
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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -741,7 +787,7 @@ func GetNamespaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
go func(metricName string) {
|
||||
|
||||
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: ""})
|
||||
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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -784,7 +836,7 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
wg.Add(1)
|
||||
go func(metricName string) {
|
||||
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: ""})
|
||||
// no need to append a null result
|
||||
ch <- reformattedResult
|
||||
@@ -801,7 +853,7 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
metricName = strings.TrimLeft(metricName, "workload_")
|
||||
queryType, params, nullRule := AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest, metricName)
|
||||
if !nullRule {
|
||||
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
|
||||
metricsStr := client.SendMonitoringRequest(queryType, params)
|
||||
fmtMetrics := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""})
|
||||
unifyMetricHistoryTimeRange(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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -845,7 +903,7 @@ func GetPodLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
|
||||
go func(metricName string) {
|
||||
queryType, params, nullRule := AssemblePodMetricRequestInfo(monitoringRequest, metricName)
|
||||
if !nullRule {
|
||||
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
|
||||
metricsStr := client.SendMonitoringRequest(queryType, params)
|
||||
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""})
|
||||
} else {
|
||||
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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -887,7 +951,7 @@ func GetContainerLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
wg.Add(1)
|
||||
go func(metricName string) {
|
||||
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: ""})
|
||||
wg.Done()
|
||||
}(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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -927,7 +997,7 @@ func GetPVCLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
|
||||
go func(metricName string) {
|
||||
queryType, params, nullRule := AssemblePVCMetricRequestInfo(monitoringRequest, metricName)
|
||||
if !nullRule {
|
||||
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
|
||||
metricsStr := client.SendMonitoringRequest(queryType, params)
|
||||
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPVC: ""})
|
||||
} else {
|
||||
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
|
||||
if metricsFilter == "" {
|
||||
metricsFilter = ".*"
|
||||
@@ -969,7 +1045,7 @@ func GetComponentLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
|
||||
wg.Add(1)
|
||||
go func(metricName string) {
|
||||
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})
|
||||
|
||||
if metricName == EtcdServerList {
|
||||
@@ -1175,7 +1251,7 @@ func getSpecificMetricItem(timestamp int64, metricName string, resource string,
|
||||
return &nsMetrics
|
||||
}
|
||||
|
||||
func AssembleClusterMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
|
||||
func AssembleClusterMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
|
||||
queryType := monitoringRequest.QueryType
|
||||
paramValues := monitoringRequest.Params
|
||||
rule := MakeClusterRule(metricName)
|
||||
@@ -1184,7 +1260,7 @@ func AssembleClusterMetricRequestInfo(monitoringRequest *client.MonitoringReques
|
||||
return queryType, params
|
||||
}
|
||||
|
||||
func AssembleNodeMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
|
||||
func AssembleNodeMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
|
||||
queryType := monitoringRequest.QueryType
|
||||
paramValues := monitoringRequest.Params
|
||||
rule := MakeNodeRule(monitoringRequest.NodeId, monitoringRequest.ResourcesFilter, metricName)
|
||||
@@ -1193,7 +1269,7 @@ func AssembleNodeMetricRequestInfo(monitoringRequest *client.MonitoringRequestPa
|
||||
return queryType, params
|
||||
}
|
||||
|
||||
func AssembleComponentRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
|
||||
func AssembleComponentRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
|
||||
queryType := monitoringRequest.QueryType
|
||||
paramValues := monitoringRequest.Params
|
||||
rule := MakeComponentRule(metricName)
|
||||
|
||||
@@ -22,8 +22,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
prom "kubesphere.io/kubesphere/pkg/simple/client/prometheus"
|
||||
)
|
||||
|
||||
func GetNamespacesWithMetrics(namespaces []*v1.Namespace) []*v1.Namespace {
|
||||
@@ -34,10 +32,10 @@ func GetNamespacesWithMetrics(namespaces []*v1.Namespace) []*v1.Namespace {
|
||||
nsFilter := "^(" + strings.Join(nsNameList, "|") + ")$"
|
||||
var timeRelateParams = make(url.Values)
|
||||
|
||||
params := prom.MonitoringRequestParams{
|
||||
params := MonitoringRequestParams{
|
||||
ResourcesFilter: nsFilter,
|
||||
Params: timeRelateParams,
|
||||
QueryType: prom.DefaultQueryType,
|
||||
QueryType: DefaultQueryType,
|
||||
MetricsFilter: "namespace_cpu_usage|namespace_memory_usage_wo_cache|namespace_pod_count",
|
||||
}
|
||||
|
||||
|
||||
33
pkg/models/metrics/types.go
Normal file
33
pkg/models/metrics/types.go
Normal 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
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package nodes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
|
||||
func DrainNode(nodename string) (err error) {
|
||||
|
||||
k8sclient := k8s.Client()
|
||||
k8sclient := client.ClientSets().K8s().Kubernetes()
|
||||
node, err := k8sclient.CoreV1().Nodes().Get(nodename, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -68,7 +68,7 @@ func DrainNode(nodename string) (err error) {
|
||||
|
||||
func drainEviction(nodename string, donech chan bool, errch chan error) {
|
||||
|
||||
k8sclient := k8s.Client()
|
||||
k8sclient := client.ClientSets().K8s().Kubernetes()
|
||||
var options metav1.ListOptions
|
||||
pods := make([]v1.Pod, 0)
|
||||
options.FieldSelector = "spec.nodeName=" + nodename
|
||||
@@ -107,7 +107,6 @@ func drainEviction(nodename string, donech chan bool, errch chan error) {
|
||||
|
||||
//create eviction
|
||||
getPodFn := func(namespace, name string) (*v1.Pod, error) {
|
||||
k8sclient := k8s.Client()
|
||||
return k8sclient.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})
|
||||
}
|
||||
evicerr := evictPods(pods, 0, getPodFn)
|
||||
@@ -118,9 +117,7 @@ func drainEviction(nodename string, donech chan bool, errch chan error) {
|
||||
glog.Fatal(evicerr)
|
||||
errch <- err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
k8sclient := k8s.Client()
|
||||
k8sclient := client.ClientSets().K8s().Kubernetes()
|
||||
deleteOptions := &metav1.DeleteOptions{}
|
||||
if GracePeriodSeconds >= 0 {
|
||||
gracePeriodSeconds := int64(GracePeriodSeconds)
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"io/ioutil"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"sort"
|
||||
|
||||
"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")
|
||||
}
|
||||
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
|
||||
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) {
|
||||
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
|
||||
service, err := getRouterService(namespace)
|
||||
if err != nil {
|
||||
@@ -309,7 +309,7 @@ func deleteRouterService(namespace string) (*corev1.Service, error) {
|
||||
return service, err
|
||||
}
|
||||
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
|
||||
// delete controller service
|
||||
serviceName := constants.IngressControllerPrefix + namespace
|
||||
@@ -333,7 +333,7 @@ func createOrUpdateRouterWorkload(namespace string, publishService bool, service
|
||||
|
||||
deployName := constants.IngressControllerPrefix + namespace
|
||||
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
deployment, err := k8sClient.ExtensionsV1beta1().Deployments(constants.IngressControllerNamespace).Get(deployName, meta_v1.GetOptions{})
|
||||
|
||||
createDeployment := true
|
||||
@@ -403,7 +403,7 @@ func createOrUpdateRouterWorkload(namespace string, publishService bool, service
|
||||
}
|
||||
|
||||
func deleteRouterWorkload(namespace string) error {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
|
||||
deleteOptions := meta_v1.DeleteOptions{}
|
||||
// delete controller deployment
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"fmt"
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/gocraft/dbr"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/db"
|
||||
"kubesphere.io/kubesphere/pkg/gojenkins"
|
||||
@@ -29,8 +28,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
"kubesphere.io/kubesphere/pkg/models/devops"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
|
||||
cs "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"net/http"
|
||||
"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) {
|
||||
|
||||
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{})...).
|
||||
From(devops.DevOpsProjectTableName)
|
||||
@@ -87,14 +89,14 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
|
||||
}
|
||||
query.Limit(uint64(limit))
|
||||
query.Offset(uint64(offset))
|
||||
_, err := query.Load(&projects)
|
||||
_, err = query.Load(&projects)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
count, err := query.Count()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
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) {
|
||||
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{})...).
|
||||
From(devops.DevOpsProjectTableName)
|
||||
@@ -137,20 +143,27 @@ func GetDevOpsProjectsCount(username string) (uint32, error) {
|
||||
func DeleteDevOpsProject(projectId, username string) error {
|
||||
err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return restful.NewError(http.StatusForbidden, err.Error())
|
||||
}
|
||||
gojenkins := admin_jenkins.Client()
|
||||
if gojenkins == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
|
||||
dp, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
return restful.NewError(http.StatusServiceUnavailable, err.Error())
|
||||
}
|
||||
devopsdb := devops_mysql.OpenDatabase()
|
||||
_, err = gojenkins.DeleteJob(projectId)
|
||||
jenkins := dp.Jenkins()
|
||||
|
||||
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 {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
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.GetPipelineRoleName(projectId, role))
|
||||
}
|
||||
err = gojenkins.DeleteProjectRoles(roleNames...)
|
||||
err = jenkins.DeleteProjectRoles(roleNames...)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
_, err = devopsdb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
|
||||
Where(db.Eq(devops.DevOpsProjectMembershipProjectIdColumn, projectId)).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
_, err = devopsdb.Update(devops.DevOpsProjectTableName).
|
||||
Set(devops.StatusColumn, devops.StatusDeleted).
|
||||
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
project := &devops.DevOpsProject{}
|
||||
@@ -183,7 +196,7 @@ func DeleteDevOpsProject(projectId, username string) error {
|
||||
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).
|
||||
LoadOne(project)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
return nil
|
||||
@@ -191,17 +204,24 @@ func DeleteDevOpsProject(projectId, username string) error {
|
||||
|
||||
func CreateDevopsProject(username string, workspace string, req *devops.DevOpsProject) (*devops.DevOpsProject, error) {
|
||||
|
||||
jenkinsClient := admin_jenkins.Client()
|
||||
if jenkinsClient == nil {
|
||||
err := fmt.Errorf("could not connect to jenkins")
|
||||
glog.Error(err)
|
||||
dp, err := cs.ClientSets().Devops()
|
||||
if err != nil {
|
||||
klog.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())
|
||||
}
|
||||
devopsdb := devops_mysql.OpenDatabase()
|
||||
|
||||
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 {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
@@ -229,14 +249,14 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
|
||||
close(addRoleCh)
|
||||
for addRoleResponse := range addRoleCh {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
globalRole, err := jenkinsClient.GetGlobalRole(devops.JenkinsAllUserRoleName)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
if globalRole == nil {
|
||||
@@ -244,41 +264,41 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
|
||||
GlobalRead: true,
|
||||
}, true)
|
||||
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())
|
||||
}
|
||||
}
|
||||
err = globalRole.AssignRole(username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
projectRole, err := jenkinsClient.GetProjectRole(devops.GetProjectRoleName(project.ProjectId, devops.ProjectOwner))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
err = projectRole.AssignRole(username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
|
||||
pipelineRole, err := jenkinsClient.GetProjectRole(devops.GetPipelineRoleName(project.ProjectId, devops.ProjectOwner))
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
err = pipelineRole.AssignRole(username)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
|
||||
}
|
||||
_, err = devopsdb.InsertInto(devops.DevOpsProjectTableName).
|
||||
Columns(devops.DevOpsProjectColumns...).Record(project).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
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).
|
||||
Columns(devops.DevOpsProjectMembershipColumns...).Record(projectMembership).Exec()
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return project, nil
|
||||
@@ -295,7 +315,7 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
|
||||
func GetUserDevopsSimpleRules(username, projectId string) ([]models.SimpleRule, error) {
|
||||
role, err := devops.GetProjectUserRole(username, projectId)
|
||||
if err != nil {
|
||||
glog.Errorf("%+v", err)
|
||||
klog.Errorf("%+v", err)
|
||||
return nil, restful.NewError(http.StatusForbidden, err.Error())
|
||||
}
|
||||
return GetDevopsRoleSimpleRules(role), nil
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
ws "kubesphere.io/kubesphere/pkg/models/workspaces"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -44,7 +44,7 @@ func CreateNamespace(workspaceName string, namespace *v1.Namespace, username str
|
||||
|
||||
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) {
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"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
|
||||
@@ -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)
|
||||
func startProcess(namespace, podName, containerName string, cmd []string, ptyHandler PtyHandler) error {
|
||||
|
||||
k8sClient := k8s.Client()
|
||||
cfg, err := k8s.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
|
||||
cfg := client.ClientSets().K8s().Config()
|
||||
|
||||
req := k8sClient.CoreV1().RESTClient().Post().
|
||||
Resource("pods").
|
||||
@@ -290,10 +288,6 @@ func NewSession(shell, namespace, podName, containerName string) (string, error)
|
||||
sizeChan: make(chan remotecommand.TerminalSize),
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
go WaitingForConnection(shell, namespace, podName, containerName, sessionId)
|
||||
|
||||
return sessionId, nil
|
||||
|
||||
@@ -19,7 +19,7 @@ package workloads
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
const retryTimes = 3
|
||||
|
||||
func JobReRun(namespace, jobName string) error {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
job, err := k8sClient.BatchV1().Jobs(namespace).Get(jobName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -71,7 +71,7 @@ func JobReRun(namespace, jobName string) error {
|
||||
}
|
||||
|
||||
func deleteJob(namespace, job string) error {
|
||||
k8sClient := k8s.Client()
|
||||
k8sClient := client.ClientSets().K8s().Kubernetes()
|
||||
deletePolicy := metav1.DeletePropagationBackground
|
||||
err := k8sClient.BatchV1().Jobs(namespace).Delete(job, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
return err
|
||||
|
||||
@@ -30,8 +30,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
"kubesphere.io/kubesphere/pkg/models/resources"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
clientset "kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"strings"
|
||||
@@ -41,7 +40,7 @@ import (
|
||||
"errors"
|
||||
"k8s.io/api/rbac/v1"
|
||||
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"
|
||||
)
|
||||
|
||||
@@ -67,13 +66,13 @@ func Namespaces(workspaceName string) ([]*core.Namespace, 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 {
|
||||
return err
|
||||
}
|
||||
if namespace.Labels[constants.WorkspaceLabelKey] == workspace {
|
||||
deletePolicy := meta_v1.DeletePropagationForeground
|
||||
return k8s.Client().CoreV1().Namespaces().Delete(namespaceName, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
deletePolicy := metav1.DeletePropagationForeground
|
||||
return clientset.ClientSets().K8s().Kubernetes().CoreV1().Namespaces().Delete(namespaceName, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||
} else {
|
||||
return errors.New("resource not found")
|
||||
}
|
||||
@@ -134,7 +133,7 @@ func CreateWorkspaceRoleBinding(workspace, username string, role string) error {
|
||||
if !k8sutil.ContainsUser(workspaceRoleBinding.Subjects, username) {
|
||||
workspaceRoleBinding = workspaceRoleBinding.DeepCopy()
|
||||
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 {
|
||||
log.Errorf("update workspace role binding failed: %+v", 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
|
||||
}
|
||||
|
||||
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).
|
||||
From(devops.DevOpsProjectTableName).
|
||||
@@ -236,7 +238,10 @@ func GetAllProjectNums() (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).
|
||||
From(devops.DevOpsProjectTableName).
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
*/
|
||||
package options
|
||||
|
||||
import "github.com/spf13/pflag"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/pflag"
|
||||
"kubesphere.io/kubesphere/pkg/utils/net"
|
||||
)
|
||||
|
||||
type ServerRunOptions struct {
|
||||
// server bind address
|
||||
@@ -49,6 +53,26 @@ func NewServerRunOptions() *ServerRunOptions {
|
||||
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) {
|
||||
|
||||
fs.StringVar(&s.BindAddress, "bind-address", "0.0.0.0", "server bind address")
|
||||
|
||||
157
pkg/server/config/config.go
Normal file
157
pkg/server/config/config.go
Normal 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)
|
||||
}
|
||||
}
|
||||
129
pkg/server/config/config_test.go
Normal file
129
pkg/server/config/config_test.go
Normal 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)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
109
pkg/simple/client/devops/devops.go
Normal file
109
pkg/simple/client/devops/devops.go
Normal 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
|
||||
}
|
||||
81
pkg/simple/client/devops/options.go
Normal file
81
pkg/simple/client/devops/options.go
Normal 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. ")
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
315
pkg/simple/client/factory.go
Normal file
315
pkg/simple/client/factory.go
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
100
pkg/simple/client/k8s/kubernetes.go
Normal file
100
pkg/simple/client/k8s/kubernetes.go
Normal 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
|
||||
}
|
||||
59
pkg/simple/client/k8s/options.go
Normal file
59
pkg/simple/client/k8s/options.go
Normal 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.")
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
1
pkg/simple/client/kubesphere/options.go
Normal file
1
pkg/simple/client/kubesphere/options.go
Normal file
@@ -0,0 +1 @@
|
||||
package kubesphere
|
||||
87
pkg/simple/client/ldap/ldap.go
Normal file
87
pkg/simple/client/ldap/ldap.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
53
pkg/simple/client/ldap/options.go
Normal file
53
pkg/simple/client/ldap/options.go
Normal 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.")
|
||||
}
|
||||
109
pkg/simple/client/mysql/condition.go
Normal file
109
pkg/simple/client/mysql/condition.go
Normal 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)
|
||||
}
|
||||
88
pkg/simple/client/mysql/condition_test.go
Normal file
88
pkg/simple/client/mysql/condition_test.go
Normal 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())
|
||||
}
|
||||
}
|
||||
283
pkg/simple/client/mysql/db.go
Normal file
283
pkg/simple/client/mysql/db.go
Normal 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
|
||||
}
|
||||
31
pkg/simple/client/mysql/error.go
Normal file
31
pkg/simple/client/mysql/error.go
Normal 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
|
||||
)
|
||||
55
pkg/simple/client/mysql/event.go
Normal file
55
pkg/simple/client/mysql/event.go
Normal 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)
|
||||
}
|
||||
82
pkg/simple/client/mysql/mysql.go
Normal file
82
pkg/simple/client/mysql/mysql.go
Normal 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
|
||||
}
|
||||
43
pkg/simple/client/mysql/options.go
Normal file
43
pkg/simple/client/mysql/options.go
Normal 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.")
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -35,86 +34,9 @@ const (
|
||||
StateSuffix = "-StatefulSet"
|
||||
)
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
func GetAppInfo(appId string) (string, string, string, error) {
|
||||
url := fmt.Sprintf("%s/v1/apps?app_id=%s", openpitrixAPIServer, appId)
|
||||
resp, err := makeHttpRequest("GET", url, "")
|
||||
func (c *OpenPitrixClient) GetAppInfo(appId string) (string, string, string, error) {
|
||||
url := fmt.Sprintf("%s/v1/apps?app_id=%s", c.apiServer, appId)
|
||||
resp, err := c.makeHttpRequest("GET", url, "")
|
||||
if err != nil {
|
||||
glog.Error(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
|
||||
}
|
||||
|
||||
func GetCluster(clusterId string) (*Cluster, error) {
|
||||
if strings.HasSuffix(openpitrixAPIServer, "/") {
|
||||
openpitrixAPIServer = strings.TrimSuffix(openpitrixAPIServer, "/")
|
||||
}
|
||||
func (c *OpenPitrixClient) GetCluster(clusterId string) (*Cluster, error) {
|
||||
url := fmt.Sprintf("%s/v1/clusters?cluster_id=%s", c.apiServer, clusterId)
|
||||
|
||||
url := fmt.Sprintf("%s/v1/clusters?cluster_id=%s", openpitrixAPIServer, clusterId)
|
||||
|
||||
resp, err := makeHttpRequest("GET", url, "")
|
||||
resp, err := c.makeHttpRequest("GET", url, "")
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
@@ -162,14 +80,11 @@ func GetCluster(clusterId string) (*Cluster, error) {
|
||||
return &clusterList.Clusters[0], nil
|
||||
}
|
||||
|
||||
func ListClusters(runtimeId, searchWord, status string, limit, offset int) (*ClusterList, error) {
|
||||
if strings.HasSuffix(openpitrixAPIServer, "/") {
|
||||
openpitrixAPIServer = strings.TrimSuffix(openpitrixAPIServer, "/")
|
||||
}
|
||||
func (c *OpenPitrixClient) ListClusters(runtimeId, searchWord, status string, limit, offset int) (*ClusterList, error) {
|
||||
|
||||
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 != "" {
|
||||
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)
|
||||
}
|
||||
|
||||
resp, err := makeHttpRequest("GET", url, "")
|
||||
resp, err := c.makeHttpRequest("GET", url, "")
|
||||
if err != nil {
|
||||
glog.Errorf("request %s failed, reason: %s", url, err)
|
||||
return nil, err
|
||||
@@ -201,9 +116,9 @@ func ListClusters(runtimeId, searchWord, status string, limit, offset int) (*Clu
|
||||
return &clusterList, nil
|
||||
}
|
||||
|
||||
func GetRepo(repoId string) (string, error) {
|
||||
url := fmt.Sprintf("%s/v1/repos?repo_id=%s", openpitrixAPIServer, repoId)
|
||||
resp, err := makeHttpRequest("GET", url, "")
|
||||
func (c *OpenPitrixClient) GetRepo(repoId string) (string, error) {
|
||||
url := fmt.Sprintf("%s/v1/repos?repo_id=%s", c.apiServer, repoId)
|
||||
resp, err := c.makeHttpRequest("GET", url, "")
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return Unknown, err
|
||||
@@ -223,9 +138,9 @@ func GetRepo(repoId string) (string, error) {
|
||||
return repos.Repos[0].Name, nil
|
||||
}
|
||||
|
||||
func GetVersion(versionId string) (string, error) {
|
||||
versionUrl := fmt.Sprintf("%s/v1/app_versions?version_id=%s", openpitrixAPIServer, versionId)
|
||||
resp, err := makeHttpRequest("GET", versionUrl, "")
|
||||
func (c *OpenPitrixClient) GetVersion(versionId string) (string, error) {
|
||||
versionUrl := fmt.Sprintf("%s/v1/app_versions?version_id=%s", c.apiServer, versionId)
|
||||
resp, err := c.makeHttpRequest("GET", versionUrl, "")
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return Unknown, err
|
||||
@@ -244,10 +159,10 @@ func GetVersion(versionId string) (string, error) {
|
||||
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)
|
||||
resp, err := makeHttpRequest("GET", versionUrl, "")
|
||||
versionUrl := fmt.Sprintf("%s/v1/runtimes?runtime_id=%s", c.apiServer, runtimeId)
|
||||
resp, err := c.makeHttpRequest("GET", versionUrl, "")
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return Unknown, err
|
||||
@@ -267,9 +182,9 @@ func GetRuntime(runtimeId string) (string, error) {
|
||||
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)
|
||||
|
||||
@@ -278,7 +193,7 @@ func CreateCluster(request CreateClusterRequest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err = makeHttpRequest("POST", versionUrl, string(data))
|
||||
data, err = c.makeHttpRequest("POST", versionUrl, string(data))
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
@@ -288,9 +203,9 @@ func CreateCluster(request CreateClusterRequest) error {
|
||||
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)
|
||||
|
||||
@@ -299,7 +214,7 @@ func DeleteCluster(request DeleteClusterRequest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err = makeHttpRequest("POST", versionUrl, string(data))
|
||||
data, err = c.makeHttpRequest("POST", versionUrl, string(data))
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
@@ -309,7 +224,7 @@ func DeleteCluster(request DeleteClusterRequest) error {
|
||||
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 err error
|
||||
@@ -319,7 +234,7 @@ func makeHttpRequest(method, url, data string) ([]byte, error) {
|
||||
req, err = http.NewRequest(method, url, strings.NewReader(data))
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", openpitrixProxyToken)
|
||||
req.Header.Add("Authorization", c.token)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
@@ -329,7 +244,7 @@ func makeHttpRequest(method, url, data string) ([]byte, error) {
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
|
||||
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)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -20,105 +20,64 @@ package openpitrix
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
"io/ioutil"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
openpitrixAPIServer string
|
||||
openpitrixProxyToken string
|
||||
once sync.Once
|
||||
c client
|
||||
)
|
||||
|
||||
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"`
|
||||
func NewOpenPitrixClient(options *OpenPitrixOptions) (*OpenPitrixClient, error) {
|
||||
return &OpenPitrixClient{
|
||||
client: &http.Client{
|
||||
Timeout: time.Duration(3) * time.Second,
|
||||
},
|
||||
apiServer: options.APIServer,
|
||||
token: options.Token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
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 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 {
|
||||
func (c *OpenPitrixClient) CreateRuntime(runtime *RunTime) error {
|
||||
|
||||
data, err := json.Marshal(runtime)
|
||||
if err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
req.Header.Add("Authorization", openpitrixProxyToken)
|
||||
req.Header.Add("Authorization", c.token)
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode > http.StatusOK {
|
||||
err = Error{resp.StatusCode, string(data)}
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c client) deleteClusters(clusters []cluster) error {
|
||||
func (c *OpenPitrixClient) deleteClusters(clusters []cluster) error {
|
||||
clusterId := make([]string, 0)
|
||||
|
||||
for _, cluster := range clusters {
|
||||
@@ -137,16 +96,16 @@ func (c client) deleteClusters(clusters []cluster) error {
|
||||
ClusterId: clusterId,
|
||||
}
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
req.Header.Add("Authorization", openpitrixProxyToken)
|
||||
req.Header.Add("Authorization", c.token)
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -154,44 +113,44 @@ func (c client) deleteClusters(clusters []cluster) error {
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode > http.StatusOK {
|
||||
err = Error{resp.StatusCode, string(data)}
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c client) listClusters(runtimeId string) ([]cluster, error) {
|
||||
func (c *OpenPitrixClient) listClusters(runtimeId string) ([]cluster, error) {
|
||||
limit := 200
|
||||
offset := 0
|
||||
clusters := make([]cluster, 0)
|
||||
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 {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", openpitrixProxyToken)
|
||||
req.Header.Add("Authorization", c.token)
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -199,7 +158,7 @@ func (c client) listClusters(runtimeId string) ([]cluster, error) {
|
||||
|
||||
if resp.StatusCode > http.StatusOK {
|
||||
err = Error{resp.StatusCode, string(data)}
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
listClusterResponse := struct {
|
||||
@@ -209,7 +168,7 @@ func (c client) listClusters(runtimeId string) ([]cluster, error) {
|
||||
err = json.Unmarshal(data, &listClusterResponse)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -225,18 +184,18 @@ func (c client) listClusters(runtimeId string) ([]cluster, error) {
|
||||
return clusters, nil
|
||||
}
|
||||
|
||||
func (c client) DeleteRuntime(runtimeId string) error {
|
||||
func (c *OpenPitrixClient) DeleteRuntime(runtimeId string) error {
|
||||
clusters, err := c.listClusters(runtimeId)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.deleteClusters(clusters)
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
klog.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
43
pkg/simple/client/openpitrix/options.go
Normal file
43
pkg/simple/client/openpitrix/options.go
Normal 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.")
|
||||
}
|
||||
117
pkg/simple/client/openpitrix/types.go
Normal file
117
pkg/simple/client/openpitrix/types.go
Normal 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
|
||||
}
|
||||
37
pkg/simple/client/prometheus/options.go
Normal file
37
pkg/simple/client/prometheus/options.go
Normal 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.")
|
||||
}
|
||||
67
pkg/simple/client/prometheus/prometheus.go
Normal file
67
pkg/simple/client/prometheus/prometheus.go
Normal 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 ""
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
57
pkg/simple/client/redis/options.go
Normal file
57
pkg/simple/client/redis/options.go
Normal 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.")
|
||||
}
|
||||
@@ -18,48 +18,49 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"fmt"
|
||||
"github.com/go-redis/redis"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
var (
|
||||
redisHost string
|
||||
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")
|
||||
type RedisClient struct {
|
||||
client *redis.Client
|
||||
}
|
||||
|
||||
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() {
|
||||
redisClient = redis.NewClient(&redis.Options{
|
||||
Addr: redisHost,
|
||||
Password: redisPassword,
|
||||
DB: redisDB,
|
||||
})
|
||||
if err := redisClient.Ping().Err(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
c := make(chan os.Signal, 0)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-c
|
||||
redisClient.Close()
|
||||
}()
|
||||
return client
|
||||
}
|
||||
|
||||
func NewRedisClient(option *RedisOptions, stopCh <-chan struct{}) (*RedisClient, error) {
|
||||
var r RedisClient
|
||||
|
||||
r.client = redis.NewClient(&redis.Options{
|
||||
Addr: fmt.Sprintf("%s:%d", option.Host, option.Port),
|
||||
Password: option.Password,
|
||||
DB: option.DB,
|
||||
})
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
61
pkg/simple/client/s2is3/options.go
Normal file
61
pkg/simple/client/s2is3/options.go
Normal 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")
|
||||
}
|
||||
@@ -1,83 +1,79 @@
|
||||
package s2is3
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"k8s.io/klog"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
s3Region string
|
||||
s3Endpoint string
|
||||
s3DisableSSL bool
|
||||
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")
|
||||
type S3Client struct {
|
||||
s3Client *s3.S3
|
||||
s3Session *session.Session
|
||||
bucket string
|
||||
}
|
||||
|
||||
func Client() *s3.S3 {
|
||||
if s2iS3 != nil {
|
||||
return s2iS3
|
||||
func NewS3Client(options *S3Options) (*S3Client, error) {
|
||||
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,
|
||||
}
|
||||
clientInitMutex.Lock()
|
||||
defer clientInitMutex.Unlock()
|
||||
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)
|
||||
|
||||
s, err := session.NewSession(&config)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to connect to s2i s3: %+v", err)
|
||||
return nil
|
||||
klog.Error(err)
|
||||
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 {
|
||||
return aws.String(s3Bucket)
|
||||
// NewS3ClientOrDie creates S3Client and panics if there is an error
|
||||
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)
|
||||
}
|
||||
|
||||
59
pkg/simple/client/servicemesh/options.go
Normal file
59
pkg/simple/client/servicemesh/options.go
Normal 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")
|
||||
}
|
||||
49
pkg/simple/client/sonarqube/options.go
Normal file
49
pkg/simple/client/sonarqube/options.go
Normal 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.")
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
54
pkg/simple/client/sonarqube/sonarqube.go
Normal file
54
pkg/simple/client/sonarqube/sonarqube.go
Normal 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
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
_ "k8s.io/kube-openapi/cmd/openapi-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/lister-gen"
|
||||
_ "k8s.io/code-generator/cmd/deepcopy-gen"
|
||||
_ "k8s.io/kube-openapi/cmd/openapi-gen/"
|
||||
_ "sigs.k8s.io/controller-tools/cmd/controller-gen"
|
||||
)
|
||||
|
||||
6
pkg/utils/net/net.go
Normal file
6
pkg/utils/net/net.go
Normal 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
|
||||
}
|
||||
@@ -13,7 +13,9 @@ limitations under the License.
|
||||
|
||||
package reflectutils
|
||||
|
||||
import "reflect"
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func In(value interface{}, container interface{}) bool {
|
||||
containerValue := reflect.ValueOf(container)
|
||||
@@ -33,3 +35,24 @@ func In(value interface{}, container interface{}) bool {
|
||||
}
|
||||
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
22
pkg/utils/term/term.go
Normal 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
|
||||
}
|
||||
@@ -3,9 +3,9 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
_ "k8s.io/kube-openapi/cmd/openapi-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/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
Reference in New Issue
Block a user