This is a huge commit, it does following things: (#1942)
1. Remove ks-iam standalone binary, move it to ks-apiserver 2. Generate all devops apis inside kubesphere repository, no need to import s2ioperator. 3. Reorganize ldap code, make it more flexible to use.
This commit is contained in:
@@ -18,122 +18,74 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/controller/application"
|
||||
"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/storage/expansion"
|
||||
|
||||
//"kubesphere.io/kubesphere/pkg/controller/job"
|
||||
"kubesphere.io/kubesphere/pkg/controller/virtualservice"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"time"
|
||||
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
|
||||
applicationclientset "github.com/kubernetes-sigs/application/pkg/client/clientset/versioned"
|
||||
applicationinformers "github.com/kubernetes-sigs/application/pkg/client/informers/externalversions"
|
||||
s2iclientset "github.com/kubesphere/s2ioperator/pkg/client/clientset/versioned"
|
||||
s2iinformers "github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions"
|
||||
istioclientset "istio.io/client-go/pkg/clientset/versioned"
|
||||
istioinformers "istio.io/client-go/pkg/informers/externalversions"
|
||||
kubesphereclientset "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
kubesphereinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
|
||||
)
|
||||
|
||||
const defaultResync = 600 * time.Second
|
||||
func AddControllers(
|
||||
mgr manager.Manager,
|
||||
client k8s.Client,
|
||||
informerFactory informers.InformerFactory,
|
||||
stopCh <-chan struct{}) error {
|
||||
|
||||
var log = logf.Log.WithName("controller-manager")
|
||||
kubernetesInformer := informerFactory.KubernetesSharedInformerFactory()
|
||||
istioInformer := informerFactory.IstioSharedInformerFactory()
|
||||
kubesphereInformer := informerFactory.KubeSphereSharedInformerFactory()
|
||||
applicationInformer := informerFactory.ApplicationSharedInformerFactory()
|
||||
|
||||
func AddControllers(mgr manager.Manager, cfg *rest.Config, stopCh <-chan struct{}) error {
|
||||
|
||||
kubeClient, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
log.Error(err, "building kubernetes client failed")
|
||||
}
|
||||
|
||||
istioclient, err := istioclientset.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
log.Error(err, "create istio client failed")
|
||||
return err
|
||||
}
|
||||
|
||||
applicationClient, err := applicationclientset.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
log.Error(err, "create application client failed")
|
||||
return err
|
||||
}
|
||||
s2iclient, err := s2iclientset.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
log.Error(err, "create s2i client failed")
|
||||
return err
|
||||
}
|
||||
kubesphereclient, err := kubesphereclientset.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
log.Error(err, "create kubesphere client failed")
|
||||
return err
|
||||
}
|
||||
|
||||
informerFactory := informers.NewSharedInformerFactory(kubeClient, defaultResync)
|
||||
istioInformer := istioinformers.NewSharedInformerFactory(istioclient, defaultResync)
|
||||
applicationInformer := applicationinformers.NewSharedInformerFactory(applicationClient, defaultResync)
|
||||
s2iInformer := s2iinformers.NewSharedInformerFactory(s2iclient, defaultResync)
|
||||
|
||||
kubesphereInformer := kubesphereinformers.NewSharedInformerFactory(kubesphereclient, defaultResync)
|
||||
|
||||
vsController := virtualservice.NewVirtualServiceController(informerFactory.Core().V1().Services(),
|
||||
vsController := virtualservice.NewVirtualServiceController(kubernetesInformer.Core().V1().Services(),
|
||||
istioInformer.Networking().V1alpha3().VirtualServices(),
|
||||
istioInformer.Networking().V1alpha3().DestinationRules(),
|
||||
kubesphereInformer.Servicemesh().V1alpha2().Strategies(),
|
||||
kubeClient,
|
||||
istioclient,
|
||||
kubesphereclient)
|
||||
client.Kubernetes(),
|
||||
client.Istio(),
|
||||
client.KubeSphere())
|
||||
|
||||
drController := destinationrule.NewDestinationRuleController(informerFactory.Apps().V1().Deployments(),
|
||||
drController := destinationrule.NewDestinationRuleController(kubernetesInformer.Apps().V1().Deployments(),
|
||||
istioInformer.Networking().V1alpha3().DestinationRules(),
|
||||
informerFactory.Core().V1().Services(),
|
||||
kubernetesInformer.Core().V1().Services(),
|
||||
kubesphereInformer.Servicemesh().V1alpha2().ServicePolicies(),
|
||||
kubeClient,
|
||||
istioclient,
|
||||
kubesphereclient)
|
||||
client.Kubernetes(),
|
||||
client.Istio(),
|
||||
client.KubeSphere())
|
||||
|
||||
apController := application.NewApplicationController(informerFactory.Core().V1().Services(),
|
||||
informerFactory.Apps().V1().Deployments(),
|
||||
informerFactory.Apps().V1().StatefulSets(),
|
||||
apController := application.NewApplicationController(kubernetesInformer.Core().V1().Services(),
|
||||
kubernetesInformer.Apps().V1().Deployments(),
|
||||
kubernetesInformer.Apps().V1().StatefulSets(),
|
||||
kubesphereInformer.Servicemesh().V1alpha2().Strategies(),
|
||||
kubesphereInformer.Servicemesh().V1alpha2().ServicePolicies(),
|
||||
applicationInformer.App().V1beta1().Applications(),
|
||||
kubeClient,
|
||||
applicationClient)
|
||||
client.Kubernetes(),
|
||||
client.Application())
|
||||
|
||||
jobController := job.NewJobController(informerFactory.Batch().V1().Jobs(), kubeClient)
|
||||
jobController := job.NewJobController(kubernetesInformer.Batch().V1().Jobs(), client.Kubernetes())
|
||||
|
||||
s2iBinaryController := s2ibinary.NewController(kubesphereclient,
|
||||
kubeClient,
|
||||
s2iBinaryController := s2ibinary.NewController(client.KubeSphere(),
|
||||
client.Kubernetes(),
|
||||
kubesphereInformer.Devops().V1alpha1().S2iBinaries())
|
||||
|
||||
s2iRunController := s2irun.NewController(kubesphereclient, s2iclient, kubeClient,
|
||||
s2iRunController := s2irun.NewS2iRunController(client.KubeSphere(),
|
||||
client.Kubernetes(),
|
||||
kubesphereInformer.Devops().V1alpha1().S2iBinaries(),
|
||||
s2iInformer.Devops().V1alpha1().S2iRuns())
|
||||
kubesphereInformer.Devops().V1alpha1().S2iRuns())
|
||||
|
||||
volumeExpansionController := expansion.NewVolumeExpansionController(
|
||||
kubeClient,
|
||||
informerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
informerFactory.Storage().V1().StorageClasses(),
|
||||
informerFactory.Core().V1().Pods(),
|
||||
informerFactory.Apps().V1().Deployments(),
|
||||
informerFactory.Apps().V1().ReplicaSets(),
|
||||
informerFactory.Apps().V1().StatefulSets())
|
||||
|
||||
kubesphereInformer.Start(stopCh)
|
||||
istioInformer.Start(stopCh)
|
||||
informerFactory.Start(stopCh)
|
||||
applicationInformer.Start(stopCh)
|
||||
s2iInformer.Start(stopCh)
|
||||
client.Kubernetes(),
|
||||
kubernetesInformer.Core().V1().PersistentVolumeClaims(),
|
||||
kubernetesInformer.Storage().V1().StorageClasses(),
|
||||
kubernetesInformer.Core().V1().Pods(),
|
||||
kubernetesInformer.Apps().V1().Deployments(),
|
||||
kubernetesInformer.Apps().V1().ReplicaSets(),
|
||||
kubernetesInformer.Apps().V1().StatefulSets())
|
||||
|
||||
controllers := map[string]manager.Runnable{
|
||||
"virtualservice-controller": vsController,
|
||||
@@ -146,9 +98,8 @@ func AddControllers(mgr manager.Manager, cfg *rest.Config, stopCh <-chan struct{
|
||||
}
|
||||
|
||||
for name, ctrl := range controllers {
|
||||
err = mgr.Add(ctrl)
|
||||
if err != nil {
|
||||
log.Error(err, "add controller to manager failed", "name", name)
|
||||
if err := mgr.Add(ctrl); err != nil {
|
||||
klog.Error(err, "add controller to manager failed", "name", name)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,10 @@ import (
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/klog"
|
||||
kubesphereconfig "kubesphere.io/kubesphere/pkg/server/config"
|
||||
kubesphereconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/s3"
|
||||
"strings"
|
||||
@@ -20,6 +21,7 @@ type KubeSphereControllerManagerOptions struct {
|
||||
DevopsOptions *jenkins.Options
|
||||
S3Options *s3.Options
|
||||
OpenPitrixOptions *openpitrix.Options
|
||||
KubeSphereOptions *kubesphere.Options
|
||||
|
||||
LeaderElection *leaderelection.LeaderElectionConfig
|
||||
}
|
||||
@@ -30,6 +32,7 @@ func NewKubeSphereControllerManagerOptions() *KubeSphereControllerManagerOptions
|
||||
DevopsOptions: jenkins.NewDevopsOptions(),
|
||||
S3Options: s3.NewS3Options(),
|
||||
OpenPitrixOptions: openpitrix.NewOptions(),
|
||||
KubeSphereOptions: kubesphere.NewKubeSphereOptions(),
|
||||
LeaderElection: &leaderelection.LeaderElectionConfig{
|
||||
LeaseDuration: 30 * time.Second,
|
||||
RenewDeadline: 15 * time.Second,
|
||||
@@ -47,13 +50,13 @@ func (s *KubeSphereControllerManagerOptions) ApplyTo(conf *kubesphereconfig.Conf
|
||||
s.OpenPitrixOptions.ApplyTo(conf.OpenPitrixOptions)
|
||||
}
|
||||
|
||||
func (s *KubeSphereControllerManagerOptions) Flags(o *KubeSphereControllerManagerOptions) cliflag.NamedFlagSets {
|
||||
func (s *KubeSphereControllerManagerOptions) Flags() cliflag.NamedFlagSets {
|
||||
fss := cliflag.NamedFlagSets{}
|
||||
|
||||
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), o.KubernetesOptions)
|
||||
s.DevopsOptions.AddFlags(fss.FlagSet("devops"), o.DevopsOptions)
|
||||
s.S3Options.AddFlags(fss.FlagSet("s3"), o.S3Options)
|
||||
s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix"), o.OpenPitrixOptions)
|
||||
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), s.KubernetesOptions)
|
||||
s.DevopsOptions.AddFlags(fss.FlagSet("devops"), s.DevopsOptions)
|
||||
s.S3Options.AddFlags(fss.FlagSet("s3"), s.S3Options)
|
||||
s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix"), s.OpenPitrixOptions)
|
||||
|
||||
fs := fss.FlagSet("leaderelection")
|
||||
s.bindLeaderElectionFlags(s.LeaderElection, fs)
|
||||
|
||||
@@ -32,10 +32,14 @@ import (
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/cmd/controller-manager/app/options"
|
||||
"kubesphere.io/kubesphere/pkg/apis"
|
||||
controllerconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
|
||||
"kubesphere.io/kubesphere/pkg/controller"
|
||||
controllerconfig "kubesphere.io/kubesphere/pkg/server/config"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/controller/namespace"
|
||||
"kubesphere.io/kubesphere/pkg/controller/workspace"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
kclient "kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
|
||||
"kubesphere.io/kubesphere/pkg/utils/term"
|
||||
"os"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
@@ -44,20 +48,20 @@ import (
|
||||
|
||||
func NewControllerManagerCommand() *cobra.Command {
|
||||
s := options.NewKubeSphereControllerManagerOptions()
|
||||
conf, err := controllerconfig.TryLoadFromDisk()
|
||||
if err == nil {
|
||||
s = &options.KubeSphereControllerManagerOptions{
|
||||
KubernetesOptions: conf.KubernetesOptions,
|
||||
DevopsOptions: conf.DevopsOptions,
|
||||
S3Options: conf.S3Options,
|
||||
OpenPitrixOptions: conf.OpenPitrixOptions,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
s = Complete(s)
|
||||
|
||||
if errs := s.Validate(); len(errs) != 0 {
|
||||
klog.Error(utilerrors.NewAggregate(errs))
|
||||
os.Exit(1)
|
||||
@@ -69,10 +73,8 @@ func NewControllerManagerCommand() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
conf := loadConfFromFile()
|
||||
|
||||
fs := cmd.Flags()
|
||||
namedFlagSets := s.Flags(conf)
|
||||
namedFlagSets := s.Flags()
|
||||
|
||||
for _, f := range namedFlagSets.FlagSets {
|
||||
fs.AddFlagSet(f)
|
||||
@@ -87,68 +89,43 @@ func NewControllerManagerCommand() *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func Complete(s *options.KubeSphereControllerManagerOptions) *options.KubeSphereControllerManagerOptions {
|
||||
conf := controllerconfig.Get()
|
||||
|
||||
conf.Apply(&controllerconfig.Config{
|
||||
DevopsOptions: s.DevopsOptions,
|
||||
KubernetesOptions: s.KubernetesOptions,
|
||||
S3Options: s.S3Options,
|
||||
OpenPitrixOptions: s.OpenPitrixOptions,
|
||||
})
|
||||
|
||||
out := &options.KubeSphereControllerManagerOptions{
|
||||
KubernetesOptions: conf.KubernetesOptions,
|
||||
DevopsOptions: conf.DevopsOptions,
|
||||
S3Options: conf.S3Options,
|
||||
OpenPitrixOptions: conf.OpenPitrixOptions,
|
||||
LeaderElection: s.LeaderElection,
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func CreateClientSet(conf *controllerconfig.Config, stopCh <-chan struct{}) error {
|
||||
csop := &client.ClientSetOptions{}
|
||||
|
||||
csop.SetKubernetesOptions(conf.KubernetesOptions).
|
||||
SetDevopsOptions(conf.DevopsOptions).
|
||||
SetS3Options(conf.S3Options).
|
||||
SetOpenPitrixOptions(conf.OpenPitrixOptions).
|
||||
SetKubeSphereOptions(conf.KubeSphereOptions)
|
||||
client.NewClientSetFactory(csop, stopCh)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadConfFromFile() *options.KubeSphereControllerManagerOptions {
|
||||
err := controllerconfig.Load()
|
||||
if err != nil {
|
||||
klog.Fatalf("error happened while loading config file")
|
||||
}
|
||||
|
||||
conf := controllerconfig.Get()
|
||||
|
||||
return &options.KubeSphereControllerManagerOptions{
|
||||
KubernetesOptions: conf.KubernetesOptions,
|
||||
DevopsOptions: conf.DevopsOptions,
|
||||
S3Options: conf.S3Options,
|
||||
OpenPitrixOptions: conf.OpenPitrixOptions,
|
||||
}
|
||||
}
|
||||
|
||||
func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{}) error {
|
||||
err := CreateClientSet(controllerconfig.Get(), stopCh)
|
||||
kubernetesClient, err := k8s.NewKubernetesClient(s.KubernetesOptions)
|
||||
if err != nil {
|
||||
klog.Error(err)
|
||||
klog.Errorf("Failed to create kubernetes clientset %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
config := client.ClientSets().K8s().Config()
|
||||
kubesphereClient := kclient.NewKubeSphereClient(s.KubeSphereOptions)
|
||||
|
||||
openpitrixClient, err := openpitrix.NewClient(s.OpenPitrixOptions)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to create openpitrix client %v", err)
|
||||
return err
|
||||
}
|
||||
/*
|
||||
devopsClient, err := jenkins.NewDevopsClient(s.DevopsOptions)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to create devops client %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
s3Client, err := s3.NewS3Client(s.S3Options)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to create s3 client", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
informerFactory := informers.NewInformerFactories(kubernetesClient.Kubernetes(), kubernetesClient.KubeSphere(), kubernetesClient.Istio(), kubernetesClient.Application())
|
||||
informerFactory.Start(stopCh)
|
||||
|
||||
run := func(ctx context.Context) {
|
||||
klog.V(0).Info("setting up manager")
|
||||
mgr, err := manager.New(config, manager.Options{})
|
||||
mgr, err := manager.New(kubernetesClient.Config(), manager.Options{})
|
||||
if err != nil {
|
||||
klog.Fatalf("unable to set up overall controller manager: %v", err)
|
||||
}
|
||||
@@ -159,16 +136,22 @@ func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
|
||||
}
|
||||
|
||||
klog.V(0).Info("Setting up controllers")
|
||||
if err := controller.AddToManager(mgr); err != nil {
|
||||
err = workspace.Add(mgr, kubesphereClient)
|
||||
if err != nil {
|
||||
klog.Fatal("Unable to create workspace controller")
|
||||
}
|
||||
|
||||
err = namespace.Add(mgr, openpitrixClient)
|
||||
if err != nil {
|
||||
klog.Fatal("Unable to create namespace controller")
|
||||
}
|
||||
|
||||
if err := AddControllers(mgr, kubernetesClient, informerFactory, stopCh); err != nil {
|
||||
klog.Fatalf("unable to register controllers to the manager: %v", err)
|
||||
}
|
||||
|
||||
if err := AddControllers(mgr, config, stopCh); err != nil {
|
||||
klog.Fatalf("unable to register controllers to the manager: %v", err)
|
||||
}
|
||||
|
||||
klog.V(0).Info("Starting the Cmd.")
|
||||
if err := mgr.Start(stopCh); err != nil {
|
||||
klog.V(0).Info("Starting the controllers.")
|
||||
if err = mgr.Start(stopCh); err != nil {
|
||||
klog.Fatalf("unable to run the manager: %v", err)
|
||||
}
|
||||
|
||||
@@ -197,8 +180,8 @@ func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{})
|
||||
lock, err := resourcelock.New(resourcelock.LeasesResourceLock,
|
||||
"kubesphere-system",
|
||||
"ks-controller-manager",
|
||||
client.ClientSets().K8s().Kubernetes().CoreV1(),
|
||||
client.ClientSets().K8s().Kubernetes().CoordinationV1(),
|
||||
kubernetesClient.Kubernetes().CoreV1(),
|
||||
kubernetesClient.Kubernetes().CoordinationV1(),
|
||||
resourcelock.ResourceLockConfig{
|
||||
Identity: id,
|
||||
EventRecorder: record.NewBroadcaster().NewRecorder(scheme.Scheme, v1.EventSource{
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
controllermanager "kubesphere.io/kubesphere/cmd/controller-manager/app"
|
||||
ksapigateway "kubesphere.io/kubesphere/cmd/ks-apigateway/app"
|
||||
ksapiserver "kubesphere.io/kubesphere/cmd/ks-apiserver/app"
|
||||
ksaiam "kubesphere.io/kubesphere/cmd/ks-iam/app"
|
||||
"os"
|
||||
)
|
||||
|
||||
@@ -46,13 +45,11 @@ func commandFor(basename string, defaultCommand *cobra.Command, commands []func(
|
||||
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() }
|
||||
apigateway := func() *cobra.Command { return ksapigateway.NewAPIGatewayCommand() }
|
||||
|
||||
commandFns := []func() *cobra.Command{
|
||||
apiserver,
|
||||
controllermanager,
|
||||
iam,
|
||||
apigateway,
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"github.com/mholt/caddy/caddy/caddymain"
|
||||
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||
"github.com/spf13/cobra"
|
||||
apiserverconfig "kubesphere.io/kubesphere/pkg/server/config"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/utils/signals"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/apigateway"
|
||||
@@ -21,12 +19,6 @@ for proxy request to the right backend. API Gateway also proxy
|
||||
Kubernetes API Server for KubeSphere authorization purpose.
|
||||
`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
err := apiserverconfig.Load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
apigateway.RegisterPlugins()
|
||||
|
||||
return Run(signals.SetupSignalHandler())
|
||||
@@ -39,11 +31,6 @@ Kubernetes API Server for KubeSphere authorization purpose.
|
||||
}
|
||||
|
||||
func Run(stopCh <-chan struct{}) error {
|
||||
|
||||
csop := &client.ClientSetOptions{}
|
||||
csop.SetKubernetesOptions(apiserverconfig.Get().KubernetesOptions)
|
||||
client.NewClientSetFactory(csop, stopCh)
|
||||
|
||||
httpserver.RegisterDevDirective("authenticate", "jwt")
|
||||
httpserver.RegisterDevDirective("authentication", "jwt")
|
||||
httpserver.RegisterDevDirective("swagger", "jwt")
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/klog"
|
||||
"kubesphere.io/kubesphere/pkg/api/iam"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver"
|
||||
genericoptions "kubesphere.io/kubesphere/pkg/server/options"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/ldap"
|
||||
esclient "kubesphere.io/kubesphere/pkg/simple/client/logging/elasticsearch"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/monitoring/prometheus"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
|
||||
@@ -14,6 +20,7 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/s3"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -29,6 +36,9 @@ type ServerRunOptions struct {
|
||||
S3Options *s3.Options
|
||||
OpenPitrixOptions *openpitrix.Options
|
||||
LoggingOptions *esclient.Options
|
||||
LdapOptions *ldap.Options
|
||||
CacheOptions *cache.Options
|
||||
AuthenticateOptions *iam.AuthenticationOptions
|
||||
}
|
||||
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
@@ -44,22 +54,28 @@ func NewServerRunOptions() *ServerRunOptions {
|
||||
S3Options: s3.NewS3Options(),
|
||||
OpenPitrixOptions: openpitrix.NewOptions(),
|
||||
LoggingOptions: esclient.NewElasticSearchOptions(),
|
||||
LdapOptions: ldap.NewOptions(),
|
||||
CacheOptions: cache.NewRedisOptions(),
|
||||
AuthenticateOptions: iam.NewAuthenticateOptions(),
|
||||
}
|
||||
|
||||
return &s
|
||||
}
|
||||
|
||||
func (s *ServerRunOptions) Flags(c *ServerRunOptions) (fss cliflag.NamedFlagSets) {
|
||||
s.GenericServerRunOptions.AddFlags(fss.FlagSet("generic"), c.GenericServerRunOptions)
|
||||
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), c.KubernetesOptions)
|
||||
s.MySQLOptions.AddFlags(fss.FlagSet("mysql"), c.MySQLOptions)
|
||||
s.DevopsOptions.AddFlags(fss.FlagSet("devops"), c.DevopsOptions)
|
||||
s.SonarQubeOptions.AddFlags(fss.FlagSet("sonarqube"), c.SonarQubeOptions)
|
||||
s.S3Options.AddFlags(fss.FlagSet("s3"), c.S3Options)
|
||||
s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix"), c.OpenPitrixOptions)
|
||||
s.ServiceMeshOptions.AddFlags(fss.FlagSet("servicemesh"), c.ServiceMeshOptions)
|
||||
s.MonitoringOptions.AddFlags(fss.FlagSet("monitoring"), c.MonitoringOptions)
|
||||
s.LoggingOptions.AddFlags(fss.FlagSet("logging"), c.LoggingOptions)
|
||||
func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
|
||||
s.GenericServerRunOptions.AddFlags(fss.FlagSet("generic"), s.GenericServerRunOptions)
|
||||
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), s.KubernetesOptions)
|
||||
s.AuthenticateOptions.AddFlags(fss.FlagSet("authenticate"), s.AuthenticateOptions)
|
||||
s.MySQLOptions.AddFlags(fss.FlagSet("mysql"), s.MySQLOptions)
|
||||
s.DevopsOptions.AddFlags(fss.FlagSet("devops"), s.DevopsOptions)
|
||||
s.SonarQubeOptions.AddFlags(fss.FlagSet("sonarqube"), s.SonarQubeOptions)
|
||||
s.LdapOptions.AddFlags(fss.FlagSet("ldap"), s.LdapOptions)
|
||||
s.CacheOptions.AddFlags(fss.FlagSet("cache"), s.CacheOptions)
|
||||
s.S3Options.AddFlags(fss.FlagSet("s3"), s.S3Options)
|
||||
s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix"), s.OpenPitrixOptions)
|
||||
s.ServiceMeshOptions.AddFlags(fss.FlagSet("servicemesh"), s.ServiceMeshOptions)
|
||||
s.MonitoringOptions.AddFlags(fss.FlagSet("monitoring"), s.MonitoringOptions)
|
||||
s.LoggingOptions.AddFlags(fss.FlagSet("logging"), s.LoggingOptions)
|
||||
|
||||
fs := fss.FlagSet("klog")
|
||||
local := flag.NewFlagSet("klog", flag.ExitOnError)
|
||||
@@ -71,3 +87,62 @@ func (s *ServerRunOptions) Flags(c *ServerRunOptions) (fss cliflag.NamedFlagSets
|
||||
|
||||
return fss
|
||||
}
|
||||
|
||||
func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIServer, error) {
|
||||
kubernetesClient, err := k8s.NewKubernetesClient(s.KubernetesOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
monitoringClient := prometheus.NewPrometheus(s.MonitoringOptions)
|
||||
|
||||
loggingClient, err := esclient.NewElasticsearch(s.LoggingOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s3Client, err := s3.NewS3Client(s.S3Options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
devopsClient, err := jenkins.NewDevopsClient(s.DevopsOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ldapClient, err := ldap.NewLdapClient(s.LdapOptions, stopCh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cacheClient, err := cache.NewRedisClient(s.CacheOptions, stopCh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", s.GenericServerRunOptions.InsecurePort),
|
||||
}
|
||||
|
||||
if s.GenericServerRunOptions.SecurePort != 0 {
|
||||
certificate, err := tls.LoadX509KeyPair(s.GenericServerRunOptions.TlsCertFile, s.GenericServerRunOptions.TlsPrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
server.TLSConfig.Certificates = []tls.Certificate{certificate}
|
||||
}
|
||||
|
||||
apiServer := &apiserver.APIServer{
|
||||
Server: server,
|
||||
KubernetesClient: kubernetesClient,
|
||||
MonitoringClient: monitoringClient,
|
||||
LoggingClient: loggingClient,
|
||||
S3Client: s3Client,
|
||||
DevopsClient: devopsClient,
|
||||
LdapClient: ldapClient,
|
||||
CacheClient: cacheClient,
|
||||
}
|
||||
|
||||
return apiServer, nil
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package options
|
||||
func (s *ServerRunOptions) Validate() []error {
|
||||
var errors []error
|
||||
|
||||
errors = append(errors, s.GenericServerRunOptions.Validate()...)
|
||||
errors = append(errors, s.DevopsOptions.Validate()...)
|
||||
errors = append(errors, s.KubernetesOptions.Validate()...)
|
||||
errors = append(errors, s.MySQLOptions.Validate()...)
|
||||
|
||||
@@ -21,31 +21,35 @@ import (
|
||||
"fmt"
|
||||
kconfig "github.com/kiali/kiali/config"
|
||||
"github.com/spf13/cobra"
|
||||
"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"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
||||
apiserverconfig "kubesphere.io/kubesphere/pkg/apiserver/config"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/servicemesh/tracing"
|
||||
kinformers "kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/kapis"
|
||||
"kubesphere.io/kubesphere/pkg/server"
|
||||
apiserverconfig "kubesphere.io/kubesphere/pkg/server/config"
|
||||
"kubesphere.io/kubesphere/pkg/server/filter"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/s3"
|
||||
"kubesphere.io/kubesphere/pkg/utils/signals"
|
||||
"kubesphere.io/kubesphere/pkg/utils/term"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func NewAPIServerCommand() *cobra.Command {
|
||||
s := options.NewServerRunOptions()
|
||||
|
||||
// Load configuration from file
|
||||
conf, err := apiserverconfig.TryLoadFromDisk()
|
||||
if err == nil {
|
||||
s = &options.ServerRunOptions{
|
||||
KubernetesOptions: conf.KubernetesOptions,
|
||||
DevopsOptions: conf.DevopsOptions,
|
||||
SonarQubeOptions: conf.SonarQubeOptions,
|
||||
ServiceMeshOptions: conf.ServiceMeshOptions,
|
||||
MySQLOptions: conf.MySQLOptions,
|
||||
MonitoringOptions: conf.MonitoringOptions,
|
||||
S3Options: conf.S3Options,
|
||||
OpenPitrixOptions: conf.OpenPitrixOptions,
|
||||
LoggingOptions: conf.LoggingOptions,
|
||||
AuthenticateOptions: conf.AuthenticateOptions,
|
||||
}
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "ks-apiserver",
|
||||
Long: `The KubeSphere API server validates and configures data for the api objects.
|
||||
@@ -60,11 +64,8 @@ cluster's shared state through which all other components interact.`,
|
||||
},
|
||||
}
|
||||
|
||||
configOptions := load()
|
||||
|
||||
fs := cmd.Flags()
|
||||
namedFlagSets := s.Flags(configOptions)
|
||||
|
||||
namedFlagSets := s.Flags()
|
||||
for _, f := range namedFlagSets.FlagSets {
|
||||
fs.AddFlagSet(f)
|
||||
}
|
||||
@@ -80,24 +81,19 @@ cluster's shared state through which all other components interact.`,
|
||||
|
||||
func Run(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
||||
|
||||
err := CreateClientSet(apiserverconfig.Get(), stopCh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = WaitForResourceSync(stopCh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
initializeServicemeshConfig(s)
|
||||
|
||||
err = CreateAPIServer(s)
|
||||
apiserver, err := s.NewAPIServer(stopCh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
err = apiserver.PrepareRun()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return apiserver.Run(stopCh)
|
||||
}
|
||||
|
||||
func initializeServicemeshConfig(s *options.ServerRunOptions) {
|
||||
@@ -119,234 +115,3 @@ func initializeServicemeshConfig(s *options.ServerRunOptions) {
|
||||
|
||||
kconfig.Set(config)
|
||||
}
|
||||
|
||||
//
|
||||
func CreateAPIServer(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
||||
var err error
|
||||
|
||||
deps := createDeps(s, stopCh)
|
||||
|
||||
apiserver := apiserver.New(deps)
|
||||
|
||||
container := runtime.Container
|
||||
container.DoNotRecover(false)
|
||||
container.Filter(filter.Logging)
|
||||
container.RecoverHandler(server.LogStackOnRecover)
|
||||
|
||||
kapis.InstallAPIs(container)
|
||||
|
||||
// install config api
|
||||
apiserverconfig.InstallAPI(container)
|
||||
|
||||
if s.GenericServerRunOptions.InsecurePort != 0 {
|
||||
err = http.ListenAndServe(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort), container)
|
||||
if err == nil {
|
||||
klog.V(0).Infof("Server listening on insecure port %d.", s.GenericServerRunOptions.InsecurePort)
|
||||
}
|
||||
}
|
||||
|
||||
if s.GenericServerRunOptions.SecurePort != 0 && len(s.GenericServerRunOptions.TlsCertFile) > 0 && len(s.GenericServerRunOptions.TlsPrivateKey) > 0 {
|
||||
err = http.ListenAndServeTLS(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.SecurePort), s.GenericServerRunOptions.TlsCertFile, s.GenericServerRunOptions.TlsPrivateKey, container)
|
||||
if err == nil {
|
||||
klog.V(0).Infof("Server listening on secure port %d.", s.GenericServerRunOptions.SecurePort)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func createDeps(s *options.ServerRunOptions, stopCh <-chan struct{}) *apiserver.Dependencies {
|
||||
deps := &apiserver.Dependencies{}
|
||||
|
||||
if s.KubernetesOptions == nil || s.KubernetesOptions.KubeConfig == "" {
|
||||
klog.Warning("kubeconfig not provided, will use in-cluster config")
|
||||
}
|
||||
|
||||
var err error
|
||||
deps.KubeClient, err = k8s.NewKubernetesClient(s.KubernetesOptions)
|
||||
if err != nil {
|
||||
klog.Fatalf("error happened when initializing kubernetes client, %v", err)
|
||||
}
|
||||
|
||||
if s.S3Options != nil && s.S3Options.Endpoint != "" {
|
||||
deps.S3, err = s3.NewS3Client(s.S3Options)
|
||||
if err != nil {
|
||||
klog.Fatalf("error initializing s3 client, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if s.OpenPitrixOptions != nil && !s.OpenPitrixOptions.IsEmpty() {
|
||||
deps.OpenPitrix, err = openpitrix.NewClient(s.OpenPitrixOptions)
|
||||
if err != nil {
|
||||
klog.Fatalf("error happened when initializing openpitrix client, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return deps
|
||||
|
||||
}
|
||||
|
||||
func WaitForResourceSync(stopCh <-chan struct{}) error {
|
||||
klog.V(0).Info("Start cache objects")
|
||||
|
||||
discoveryClient := client.ClientSets().K8s().Discovery()
|
||||
apiResourcesList, err := discoveryClient.ServerResources()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isResourceExists := func(resource schema.GroupVersionResource) bool {
|
||||
for _, apiResource := range apiResourcesList {
|
||||
if apiResource.GroupVersion == resource.GroupVersion().String() {
|
||||
for _, rsc := range apiResource.APIResources {
|
||||
if rsc.Name == resource.Resource {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
informerFactory := kinformers.NewInformerFactories(client.ClientSets().K8s().Kubernetes(), client.ClientSets().K8s().KubeSphere(), client.ClientSets().K8s().S2i(),
|
||||
client.ClientSets().K8s().Application())
|
||||
|
||||
// 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"},
|
||||
|
||||
{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"},
|
||||
|
||||
{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"},
|
||||
|
||||
{Group: "storage.k8s.io", Version: "v1", Resource: "storageclasses"},
|
||||
|
||||
{Group: "batch", Version: "v1", Resource: "jobs"},
|
||||
{Group: "batch", Version: "v1beta1", Resource: "cronjobs"},
|
||||
|
||||
{Group: "extensions", Version: "v1beta1", Resource: "ingresses"},
|
||||
|
||||
{Group: "autoscaling", Version: "v2beta2", Resource: "horizontalpodautoscalers"},
|
||||
}
|
||||
|
||||
for _, gvr := range k8sGVRs {
|
||||
if !isResourceExists(gvr) {
|
||||
klog.Warningf("resource %s not exists in the cluster", gvr)
|
||||
} else {
|
||||
_, err := informerFactory.KubernetesSharedInformerFactory().ForResource(gvr)
|
||||
if err != nil {
|
||||
klog.Errorf("cannot create informer for %s", gvr)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
informerFactory.KubernetesSharedInformerFactory().Start(stopCh)
|
||||
informerFactory.KubernetesSharedInformerFactory().WaitForCacheSync(stopCh)
|
||||
|
||||
s2iInformerFactory := informerFactory.S2iSharedInformerFactory()
|
||||
|
||||
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 {
|
||||
if !isResourceExists(gvr) {
|
||||
klog.Warningf("resource %s not exists in the cluster", gvr)
|
||||
} else {
|
||||
_, err := s2iInformerFactory.ForResource(gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s2iInformerFactory.Start(stopCh)
|
||||
s2iInformerFactory.WaitForCacheSync(stopCh)
|
||||
|
||||
ksInformerFactory := informerFactory.KubeSphereSharedInformerFactory()
|
||||
|
||||
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 {
|
||||
if !isResourceExists(gvr) {
|
||||
klog.Warningf("resource %s not exists in the cluster", gvr)
|
||||
} else {
|
||||
_, err := ksInformerFactory.ForResource(gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksInformerFactory.Start(stopCh)
|
||||
ksInformerFactory.WaitForCacheSync(stopCh)
|
||||
|
||||
appInformerFactory := informerFactory.ApplicationSharedInformerFactory()
|
||||
|
||||
appGVRs := []schema.GroupVersionResource{
|
||||
{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"},
|
||||
}
|
||||
|
||||
for _, gvr := range appGVRs {
|
||||
if !isResourceExists(gvr) {
|
||||
klog.Warningf("resource %s not exists in the cluster", gvr)
|
||||
} else {
|
||||
_, err := appInformerFactory.ForResource(gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appInformerFactory.Start(stopCh)
|
||||
appInformerFactory.WaitForCacheSync(stopCh)
|
||||
|
||||
klog.V(0).Info("Finished caching objects")
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// load options from config file
|
||||
func load() *options.ServerRunOptions {
|
||||
conf := apiserverconfig.Get()
|
||||
|
||||
return &options.ServerRunOptions{
|
||||
KubernetesOptions: conf.KubernetesOptions,
|
||||
DevopsOptions: conf.DevopsOptions,
|
||||
SonarQubeOptions: conf.SonarQubeOptions,
|
||||
ServiceMeshOptions: conf.ServiceMeshOptions,
|
||||
MySQLOptions: conf.MySQLOptions,
|
||||
MonitoringOptions: conf.MonitoringOptions,
|
||||
S3Options: conf.S3Options,
|
||||
OpenPitrixOptions: conf.OpenPitrixOptions,
|
||||
LoggingOptions: conf.LoggingOptions,
|
||||
}
|
||||
}
|
||||
|
||||
func initConfigz() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,32 +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 main
|
||||
|
||||
import (
|
||||
"kubesphere.io/kubesphere/cmd/ks-iam/app"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
cmd := app.NewAPIServerCommand()
|
||||
|
||||
if err := cmd.Execute(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
@@ -1,86 +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 options
|
||||
|
||||
import (
|
||||
"flag"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/klog"
|
||||
genericoptions "kubesphere.io/kubesphere/pkg/server/options"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/cache"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/ldap"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ServerRunOptions struct {
|
||||
GenericServerRunOptions *genericoptions.ServerRunOptions
|
||||
KubernetesOptions *k8s.KubernetesOptions
|
||||
LdapOptions *ldap.Options
|
||||
RedisOptions *cache.Options
|
||||
MySQLOptions *mysql.Options
|
||||
AdminEmail string
|
||||
AdminPassword string
|
||||
TokenIdleTimeout time.Duration
|
||||
JWTSecret string
|
||||
AuthRateLimit string
|
||||
EnableMultiLogin bool
|
||||
GenerateKubeConfig bool
|
||||
}
|
||||
|
||||
func NewServerRunOptions() *ServerRunOptions {
|
||||
s := &ServerRunOptions{
|
||||
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
|
||||
KubernetesOptions: k8s.NewKubernetesOptions(),
|
||||
LdapOptions: ldap.NewOptions(),
|
||||
MySQLOptions: mysql.NewMySQLOptions(),
|
||||
RedisOptions: cache.NewRedisOptions(),
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *ServerRunOptions) Flags(conf *ServerRunOptions) (fss cliflag.NamedFlagSets) {
|
||||
|
||||
fs := fss.FlagSet("generic")
|
||||
|
||||
s.GenericServerRunOptions.AddFlags(fs, conf.GenericServerRunOptions)
|
||||
fs.StringVar(&s.AdminEmail, "admin-email", "admin@kubesphere.io", "default administrator's email")
|
||||
fs.StringVar(&s.AdminPassword, "admin-password", "passw0rd", "default administrator's password")
|
||||
fs.DurationVar(&s.TokenIdleTimeout, "token-idle-timeout", 30*time.Minute, "tokens that are idle beyond that time will expire,0s means the token has no expiration time. valid time units are \"ns\",\"us\",\"ms\",\"s\",\"m\",\"h\"")
|
||||
fs.StringVar(&s.JWTSecret, "jwt-secret", "", "jwt secret")
|
||||
fs.StringVar(&s.AuthRateLimit, "auth-rate-limit", "5/30m", "specifies the maximum number of authentication attempts permitted and time interval,valid time units are \"s\",\"m\",\"h\"")
|
||||
fs.BoolVar(&s.EnableMultiLogin, "enable-multi-login", false, "allow one account to have multiple sessions")
|
||||
fs.BoolVar(&s.GenerateKubeConfig, "generate-kubeconfig", true, "generate kubeconfig for new users, kubeconfig is required in devops pipeline, set to false if you don't need devops.")
|
||||
|
||||
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), conf.KubernetesOptions)
|
||||
s.LdapOptions.AddFlags(fss.FlagSet("ldap"), conf.LdapOptions)
|
||||
s.RedisOptions.AddFlags(fss.FlagSet("redis"), conf.RedisOptions)
|
||||
s.MySQLOptions.AddFlags(fss.FlagSet("mysql"), conf.MySQLOptions)
|
||||
|
||||
kfs := 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)
|
||||
kfs.AddGoFlag(fl)
|
||||
})
|
||||
|
||||
return fss
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package options
|
||||
|
||||
func (s *ServerRunOptions) Validate() []error {
|
||||
errs := []error{}
|
||||
|
||||
errs = append(errs, s.KubernetesOptions.Validate()...)
|
||||
errs = append(errs, s.GenericServerRunOptions.Validate()...)
|
||||
errs = append(errs, s.LdapOptions.Validate()...)
|
||||
|
||||
return errs
|
||||
}
|
||||
@@ -1,156 +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 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/ks-iam/app/options"
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/kapis"
|
||||
"kubesphere.io/kubesphere/pkg/models/iam"
|
||||
"kubesphere.io/kubesphere/pkg/server"
|
||||
apiserverconfig "kubesphere.io/kubesphere/pkg/server/config"
|
||||
"kubesphere.io/kubesphere/pkg/server/filter"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client"
|
||||
"kubesphere.io/kubesphere/pkg/utils/jwtutil"
|
||||
"kubesphere.io/kubesphere/pkg/utils/signals"
|
||||
"kubesphere.io/kubesphere/pkg/utils/term"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func NewAPIServerCommand() *cobra.Command {
|
||||
s := options.NewServerRunOptions()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "ks-iam",
|
||||
Long: `The KubeSphere account 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 {
|
||||
|
||||
err := apiserverconfig.Load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if errs := s.Validate(); len(errs) != 0 {
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
return Run(s, signals.SetupSignalHandler())
|
||||
},
|
||||
}
|
||||
|
||||
conf := loadFromFile()
|
||||
|
||||
fs := cmd.Flags()
|
||||
namedFlagSets := s.Flags(conf)
|
||||
|
||||
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, stopChan <-chan struct{}) error {
|
||||
csop := client.NewClientSetOptions()
|
||||
csop.SetKubernetesOptions(s.KubernetesOptions).
|
||||
SetLdapOptions(s.LdapOptions).
|
||||
SetRedisOptions(s.RedisOptions).
|
||||
SetMySQLOptions(s.MySQLOptions)
|
||||
|
||||
client.NewClientSetFactory(csop, stopChan)
|
||||
|
||||
waitForResourceSync(stopChan)
|
||||
|
||||
err := iam.Init(s.AdminEmail, s.AdminPassword, s.AuthRateLimit, s.TokenIdleTimeout, s.EnableMultiLogin, s.GenerateKubeConfig)
|
||||
|
||||
jwtutil.Setup(s.JWTSecret)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
container := runtime.Container
|
||||
container.Filter(filter.Logging)
|
||||
container.DoNotRecover(false)
|
||||
container.RecoverHandler(server.LogStackOnRecover)
|
||||
|
||||
kapis.InstallAuthorizationAPIs(container)
|
||||
|
||||
if s.GenericServerRunOptions.InsecurePort != 0 {
|
||||
klog.Infof("Server listening on %s:%d ", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort)
|
||||
err = http.ListenAndServe(fmt.Sprintf("%s:%d", s.GenericServerRunOptions.BindAddress, s.GenericServerRunOptions.InsecurePort), container)
|
||||
}
|
||||
|
||||
if s.GenericServerRunOptions.SecurePort != 0 && len(s.GenericServerRunOptions.TlsCertFile) > 0 && len(s.GenericServerRunOptions.TlsPrivateKey) > 0 {
|
||||
klog.Infof("Server listening on %s:%d", s.GenericServerRunOptions.BindAddress, 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 loadFromFile() *options.ServerRunOptions {
|
||||
err := apiserverconfig.Load()
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
|
||||
conf := apiserverconfig.Get()
|
||||
|
||||
return &options.ServerRunOptions{
|
||||
KubernetesOptions: conf.KubernetesOptions,
|
||||
LdapOptions: conf.LdapOptions,
|
||||
RedisOptions: conf.RedisOptions,
|
||||
MySQLOptions: conf.MySQLOptions,
|
||||
}
|
||||
}
|
||||
|
||||
func waitForResourceSync(stopCh <-chan struct{}) {
|
||||
|
||||
informerFactory := informers.SharedInformerFactory()
|
||||
informerFactory.Rbac().V1().Roles().Lister()
|
||||
informerFactory.Rbac().V1().RoleBindings().Lister()
|
||||
informerFactory.Rbac().V1().ClusterRoles().Lister()
|
||||
informerFactory.Rbac().V1().ClusterRoleBindings().Lister()
|
||||
|
||||
informerFactory.Core().V1().Namespaces().Lister()
|
||||
|
||||
informerFactory.Start(stopCh)
|
||||
informerFactory.WaitForCacheSync(stopCh)
|
||||
|
||||
ksInformerFactory := informers.KsSharedInformerFactory()
|
||||
ksInformerFactory.Tenant().V1alpha1().Workspaces().Lister()
|
||||
|
||||
ksInformerFactory.Start(stopCh)
|
||||
ksInformerFactory.WaitForCacheSync(stopCh)
|
||||
}
|
||||
Reference in New Issue
Block a user