未验证 提交 eceadec6 编写于 作者: Z zryfish 提交者: GitHub

devlopment branch (#1736)

上级 ff0ffe86
...@@ -10,16 +10,16 @@ import ( ...@@ -10,16 +10,16 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/devops" "kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s" "kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix" "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3" "kubesphere.io/kubesphere/pkg/simple/client/s3"
"strings" "strings"
"time" "time"
) )
type KubeSphereControllerManagerOptions struct { type KubeSphereControllerManagerOptions struct {
KubernetesOptions *k8s.KubernetesOptions KubernetesOptions *k8s.KubernetesOptions
DevopsOptions *devops.DevopsOptions DevopsOptions *devops.Options
S3Options *s2is3.S3Options S3Options *s3.Options
OpenPitrixOptions *openpitrix.OpenPitrixOptions OpenPitrixOptions *openpitrix.Options
LeaderElection *leaderelection.LeaderElectionConfig LeaderElection *leaderelection.LeaderElectionConfig
} }
...@@ -28,7 +28,7 @@ func NewKubeSphereControllerManagerOptions() *KubeSphereControllerManagerOptions ...@@ -28,7 +28,7 @@ func NewKubeSphereControllerManagerOptions() *KubeSphereControllerManagerOptions
s := &KubeSphereControllerManagerOptions{ s := &KubeSphereControllerManagerOptions{
KubernetesOptions: k8s.NewKubernetesOptions(), KubernetesOptions: k8s.NewKubernetesOptions(),
DevopsOptions: devops.NewDevopsOptions(), DevopsOptions: devops.NewDevopsOptions(),
S3Options: s2is3.NewS3Options(), S3Options: s3.NewS3Options(),
OpenPitrixOptions: openpitrix.NewOpenPitrixOptions(), OpenPitrixOptions: openpitrix.NewOpenPitrixOptions(),
LeaderElection: &leaderelection.LeaderElectionConfig{ LeaderElection: &leaderelection.LeaderElectionConfig{
LeaseDuration: 30 * time.Second, LeaseDuration: 30 * time.Second,
...@@ -47,13 +47,13 @@ func (s *KubeSphereControllerManagerOptions) ApplyTo(conf *kubesphereconfig.Conf ...@@ -47,13 +47,13 @@ func (s *KubeSphereControllerManagerOptions) ApplyTo(conf *kubesphereconfig.Conf
s.OpenPitrixOptions.ApplyTo(conf.OpenPitrixOptions) s.OpenPitrixOptions.ApplyTo(conf.OpenPitrixOptions)
} }
func (s *KubeSphereControllerManagerOptions) Flags() cliflag.NamedFlagSets { func (s *KubeSphereControllerManagerOptions) Flags(o *KubeSphereControllerManagerOptions) cliflag.NamedFlagSets {
fss := cliflag.NamedFlagSets{} fss := cliflag.NamedFlagSets{}
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes")) s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), o.KubernetesOptions)
s.DevopsOptions.AddFlags(fss.FlagSet("devops")) s.DevopsOptions.AddFlags(fss.FlagSet("devops"), o.DevopsOptions)
s.S3Options.AddFlags(fss.FlagSet("s3")) s.S3Options.AddFlags(fss.FlagSet("s3"), o.S3Options)
s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix")) s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix"), o.OpenPitrixOptions)
fs := fss.FlagSet("leaderelection") fs := fss.FlagSet("leaderelection")
s.bindLeaderElectionFlags(s.LeaderElection, fs) s.bindLeaderElectionFlags(s.LeaderElection, fs)
......
...@@ -69,8 +69,10 @@ func NewControllerManagerCommand() *cobra.Command { ...@@ -69,8 +69,10 @@ func NewControllerManagerCommand() *cobra.Command {
}, },
} }
conf := loadConfFromFile()
fs := cmd.Flags() fs := cmd.Flags()
namedFlagSets := s.Flags() namedFlagSets := s.Flags(conf)
for _, f := range namedFlagSets.FlagSets { for _, f := range namedFlagSets.FlagSets {
fs.AddFlagSet(f) fs.AddFlagSet(f)
...@@ -119,6 +121,22 @@ func CreateClientSet(conf *controllerconfig.Config, stopCh <-chan struct{}) erro ...@@ -119,6 +121,22 @@ func CreateClientSet(conf *controllerconfig.Config, stopCh <-chan struct{}) erro
return nil 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 { func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{}) error {
err := CreateClientSet(controllerconfig.Get(), stopCh) err := CreateClientSet(controllerconfig.Get(), stopCh)
if err != nil { if err != nil {
......
...@@ -11,24 +11,24 @@ import ( ...@@ -11,24 +11,24 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/mysql" "kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix" "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/prometheus" "kubesphere.io/kubesphere/pkg/simple/client/prometheus"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3" "kubesphere.io/kubesphere/pkg/simple/client/s3"
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh" "kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube" "kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"strings" "strings"
) )
type ServerRunOptions struct { type ServerRunOptions struct {
ConfigFile string
GenericServerRunOptions *genericoptions.ServerRunOptions GenericServerRunOptions *genericoptions.ServerRunOptions
KubernetesOptions *k8s.KubernetesOptions
KubernetesOptions *k8s.KubernetesOptions DevopsOptions *devops.Options
DevopsOptions *devops.DevopsOptions SonarQubeOptions *sonarqube.Options
SonarQubeOptions *sonarqube.SonarQubeOptions ServiceMeshOptions *servicemesh.Options
ServiceMeshOptions *servicemesh.ServiceMeshOptions MySQLOptions *mysql.Options
MySQLOptions *mysql.MySQLOptions MonitoringOptions *prometheus.Options
MonitoringOptions *prometheus.PrometheusOptions S3Options *s3.Options
S3Options *s2is3.S3Options OpenPitrixOptions *openpitrix.Options
OpenPitrixOptions *openpitrix.OpenPitrixOptions LoggingOptions *esclient.Options
LoggingOptions *esclient.ElasticSearchOptions
} }
func NewServerRunOptions() *ServerRunOptions { func NewServerRunOptions() *ServerRunOptions {
...@@ -41,7 +41,7 @@ func NewServerRunOptions() *ServerRunOptions { ...@@ -41,7 +41,7 @@ func NewServerRunOptions() *ServerRunOptions {
ServiceMeshOptions: servicemesh.NewServiceMeshOptions(), ServiceMeshOptions: servicemesh.NewServiceMeshOptions(),
MySQLOptions: mysql.NewMySQLOptions(), MySQLOptions: mysql.NewMySQLOptions(),
MonitoringOptions: prometheus.NewPrometheusOptions(), MonitoringOptions: prometheus.NewPrometheusOptions(),
S3Options: s2is3.NewS3Options(), S3Options: s3.NewS3Options(),
OpenPitrixOptions: openpitrix.NewOpenPitrixOptions(), OpenPitrixOptions: openpitrix.NewOpenPitrixOptions(),
LoggingOptions: esclient.NewElasticSearchOptions(), LoggingOptions: esclient.NewElasticSearchOptions(),
} }
...@@ -49,18 +49,17 @@ func NewServerRunOptions() *ServerRunOptions { ...@@ -49,18 +49,17 @@ func NewServerRunOptions() *ServerRunOptions {
return &s return &s
} }
func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) { func (s *ServerRunOptions) Flags(c *ServerRunOptions) (fss cliflag.NamedFlagSets) {
s.GenericServerRunOptions.AddFlags(fss.FlagSet("generic"), c.GenericServerRunOptions)
s.GenericServerRunOptions.AddFlags(fss.FlagSet("generic")) s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), c.KubernetesOptions)
s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes")) s.MySQLOptions.AddFlags(fss.FlagSet("mysql"), c.MySQLOptions)
s.MySQLOptions.AddFlags(fss.FlagSet("mysql")) s.DevopsOptions.AddFlags(fss.FlagSet("devops"), c.DevopsOptions)
s.DevopsOptions.AddFlags(fss.FlagSet("devops")) s.SonarQubeOptions.AddFlags(fss.FlagSet("sonarqube"), c.SonarQubeOptions)
s.SonarQubeOptions.AddFlags(fss.FlagSet("sonarqube")) s.S3Options.AddFlags(fss.FlagSet("s3"), c.S3Options)
s.S3Options.AddFlags(fss.FlagSet("s3")) s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix"), c.OpenPitrixOptions)
s.OpenPitrixOptions.AddFlags(fss.FlagSet("openpitrix")) s.ServiceMeshOptions.AddFlags(fss.FlagSet("servicemesh"), c.ServiceMeshOptions)
s.ServiceMeshOptions.AddFlags(fss.FlagSet("servicemesh")) s.MonitoringOptions.AddFlags(fss.FlagSet("monitoring"), c.MonitoringOptions)
s.MonitoringOptions.AddFlags(fss.FlagSet("monitoring")) s.LoggingOptions.AddFlags(fss.FlagSet("logging"), c.LoggingOptions)
s.LoggingOptions.AddFlags(fss.FlagSet("logging"))
fs := fss.FlagSet("klog") fs := fss.FlagSet("klog")
local := flag.NewFlagSet("klog", flag.ExitOnError) local := flag.NewFlagSet("klog", flag.ExitOnError)
......
...@@ -26,14 +26,18 @@ import ( ...@@ -26,14 +26,18 @@ import (
cliflag "k8s.io/component-base/cli/flag" cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/cmd/ks-apiserver/app/options" "kubesphere.io/kubesphere/cmd/ks-apiserver/app/options"
"kubesphere.io/kubesphere/pkg/apiserver"
"kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/apiserver/servicemesh/tracing" "kubesphere.io/kubesphere/pkg/apiserver/servicemesh/tracing"
"kubesphere.io/kubesphere/pkg/informers" kinformers "kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/kapis" "kubesphere.io/kubesphere/pkg/kapis"
"kubesphere.io/kubesphere/pkg/server" "kubesphere.io/kubesphere/pkg/server"
apiserverconfig "kubesphere.io/kubesphere/pkg/server/config" apiserverconfig "kubesphere.io/kubesphere/pkg/server/config"
"kubesphere.io/kubesphere/pkg/server/filter" "kubesphere.io/kubesphere/pkg/server/filter"
"kubesphere.io/kubesphere/pkg/simple/client" "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/signals"
"kubesphere.io/kubesphere/pkg/utils/term" "kubesphere.io/kubesphere/pkg/utils/term"
"net/http" "net/http"
...@@ -48,16 +52,6 @@ func NewAPIServerCommand() *cobra.Command { ...@@ -48,16 +52,6 @@ func NewAPIServerCommand() *cobra.Command {
The API Server services REST operations and provides the frontend to the The API Server services REST operations and provides the frontend to the
cluster's shared state through which all other components interact.`, cluster's shared state through which all other components interact.`,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := apiserverconfig.Load()
if err != nil {
return err
}
err = Complete(s)
if err != nil {
return err
}
if errs := s.Validate(); len(errs) != 0 { if errs := s.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs) return utilerrors.NewAggregate(errs)
} }
...@@ -66,8 +60,10 @@ cluster's shared state through which all other components interact.`, ...@@ -66,8 +60,10 @@ cluster's shared state through which all other components interact.`,
}, },
} }
configOptions := load()
fs := cmd.Flags() fs := cmd.Flags()
namedFlagSets := s.Flags() namedFlagSets := s.Flags(configOptions)
for _, f := range namedFlagSets.FlagSets { for _, f := range namedFlagSets.FlagSets {
fs.AddFlagSet(f) fs.AddFlagSet(f)
...@@ -125,9 +121,13 @@ func initializeServicemeshConfig(s *options.ServerRunOptions) { ...@@ -125,9 +121,13 @@ func initializeServicemeshConfig(s *options.ServerRunOptions) {
} }
// //
func CreateAPIServer(s *options.ServerRunOptions) error { func CreateAPIServer(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
var err error var err error
deps := createDeps(s, stopCh)
apiserver := apiserver.New(deps)
container := runtime.Container container := runtime.Container
container.DoNotRecover(false) container.DoNotRecover(false)
container.Filter(filter.Logging) container.Filter(filter.Logging)
...@@ -155,23 +155,35 @@ func CreateAPIServer(s *options.ServerRunOptions) error { ...@@ -155,23 +155,35 @@ func CreateAPIServer(s *options.ServerRunOptions) error {
return err return err
} }
func CreateClientSet(conf *apiserverconfig.Config, stopCh <-chan struct{}) error { func createDeps(s *options.ServerRunOptions, stopCh <-chan struct{}) *apiserver.Dependencies {
csop := &client.ClientSetOptions{} deps := &apiserver.Dependencies{}
csop.SetDevopsOptions(conf.DevopsOptions). if s.KubernetesOptions == nil || s.KubernetesOptions.KubeConfig == "" {
SetSonarQubeOptions(conf.SonarQubeOptions). klog.Warning("kubeconfig not provided, will use in-cluster config")
SetKubernetesOptions(conf.KubernetesOptions). }
SetMySQLOptions(conf.MySQLOptions).
SetLdapOptions(conf.LdapOptions).
SetS3Options(conf.S3Options).
SetOpenPitrixOptions(conf.OpenPitrixOptions).
SetPrometheusOptions(conf.MonitoringOptions).
SetKubeSphereOptions(conf.KubeSphereOptions).
SetElasticSearchOptions(conf.LoggingOptions)
client.NewClientSetFactory(csop, stopCh) 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.NewOpenPitrixClient(s.OpenPitrixOptions)
if err != nil {
klog.Fatalf("error happened when initializing openpitrix client, %v", err)
}
}
return deps
return nil
} }
func WaitForResourceSync(stopCh <-chan struct{}) error { func WaitForResourceSync(stopCh <-chan struct{}) error {
...@@ -196,7 +208,8 @@ func WaitForResourceSync(stopCh <-chan struct{}) error { ...@@ -196,7 +208,8 @@ func WaitForResourceSync(stopCh <-chan struct{}) error {
return false return false
} }
informerFactory := informers.SharedInformerFactory() 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 // resources we have to create informer first
k8sGVRs := []schema.GroupVersionResource{ k8sGVRs := []schema.GroupVersionResource{
...@@ -234,7 +247,7 @@ func WaitForResourceSync(stopCh <-chan struct{}) error { ...@@ -234,7 +247,7 @@ func WaitForResourceSync(stopCh <-chan struct{}) error {
if !isResourceExists(gvr) { if !isResourceExists(gvr) {
klog.Warningf("resource %s not exists in the cluster", gvr) klog.Warningf("resource %s not exists in the cluster", gvr)
} else { } else {
_, err := informerFactory.ForResource(gvr) _, err := informerFactory.KubernetesSharedInformerFactory().ForResource(gvr)
if err != nil { if err != nil {
klog.Errorf("cannot create informer for %s", gvr) klog.Errorf("cannot create informer for %s", gvr)
return err return err
...@@ -242,10 +255,10 @@ func WaitForResourceSync(stopCh <-chan struct{}) error { ...@@ -242,10 +255,10 @@ func WaitForResourceSync(stopCh <-chan struct{}) error {
} }
} }
informerFactory.Start(stopCh) informerFactory.KubernetesSharedInformerFactory().Start(stopCh)
informerFactory.WaitForCacheSync(stopCh) informerFactory.KubernetesSharedInformerFactory().WaitForCacheSync(stopCh)
s2iInformerFactory := informers.S2iSharedInformerFactory() s2iInformerFactory := informerFactory.S2iSharedInformerFactory()
s2iGVRs := []schema.GroupVersionResource{ s2iGVRs := []schema.GroupVersionResource{
{Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuildertemplates"}, {Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuildertemplates"},
...@@ -267,7 +280,7 @@ func WaitForResourceSync(stopCh <-chan struct{}) error { ...@@ -267,7 +280,7 @@ func WaitForResourceSync(stopCh <-chan struct{}) error {
s2iInformerFactory.Start(stopCh) s2iInformerFactory.Start(stopCh)
s2iInformerFactory.WaitForCacheSync(stopCh) s2iInformerFactory.WaitForCacheSync(stopCh)
ksInformerFactory := informers.KsSharedInformerFactory() ksInformerFactory := informerFactory.KubeSphereSharedInformerFactory()
ksGVRs := []schema.GroupVersionResource{ ksGVRs := []schema.GroupVersionResource{
{Group: "tenant.kubesphere.io", Version: "v1alpha1", Resource: "workspaces"}, {Group: "tenant.kubesphere.io", Version: "v1alpha1", Resource: "workspaces"},
...@@ -291,7 +304,7 @@ func WaitForResourceSync(stopCh <-chan struct{}) error { ...@@ -291,7 +304,7 @@ func WaitForResourceSync(stopCh <-chan struct{}) error {
ksInformerFactory.Start(stopCh) ksInformerFactory.Start(stopCh)
ksInformerFactory.WaitForCacheSync(stopCh) ksInformerFactory.WaitForCacheSync(stopCh)
appInformerFactory := informers.AppSharedInformerFactory() appInformerFactory := informerFactory.ApplicationSharedInformerFactory()
appGVRs := []schema.GroupVersionResource{ appGVRs := []schema.GroupVersionResource{
{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"}, {Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"},
...@@ -317,36 +330,23 @@ func WaitForResourceSync(stopCh <-chan struct{}) error { ...@@ -317,36 +330,23 @@ func WaitForResourceSync(stopCh <-chan struct{}) error {
} }
// apply server run options to configuration // load options from config file
func Complete(s *options.ServerRunOptions) error { func load() *options.ServerRunOptions {
// loading configuration file
conf := apiserverconfig.Get() conf := apiserverconfig.Get()
conf.Apply(&apiserverconfig.Config{ return &options.ServerRunOptions{
MySQLOptions: s.MySQLOptions, KubernetesOptions: conf.KubernetesOptions,
DevopsOptions: s.DevopsOptions, DevopsOptions: conf.DevopsOptions,
SonarQubeOptions: s.SonarQubeOptions, SonarQubeOptions: conf.SonarQubeOptions,
KubernetesOptions: s.KubernetesOptions, ServiceMeshOptions: conf.ServiceMeshOptions,
ServiceMeshOptions: s.ServiceMeshOptions, MySQLOptions: conf.MySQLOptions,
MonitoringOptions: s.MonitoringOptions, MonitoringOptions: conf.MonitoringOptions,
S3Options: s.S3Options, S3Options: conf.S3Options,
OpenPitrixOptions: s.OpenPitrixOptions, OpenPitrixOptions: conf.OpenPitrixOptions,
LoggingOptions: s.LoggingOptions, LoggingOptions: conf.LoggingOptions,
})
*s = options.ServerRunOptions{
GenericServerRunOptions: s.GenericServerRunOptions,
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 return nil
} }
...@@ -22,10 +22,10 @@ import ( ...@@ -22,10 +22,10 @@ import (
cliflag "k8s.io/component-base/cli/flag" cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog" "k8s.io/klog"
genericoptions "kubesphere.io/kubesphere/pkg/server/options" 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/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/ldap" "kubesphere.io/kubesphere/pkg/simple/client/ldap"
"kubesphere.io/kubesphere/pkg/simple/client/mysql" "kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
"strings" "strings"
"time" "time"
) )
...@@ -33,9 +33,9 @@ import ( ...@@ -33,9 +33,9 @@ import (
type ServerRunOptions struct { type ServerRunOptions struct {
GenericServerRunOptions *genericoptions.ServerRunOptions GenericServerRunOptions *genericoptions.ServerRunOptions
KubernetesOptions *k8s.KubernetesOptions KubernetesOptions *k8s.KubernetesOptions
LdapOptions *ldap.LdapOptions LdapOptions *ldap.Options
RedisOptions *redis.RedisOptions RedisOptions *cache.Options
MySQLOptions *mysql.MySQLOptions MySQLOptions *mysql.Options
AdminEmail string AdminEmail string
AdminPassword string AdminPassword string
TokenIdleTimeout time.Duration TokenIdleTimeout time.Duration
...@@ -51,16 +51,16 @@ func NewServerRunOptions() *ServerRunOptions { ...@@ -51,16 +51,16 @@ func NewServerRunOptions() *ServerRunOptions {
KubernetesOptions: k8s.NewKubernetesOptions(), KubernetesOptions: k8s.NewKubernetesOptions(),
LdapOptions: ldap.NewLdapOptions(), LdapOptions: ldap.NewLdapOptions(),
MySQLOptions: mysql.NewMySQLOptions(), MySQLOptions: mysql.NewMySQLOptions(),
RedisOptions: redis.NewRedisOptions(), RedisOptions: cache.NewRedisOptions(),
} }
return s return s
} }
func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) { func (s *ServerRunOptions) Flags(conf *ServerRunOptions) (fss cliflag.NamedFlagSets) {
fs := fss.FlagSet("generic") fs := fss.FlagSet("generic")
s.GenericServerRunOptions.AddFlags(fs) s.GenericServerRunOptions.AddFlags(fs, conf.GenericServerRunOptions)
fs.StringVar(&s.AdminEmail, "admin-email", "admin@kubesphere.io", "default administrator's email") 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.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.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\"")
...@@ -69,10 +69,10 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) { ...@@ -69,10 +69,10 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
fs.BoolVar(&s.EnableMultiLogin, "enable-multi-login", false, "allow one account to have multiple sessions") 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.") 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")) s.KubernetesOptions.AddFlags(fss.FlagSet("kubernetes"), conf.KubernetesOptions)
s.LdapOptions.AddFlags(fss.FlagSet("ldap")) s.LdapOptions.AddFlags(fss.FlagSet("ldap"), conf.LdapOptions)
s.RedisOptions.AddFlags(fss.FlagSet("redis")) s.RedisOptions.AddFlags(fss.FlagSet("redis"), conf.RedisOptions)
s.MySQLOptions.AddFlags(fss.FlagSet("mysql")) s.MySQLOptions.AddFlags(fss.FlagSet("mysql"), conf.MySQLOptions)
kfs := fss.FlagSet("klog") kfs := fss.FlagSet("klog")
local := flag.NewFlagSet("klog", flag.ExitOnError) local := flag.NewFlagSet("klog", flag.ExitOnError)
......
...@@ -53,11 +53,6 @@ cluster's shared state through which all other components interact.`, ...@@ -53,11 +53,6 @@ cluster's shared state through which all other components interact.`,
return err return err
} }
err = Complete(s)
if err != nil {
return err
}
if errs := s.Validate(); len(errs) != 0 { if errs := s.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs) return utilerrors.NewAggregate(errs)
} }
...@@ -66,8 +61,10 @@ cluster's shared state through which all other components interact.`, ...@@ -66,8 +61,10 @@ cluster's shared state through which all other components interact.`,
}, },
} }
conf := loadFromFile()
fs := cmd.Flags() fs := cmd.Flags()
namedFlagSets := s.Flags() namedFlagSets := s.Flags(conf)
for _, f := range namedFlagSets.FlagSets { for _, f := range namedFlagSets.FlagSets {
fs.AddFlagSet(f) fs.AddFlagSet(f)
...@@ -122,22 +119,20 @@ func Run(s *options.ServerRunOptions, stopChan <-chan struct{}) error { ...@@ -122,22 +119,20 @@ func Run(s *options.ServerRunOptions, stopChan <-chan struct{}) error {
return err return err
} }
func Complete(s *options.ServerRunOptions) error { func loadFromFile() *options.ServerRunOptions {
conf := apiserverconfig.Get() err := apiserverconfig.Load()
if err != nil {
conf.Apply(&apiserverconfig.Config{ klog.Fatal(err)
KubernetesOptions: s.KubernetesOptions, }
LdapOptions: s.LdapOptions,
RedisOptions: s.RedisOptions,
MySQLOptions: s.MySQLOptions,
})
s.KubernetesOptions = conf.KubernetesOptions conf := apiserverconfig.Get()
s.LdapOptions = conf.LdapOptions
s.RedisOptions = conf.RedisOptions
s.MySQLOptions = conf.MySQLOptions
return nil return &options.ServerRunOptions{
KubernetesOptions: conf.KubernetesOptions,
LdapOptions: conf.LdapOptions,
RedisOptions: conf.RedisOptions,
MySQLOptions: conf.MySQLOptions,
}
} }
func waitForResourceSync(stopCh <-chan struct{}) { func waitForResourceSync(stopCh <-chan struct{}) {
......
...@@ -40,6 +40,7 @@ require ( ...@@ -40,6 +40,7 @@ require (
github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6 github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6
github.com/golang/example v0.0.0-20170904185048-46695d81d1fa github.com/golang/example v0.0.0-20170904185048-46695d81d1fa
github.com/golang/protobuf v1.3.2 github.com/golang/protobuf v1.3.2
github.com/google/go-cmp v0.3.0
github.com/google/go-querystring v1.0.0 // indirect github.com/google/go-querystring v1.0.0 // indirect
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
github.com/gophercloud/gophercloud v0.3.0 // indirect github.com/gophercloud/gophercloud v0.3.0 // indirect
...@@ -63,8 +64,8 @@ require ( ...@@ -63,8 +64,8 @@ require (
github.com/mholt/certmagic v0.5.1 // indirect github.com/mholt/certmagic v0.5.1 // indirect
github.com/miekg/dns v1.1.9 // indirect github.com/miekg/dns v1.1.9 // indirect
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
github.com/onsi/ginkgo v1.8.0 github.com/onsi/ginkgo v1.10.1
github.com/onsi/gomega v1.5.0 github.com/onsi/gomega v1.7.0
github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec v1.0.1 // indirect github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/openshift/api v3.9.0+incompatible // indirect github.com/openshift/api v3.9.0+incompatible // indirect
...@@ -87,16 +88,16 @@ require ( ...@@ -87,16 +88,16 @@ require (
gopkg.in/yaml.v2 v2.2.4 gopkg.in/yaml.v2 v2.2.4
istio.io/api v0.0.0-20191111210003-35e06ef8d838 istio.io/api v0.0.0-20191111210003-35e06ef8d838
istio.io/client-go v0.0.0-20191113122552-9bd0ba57c3d2 istio.io/client-go v0.0.0-20191113122552-9bd0ba57c3d2
k8s.io/api v0.0.0-20191114100352-16d7abae0d2a k8s.io/api v0.17.0
k8s.io/apiextensions-apiserver v0.0.0-20191114105449-027877536833 k8s.io/apiextensions-apiserver v0.0.0-20191114105449-027877536833
k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb k8s.io/apimachinery v0.17.0
k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682 k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682
k8s.io/client-go v0.0.0-20191114101535-6c5935290e33 k8s.io/client-go v0.17.0
k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894 k8s.io/code-generator v0.17.0
k8s.io/component-base v0.0.0-20191114102325-35a9586014f7 k8s.io/component-base v0.17.0
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f // indirect k8s.io/kubectl v0.17.0
kubesphere.io/im v0.1.0 // indirect kubesphere.io/im v0.1.0 // indirect
openpitrix.io/iam v0.1.0 // indirect openpitrix.io/iam v0.1.0 // indirect
openpitrix.io/openpitrix v0.4.1-0.20190920134345-4d2be6e4965c openpitrix.io/openpitrix v0.4.1-0.20190920134345-4d2be6e4965c
......
...@@ -18,6 +18,8 @@ github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VY ...@@ -18,6 +18,8 @@ github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VY
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc= github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
...@@ -60,6 +62,8 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR ...@@ -60,6 +62,8 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
...@@ -77,6 +81,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc ...@@ -77,6 +81,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
...@@ -115,6 +120,8 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3 ...@@ -115,6 +120,8 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
...@@ -191,6 +198,9 @@ github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= ...@@ -191,6 +198,9 @@ github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
...@@ -213,6 +223,7 @@ github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU= ...@@ -213,6 +223,7 @@ github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU=
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 h1:6TSoaYExHper8PYsJu23GWVNOyYRCSnIFyxKgLSZ54w=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
...@@ -285,6 +296,9 @@ github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= ...@@ -285,6 +296,9 @@ github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/lucas-clemente/quic-go v0.11.1 h1:zasajC848Dqq/+WqfqBCkmPw+YHNe1MBts/z7y7nXf4= github.com/lucas-clemente/quic-go v0.11.1 h1:zasajC848Dqq/+WqfqBCkmPw+YHNe1MBts/z7y7nXf4=
github.com/lucas-clemente/quic-go v0.11.1/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lucas-clemente/quic-go v0.11.1/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
...@@ -309,6 +323,8 @@ github.com/miekg/dns v1.1.9 h1:OIdC9wT96RzuZMf2PfKRhFgsStHUUBZLM/lo1LqiM9E= ...@@ -309,6 +323,8 @@ github.com/miekg/dns v1.1.9 h1:OIdC9wT96RzuZMf2PfKRhFgsStHUUBZLM/lo1LqiM9E=
github.com/miekg/dns v1.1.9/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.9/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
...@@ -343,6 +359,7 @@ github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWo ...@@ -343,6 +359,7 @@ github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWo
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 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/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
...@@ -416,6 +433,7 @@ github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70 ...@@ -416,6 +433,7 @@ github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
...@@ -517,6 +535,8 @@ k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb h1:ZUNsbuPdXWrj0rZziRfCWc ...@@ -517,6 +535,8 @@ k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb h1:ZUNsbuPdXWrj0rZziRfCWc
k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ= k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ=
k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682 h1:+FvAOv/4JyYgZanQI8h+UW9FCmLzyEz7EZunuET6p5g= k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682 h1:+FvAOv/4JyYgZanQI8h+UW9FCmLzyEz7EZunuET6p5g=
k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682/go.mod h1:Idob8Va6/sMX5SmwPLsU0pdvFlkwxuJ5x+fXMG8NbKE= k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682/go.mod h1:Idob8Va6/sMX5SmwPLsU0pdvFlkwxuJ5x+fXMG8NbKE=
k8s.io/cli-runtime v0.17.0 h1:XEuStbJBHCQlEKFyTQmceDKEWOSYHZkcYWKp3SsQ9Hk=
k8s.io/cli-runtime v0.17.0/go.mod h1:1E5iQpMODZq2lMWLUJELwRu2MLWIzwvMgDBpn3Y81Qo=
k8s.io/client-go v0.0.0-20191114101535-6c5935290e33 h1:07mhG/2oEoo3N+sHVOo0L9PJ/qvbk3N5n2dj8IWefnQ= k8s.io/client-go v0.0.0-20191114101535-6c5935290e33 h1:07mhG/2oEoo3N+sHVOo0L9PJ/qvbk3N5n2dj8IWefnQ=
k8s.io/client-go v0.0.0-20191114101535-6c5935290e33/go.mod h1:4L/zQOBkEf4pArQJ+CMk1/5xjA30B5oyWv+Bzb44DOw= k8s.io/client-go v0.0.0-20191114101535-6c5935290e33/go.mod h1:4L/zQOBkEf4pArQJ+CMk1/5xjA30B5oyWv+Bzb44DOw=
k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894 h1:NMYlxaF7rYQJk2E2IyrUhaX81zX24+dmoZdkPw0gJqI= k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894 h1:NMYlxaF7rYQJk2E2IyrUhaX81zX24+dmoZdkPw0gJqI=
...@@ -529,6 +549,9 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= ...@@ -529,6 +549,9 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kubectl v0.17.0 h1:xD4EWlL+epc/JTO1gvSjmV9yiYF0Z2wiHK2DIek6URY=
k8s.io/kubectl v0.17.0/go.mod h1:jIPrUAW656Vzn9wZCCe0PC+oTcu56u2HgFD21Xbfk1s=
k8s.io/metrics v0.17.0/go.mod h1:EH1D3YAwN6d7bMelrElnLhLg72l/ERStyv2SIQVt6Do=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
kubesphere.io/application v0.0.0-20190404151855-67ae7f915d4e/go.mod h1:NhUQ0ZUdFz8NTQ+SvQG0JUKAn+q71v3TPExjsjRPIZI= kubesphere.io/application v0.0.0-20190404151855-67ae7f915d4e/go.mod h1:NhUQ0ZUdFz8NTQ+SvQG0JUKAn+q71v3TPExjsjRPIZI=
...@@ -549,9 +572,13 @@ sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9 ...@@ -549,9 +572,13 @@ sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns= sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
sigs.k8s.io/controller-tools v0.2.4 h1:la1h46EzElvWefWLqfsXrnsO3lZjpkI0asTpX6h8PLA= sigs.k8s.io/controller-tools v0.2.4 h1:la1h46EzElvWefWLqfsXrnsO3lZjpkI0asTpX6h8PLA=
sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA=
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ= sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM= sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w= sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc h1:MksmcCZQWAQJCTA5T0jgI/0sJ51AVm4Z41MrmfczEoc=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
#!/bin/bash #!/bin/bash
set -e set -e
GV="network:v1alpha1 servicemesh:v1alpha2 tenant:v1alpha1 devops:v1alpha1" GV="network:v1alpha1 servicemesh:v1alpha2 tenant:v1alpha1 devops:v1alpha1 logging:v1alpha2"
rm -rf ./pkg/client rm -rf ./pkg/client
./hack/generate_group.sh "client,lister,informer" kubesphere.io/kubesphere/pkg/client kubesphere.io/kubesphere/pkg/apis "$GV" --output-base=./ -h "$PWD/hack/boilerplate.go.txt" ./hack/generate_group.sh "client,lister,informer" kubesphere.io/kubesphere/pkg/client kubesphere.io/kubesphere/pkg/apis "$GV" --output-base=./ -h "$PWD/hack/boilerplate.go.txt"
......
package v1alpha2
import "time"
// ComponentStatus represents system component status.
type ComponentStatus struct {
Name string `json:"name" description:"component name"`
Namespace string `json:"namespace" description:"the name of the namespace"`
SelfLink string `json:"selfLink" description:"self link"`
Label interface{} `json:"label" description:"labels"`
StartedAt time.Time `json:"startedAt" description:"started time"`
TotalBackends int `json:"totalBackends" description:"the total replicas of each backend system component"`
HealthyBackends int `json:"healthyBackends" description:"the number of healthy backend components"`
}
// NodeStatus assembles cluster nodes status, simply wrap unhealthy and total nodes.
type NodeStatus struct {
// total nodes of cluster, including master nodes
TotalNodes int `json:"totalNodes" description:"total number of nodes"`
// healthy nodes means nodes whose state is NodeReady
HealthyNodes int `json:"healthyNodes" description:"the number of healthy nodes"`
}
//
type HealthStatus struct {
KubeSphereComponents []ComponentStatus `json:"kubesphereStatus" description:"kubesphere components status"`
NodeStatus NodeStatus `json:"nodeStatus" description:"nodes status"`
}
package api
import (
"github.com/emicklei/go-restful"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"net/http"
)
type ListResult struct {
Items []interface{} `json:"items,omitempty"`
TotalItems int `json:"totalItems,omitempty"`
}
type ResourceQuota struct {
Namespace string `json:"namespace" description:"namespace"`
Data corev1.ResourceQuotaStatus `json:"data" description:"resource quota status"`
}
type NamespacedResourceQuota struct {
Namespace string `json:"namespace,omitempty"`
Data struct {
corev1.ResourceQuotaStatus
// quota left status, do the math on the side, cause it's
// a lot easier with go-client library
Left corev1.ResourceList `json:"left,omitempty"`
} `json:"data,omitempty"`
}
type Router struct {
RouterType string `json:"type"`
Annotations map[string]string `json:"annotations"`
}
type GitCredential struct {
RemoteUrl string `json:"remoteUrl" description:"git server url"`
SecretRef *corev1.SecretReference `json:"secretRef,omitempty" description:"auth secret reference"`
}
type RegistryCredential struct {
Username string `json:"username" description:"username"`
Password string `json:"password" description:"password"`
ServerHost string `json:"serverhost" description:"registry server host"`
}
type Workloads struct {
Namespace string `json:"namespace" description:"the name of the namespace"`
Count map[string]int `json:"data" description:"the number of unhealthy workloads"`
Items map[string]interface{} `json:"items,omitempty" description:"unhealthy workloads"`
}
type ClientType string
const (
ClientKubernetes ClientType = "Kubernetes"
ClientKubeSphere ClientType = "Kubesphere"
ClientIstio ClientType = "Istio"
ClientS2i ClientType = "S2i"
ClientApplication ClientType = "Application"
StatusOK = "ok"
)
var SupportedGroupVersionResources = map[ClientType][]schema.GroupVersionResource{
// all supported kubernetes api objects
ClientKubernetes: {
{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"},
},
// all supported kubesphere api objects
ClientKubeSphere: {
{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"},
},
// all supported istio api objects
ClientIstio: {},
// all supported s2i api objects
// TODO: move s2i clientset into kubesphere
ClientS2i: {
{Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuildertemplates"},
{Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2iruns"},
{Group: "devops.kubesphere.io", Version: "v1alpha1", Resource: "s2ibuilders"},
},
// kubernetes-sigs application api objects
ClientApplication: {
{Group: "app.k8s.io", Version: "v1beta1", Resource: "applications"},
},
}
// List of all resource kinds supported by the UI.
const (
ResourceKindConfigMap = "configmaps"
ResourceKindDaemonSet = "daemonsets"
ResourceKindDeployment = "deployments"
ResourceKindEvent = "events"
ResourceKindHorizontalPodAutoscaler = "horizontalpodautoscalers"
ResourceKindIngress = "ingresses"
ResourceKindJob = "jobs"
ResourceKindCronJob = "cronjobs"
ResourceKindLimitRange = "limitranges"
ResourceKindNamespace = "namespaces"
ResourceKindNode = "nodes"
ResourceKindPersistentVolumeClaim = "persistentvolumeclaims"
ResourceKindPersistentVolume = "persistentvolumes"
ResourceKindCustomResourceDefinition = "customresourcedefinitions"
ResourceKindPod = "pods"
ResourceKindReplicaSet = "replicasets"
ResourceKindResourceQuota = "resourcequota"
ResourceKindSecret = "secrets"
ResourceKindService = "services"
ResourceKindStatefulSet = "statefulsets"
ResourceKindStorageClass = "storageclasses"
ResourceKindClusterRole = "clusterroles"
ResourceKindClusterRoleBinding = "clusterrolebindings"
ResourceKindRole = "roles"
ResourceKindRoleBinding = "rolebindings"
ResourceKindWorkspace = "workspaces"
ResourceKindS2iBinary = "s2ibinaries"
ResourceKindStrategy = "strategy"
ResourceKindServicePolicy = "servicepolicies"
ResourceKindS2iBuilderTemplate = "s2ibuildertemplates"
ResourceKindeS2iRun = "s2iruns"
ResourceKindS2iBuilder = "s2ibuilders"
ResourceKindApplication = "applications"
)
func HandleInternalError(response *restful.Response, err error) {
statusCode := http.StatusInternalServerError
response.WriteError(statusCode, err)
}
func HandleBadRequest(response *restful.Response, err error) {
}
...@@ -25,7 +25,7 @@ import ( ...@@ -25,7 +25,7 @@ import (
"k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal"
"kubesphere.io/kubesphere/pkg/simple/client/redis" "kubesphere.io/kubesphere/pkg/simple/client/cache"
"log" "log"
"net/http" "net/http"
"strconv" "strconv"
...@@ -44,9 +44,9 @@ type Auth struct { ...@@ -44,9 +44,9 @@ type Auth struct {
type Rule struct { type Rule struct {
Secret []byte Secret []byte
Path string Path string
RedisOptions *redis.RedisOptions RedisOptions *cache.Options
TokenIdleTimeout time.Duration TokenIdleTimeout time.Duration
RedisClient *redis.RedisClient RedisClient cache.Interface
ExclusionRules []internal.ExclusionRule ExclusionRules []internal.ExclusionRule
} }
...@@ -194,15 +194,15 @@ func (h Auth) Validate(uToken string) (*jwt.Token, error) { ...@@ -194,15 +194,15 @@ func (h Auth) Validate(uToken string) (*jwt.Token, error) {
tokenKey := fmt.Sprintf("kubesphere:users:%s:token:%s", username, uToken) tokenKey := fmt.Sprintf("kubesphere:users:%s:token:%s", username, uToken)
exist, err := h.Rule.RedisClient.Redis().Exists(tokenKey).Result() exist, err := h.Rule.RedisClient.Exists(tokenKey)
if err != nil { if err != nil {
klog.Error(err) klog.Error(err)
return nil, err return nil, err
} }
if exist == 1 { if exist {
// reset expiration time if token exist // reset expiration time if token exist
h.Rule.RedisClient.Redis().Expire(tokenKey, h.Rule.TokenIdleTimeout) h.Rule.RedisClient.Expire(tokenKey, h.Rule.TokenIdleTimeout)
return token, nil return token, nil
} else { } else {
return nil, errors.New("illegal token") return nil, errors.New("illegal token")
......
...@@ -20,7 +20,7 @@ package authenticate ...@@ -20,7 +20,7 @@ package authenticate
import ( import (
"fmt" "fmt"
"kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal"
"kubesphere.io/kubesphere/pkg/simple/client/redis" "kubesphere.io/kubesphere/pkg/simple/client/cache"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"time" "time"
...@@ -36,8 +36,10 @@ func Setup(c *caddy.Controller) error { ...@@ -36,8 +36,10 @@ func Setup(c *caddy.Controller) error {
return err return err
} }
stopCh := make(chan struct{})
c.OnStartup(func() error { c.OnStartup(func() error {
rule.RedisClient, err = redis.NewRedisClient(rule.RedisOptions, nil) rule.RedisClient, err = cache.NewRedisClient(rule.RedisOptions, stopCh)
// ensure redis is connected when startup // ensure redis is connected when startup
if err != nil { if err != nil {
return err return err
...@@ -47,7 +49,8 @@ func Setup(c *caddy.Controller) error { ...@@ -47,7 +49,8 @@ func Setup(c *caddy.Controller) error {
}) })
c.OnShutdown(func() error { c.OnShutdown(func() error {
return rule.RedisClient.Redis().Close() close(stopCh)
return nil
}) })
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
...@@ -96,7 +99,7 @@ func parse(c *caddy.Controller) (*Rule, error) { ...@@ -96,7 +99,7 @@ func parse(c *caddy.Controller) (*Rule, error) {
return nil, c.ArgErr() return nil, c.ArgErr()
} }
options := &redis.RedisOptions{RedisURL: c.Val()} options := &cache.Options{RedisURL: c.Val()}
if err := options.Validate(); len(err) > 0 { if err := options.Validate(); len(err) > 0 {
return nil, c.ArgErr() return nil, c.ArgErr()
......
...@@ -23,7 +23,9 @@ import ( ...@@ -23,7 +23,9 @@ import (
"fmt" "fmt"
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/client-go/informers"
"kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/utils/k8sutil" "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"log" "log"
"net/http" "net/http"
...@@ -34,21 +36,22 @@ import ( ...@@ -34,21 +36,22 @@ import (
k8serr "k8s.io/apimachinery/pkg/api/errors" k8serr "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
) )
type Authentication struct { type Authentication struct {
Rule *Rule Rule *Rule
Next httpserver.Handler Next httpserver.Handler
informerFactory informers.SharedInformerFactory
} }
type Rule struct { type Rule struct {
Path string Path string
ExclusionRules []internal.ExclusionRule KubernetesOptions *k8s.KubernetesOptions
ExclusionRules []internal.ExclusionRule
} }
func (c Authentication) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { func (c *Authentication) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
if httpserver.Path(r.URL.Path).Matches(c.Rule.Path) { if httpserver.Path(r.URL.Path).Matches(c.Rule.Path) {
...@@ -65,7 +68,7 @@ func (c Authentication) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, ...@@ -65,7 +68,7 @@ func (c Authentication) ServeHTTP(w http.ResponseWriter, r *http.Request) (int,
return c.Next.ServeHTTP(w, r) return c.Next.ServeHTTP(w, r)
} }
permitted, err := permissionValidate(attrs) permitted, err := c.permissionValidate(attrs)
if err != nil { if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
...@@ -88,13 +91,13 @@ func handleForbidden(w http.ResponseWriter, err error) int { ...@@ -88,13 +91,13 @@ func handleForbidden(w http.ResponseWriter, err error) int {
return http.StatusForbidden return http.StatusForbidden
} }
func permissionValidate(attrs authorizer.Attributes) (bool, error) { func (c *Authentication) permissionValidate(attrs authorizer.Attributes) (bool, error) {
if attrs.GetResource() == "users" && attrs.GetUser().GetName() == attrs.GetName() { if attrs.GetResource() == "users" && attrs.GetUser().GetName() == attrs.GetName() {
return true, nil return true, nil
} }
permitted, err := clusterRoleValidate(attrs) permitted, err := c.clusterRoleValidate(attrs)
if err != nil { if err != nil {
log.Println("lister error", err) log.Println("lister error", err)
...@@ -106,7 +109,7 @@ func permissionValidate(attrs authorizer.Attributes) (bool, error) { ...@@ -106,7 +109,7 @@ func permissionValidate(attrs authorizer.Attributes) (bool, error) {
} }
if attrs.GetNamespace() != "" { if attrs.GetNamespace() != "" {
permitted, err = roleValidate(attrs) permitted, err = c.roleValidate(attrs)
if err != nil { if err != nil {
log.Println("lister error", err) log.Println("lister error", err)
...@@ -121,9 +124,9 @@ func permissionValidate(attrs authorizer.Attributes) (bool, error) { ...@@ -121,9 +124,9 @@ func permissionValidate(attrs authorizer.Attributes) (bool, error) {
return false, nil return false, nil
} }
func roleValidate(attrs authorizer.Attributes) (bool, error) { func (c *Authentication) roleValidate(attrs authorizer.Attributes) (bool, error) {
roleBindingLister := informers.SharedInformerFactory().Rbac().V1().RoleBindings().Lister() roleBindingLister := c.informerFactory.Rbac().V1().RoleBindings().Lister()
roleLister := informers.SharedInformerFactory().Rbac().V1().Roles().Lister() roleLister := c.informerFactory.Rbac().V1().Roles().Lister()
roleBindings, err := roleBindingLister.RoleBindings(attrs.GetNamespace()).List(labels.Everything()) roleBindings, err := roleBindingLister.RoleBindings(attrs.GetNamespace()).List(labels.Everything())
if err != nil { if err != nil {
...@@ -158,10 +161,10 @@ func roleValidate(attrs authorizer.Attributes) (bool, error) { ...@@ -158,10 +161,10 @@ func roleValidate(attrs authorizer.Attributes) (bool, error) {
return false, nil return false, nil
} }
func clusterRoleValidate(attrs authorizer.Attributes) (bool, error) { func (c *Authentication) clusterRoleValidate(attrs authorizer.Attributes) (bool, error) {
clusterRoleBindingLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister() clusterRoleBindingLister := c.informerFactory.Rbac().V1().ClusterRoleBindings().Lister()
clusterRoleBindings, err := clusterRoleBindingLister.List(labels.Everything()) clusterRoleBindings, err := clusterRoleBindingLister.List(labels.Everything())
clusterRoleLister := informers.SharedInformerFactory().Rbac().V1().ClusterRoles().Lister() clusterRoleLister := c.informerFactory.Rbac().V1().ClusterRoles().Lister()
if err != nil { if err != nil {
return false, err return false, err
} }
......
...@@ -21,7 +21,9 @@ import ( ...@@ -21,7 +21,9 @@ import (
"fmt" "fmt"
"github.com/mholt/caddy" "github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver" "github.com/mholt/caddy/caddyhttp/httpserver"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
...@@ -31,19 +33,28 @@ import ( ...@@ -31,19 +33,28 @@ import (
func Setup(c *caddy.Controller) error { func Setup(c *caddy.Controller) error {
rule, err := parse(c) rule, err := parse(c)
if err != nil {
return err
}
if rule.KubernetesOptions == nil && rule.KubernetesOptions.KubeConfig == "" {
klog.Warning("no kubeconfig provided, will use in cluster config, this may not work")
}
kubeClient, err := k8s.NewKubernetesClient(rule.KubernetesOptions)
if err != nil { if err != nil {
return err return err
} }
informerFactory := informers.NewInformerFactories(kubeClient.Kubernetes(), nil, nil, nil)
stopChan := make(chan struct{}, 0) stopChan := make(chan struct{}, 0)
c.OnStartup(func() error { c.OnStartup(func() error {
informerFactory := informers.SharedInformerFactory() informerFactory.KubernetesSharedInformerFactory().Rbac().V1().Roles().Lister()
informerFactory.Rbac().V1().Roles().Lister() informerFactory.KubernetesSharedInformerFactory().Rbac().V1().RoleBindings().Lister()
informerFactory.Rbac().V1().RoleBindings().Lister() informerFactory.KubernetesSharedInformerFactory().Rbac().V1().ClusterRoles().Lister()
informerFactory.Rbac().V1().ClusterRoles().Lister() informerFactory.KubernetesSharedInformerFactory().Rbac().V1().ClusterRoleBindings().Lister()
informerFactory.Rbac().V1().ClusterRoleBindings().Lister() informerFactory.KubernetesSharedInformerFactory().Start(stopChan)
informerFactory.Start(stopChan) informerFactory.KubernetesSharedInformerFactory().WaitForCacheSync(stopChan)
informerFactory.WaitForCacheSync(stopChan)
fmt.Println("Authentication middleware is initiated") fmt.Println("Authentication middleware is initiated")
return nil return nil
}) })
...@@ -54,7 +65,7 @@ func Setup(c *caddy.Controller) error { ...@@ -54,7 +65,7 @@ func Setup(c *caddy.Controller) error {
}) })
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
return &Authentication{Next: next, Rule: rule} return &Authentication{Next: next, Rule: rule, informerFactory: informerFactory.KubernetesSharedInformerFactory()}
}) })
return nil return nil
} }
......
package apis
import "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
func init() {
// Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
AddToSchemes = append(AddToSchemes, v1alpha2.SchemeBuilder.AddToScheme)
}
...@@ -56,7 +56,7 @@ func (in *S2iBinary) DeepCopyObject() runtime.Object { ...@@ -56,7 +56,7 @@ func (in *S2iBinary) DeepCopyObject() runtime.Object {
func (in *S2iBinaryList) DeepCopyInto(out *S2iBinaryList) { func (in *S2iBinaryList) DeepCopyInto(out *S2iBinaryList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]S2iBinary, len(*in)) *out = make([]S2iBinary, len(*in))
......
/*
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 v1alpha2 contains API Schema definitions for the servicemesh v1alpha2 API group
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=kubesphere.io/kubesphere/pkg/apis/logging
// +k8s:defaulter-gen=TypeMeta
// +groupName=logging.kubesphere.io
package v1alpha2
package v1alpha2
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type FluentBit struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec FluentBitSpec `json:"spec"`
Status FluentBitStatus `json:"status,omitempty"`
}
// FluentBitSpec holds the spec for the operator
type FluentBitSpec struct {
Service []Plugin `json:"service"`
Input []Plugin `json:"input"`
Filter []Plugin `json:"filter"`
Output []Plugin `json:"output"`
Settings []Plugin `json:"settings"`
}
// FluentBitStatus holds the status info for the operator
type FluentBitStatus struct {
// Fill me
}
// Plugin struct for fluent-bit plugins
type Plugin struct {
Type string `json:"type" description:"output plugin type, eg. fluentbit-output-es"`
Name string `json:"name" description:"output plugin name, eg. fluentbit-output-es"`
Parameters []Parameter `json:"parameters" description:"output plugin configuration parameters"`
}
// Fluent-bit output plugins
type OutputPlugin struct {
Plugin
Id string `json:"id,omitempty" description:"output uuid"`
Enable bool `json:"enable" description:"active status, one of true, false"`
Updatetime *metav1.Time `json:"updatetime,omitempty" description:"last updatetime"`
}
// Parameter generic parameter type to handle values from different sources
type Parameter struct {
Name string `json:"name" description:"configuration parameter key, eg. Name. refer to Fluent bit's Output Plugins Section for more configuration parameters."`
ValueFrom *ValueFrom `json:"valueFrom,omitempty"`
Value string `json:"value" description:"configuration parameter value, eg. es. refer to Fluent bit's Output Plugins Section for more configuration parameters."`
}
// ValueFrom generic type to determine value origin
type ValueFrom struct {
SecretKeyRef KubernetesSecret `json:"secretKeyRef"`
}
// KubernetesSecret is a ValueFrom type
type KubernetesSecret struct {
Name string `json:"name"`
Key string `json:"key"`
Namespace string `json:"namespace"`
}
// FluentBitList auto generated by the sdk
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type FluentBitList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []FluentBit `json:"items"`
}
/*
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 v1alpha1 contains API Schema definitions for the tenant v1alpha1 API group
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=kubesphere.io/kubesphere/pkg/apis/logging
// +k8s:defaulter-gen=TypeMeta
// +groupName=logging.kubesphere.io
package v1alpha2
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
)
var (
// SchemeGroupVersion is group version used to register these objects
SchemeGroupVersion = schema.GroupVersion{Group: "logging.kubesphere.io", Version: "v1alpha2"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
// AddToScheme is required by pkg/client/...
AddToScheme = SchemeBuilder.AddToScheme
)
// Resource is required by pkg/client/listers/...
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
// +build !ignore_autogenerated
/* /*
Copyright 2018 The KubeSphere Authors. Copyright 2019 The KubeSphere authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package fluentbitclient
import ( // Code generated by deepcopy-gen. DO NOT EDIT.
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
"time"
)
const ( package v1alpha2
CRDPlural string = "fluentbits"
CRDGroup string = "logging.kubesphere.io"
CRDVersion string = "v1alpha1"
FullCRDName string = CRDPlural + "." + CRDGroup
)
// FluentBitList auto generated by the sdk
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type FluentBitList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []FluentBit `json:"items"`
}
// FluentBit auto generated by the sdk
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type FluentBit struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec FluentBitSpec `json:"spec"`
Status FluentBitStatus `json:"status,omitempty"`
}
// FluentBitSpec holds the spec for the operator
type FluentBitSpec struct {
Service []Plugin `json:"service"`
Input []Plugin `json:"input"`
Filter []Plugin `json:"filter"`
Output []Plugin `json:"output"`
Settings []Plugin `json:"settings"`
}
// FluentBitStatus holds the status info for the operator import (
type FluentBitStatus struct { runtime "k8s.io/apimachinery/pkg/runtime"
// Fill me )
}
// Plugin struct for fluent-bit plugins
type Plugin struct {
Type string `json:"type" description:"output plugin type, eg. fluentbit-output-es"`
Name string `json:"name" description:"output plugin name, eg. fluentbit-output-es"`
Parameters []Parameter `json:"parameters" description:"output plugin configuration parameters"`
}
// Fluent-bit output plugins
type OutputPlugin struct {
Plugin
Id string `json:"id,omitempty" description:"output uuid"`
Enable bool `json:"enable" description:"active status, one of true, false"`
Updatetime time.Time `json:"updatetime,omitempty" description:"last updatetime"`
}
// Parameter generic parameter type to handle values from different sources
type Parameter struct {
Name string `json:"name" description:"configuration parameter key, eg. Name. refer to Fluent bit's Output Plugins Section for more configuration parameters."`
ValueFrom *ValueFrom `json:"valueFrom,omitempty"`
Value string `json:"value" description:"configuration parameter value, eg. es. refer to Fluent bit's Output Plugins Section for more configuration parameters."`
}
// ValueFrom generic type to determine value origin
type ValueFrom struct {
SecretKeyRef KubernetesSecret `json:"secretKeyRef"`
}
// KubernetesSecret is a ValueFrom type
type KubernetesSecret struct {
Name string `json:"name"`
Key string `json:"key"`
Namespace string `json:"namespace"`
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FluentBit) DeepCopyInto(out *FluentBit) { func (in *FluentBit) DeepCopyInto(out *FluentBit) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status out.Status = in.Status
return return
} }
...@@ -128,7 +56,7 @@ func (in *FluentBit) DeepCopyObject() runtime.Object { ...@@ -128,7 +56,7 @@ func (in *FluentBit) DeepCopyObject() runtime.Object {
func (in *FluentBitList) DeepCopyInto(out *FluentBitList) { func (in *FluentBitList) DeepCopyInto(out *FluentBitList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]FluentBit, len(*in)) *out = make([]FluentBit, len(*in))
...@@ -160,6 +88,41 @@ func (in *FluentBitList) DeepCopyObject() runtime.Object { ...@@ -160,6 +88,41 @@ func (in *FluentBitList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FluentBitSpec) DeepCopyInto(out *FluentBitSpec) { func (in *FluentBitSpec) DeepCopyInto(out *FluentBitSpec) {
*out = *in *out = *in
if in.Service != nil {
in, out := &in.Service, &out.Service
*out = make([]Plugin, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Input != nil {
in, out := &in.Input, &out.Input
*out = make([]Plugin, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Filter != nil {
in, out := &in.Filter, &out.Filter
*out = make([]Plugin, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Output != nil {
in, out := &in.Output, &out.Output
*out = make([]Plugin, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Settings != nil {
in, out := &in.Settings, &out.Settings
*out = make([]Plugin, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return return
} }
...@@ -189,100 +152,100 @@ func (in *FluentBitStatus) DeepCopy() *FluentBitStatus { ...@@ -189,100 +152,100 @@ func (in *FluentBitStatus) DeepCopy() *FluentBitStatus {
return out return out
} }
// Create a Rest client with the new CRD Schema // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
var SchemeGroupVersion = schema.GroupVersion{Group: CRDGroup, Version: CRDVersion} func (in *KubernetesSecret) DeepCopyInto(out *KubernetesSecret) {
*out = *in
func addKnownTypes(scheme *runtime.Scheme) error { return
scheme.AddKnownTypes(SchemeGroupVersion,
&FluentBit{},
&FluentBitList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
} }
func NewFluentbitCRDClient(cfg *rest.Config) (*rest.RESTClient, *runtime.Scheme, error) { // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesSecret.
scheme := runtime.NewScheme() func (in *KubernetesSecret) DeepCopy() *KubernetesSecret {
SchemeBuilder := runtime.NewSchemeBuilder(addKnownTypes) if in == nil {
if err := SchemeBuilder.AddToScheme(scheme); err != nil { return nil
return nil, nil, err
}
config := *cfg
config.GroupVersion = &SchemeGroupVersion
config.APIPath = "/apis"
config.ContentType = runtime.ContentTypeJSON
config.NegotiatedSerializer = serializer.NewCodecFactory(runtime.NewScheme()).WithoutConversion()
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, nil, err
} }
return client, scheme, nil out := new(KubernetesSecret)
} in.DeepCopyInto(out)
return out
// This file implement all the (CRUD) client methods we need to access our CRD object
func CrdClient(cl *rest.RESTClient, scheme *runtime.Scheme, namespace string) *crdclient {
return &crdclient{cl: cl, ns: namespace, plural: CRDPlural,
codec: runtime.NewParameterCodec(scheme)}
} }
type crdclient struct { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
cl *rest.RESTClient func (in *OutputPlugin) DeepCopyInto(out *OutputPlugin) {
ns string *out = *in
plural string in.Plugin.DeepCopyInto(&out.Plugin)
codec runtime.ParameterCodec if in.Updatetime != nil {
in, out := &in.Updatetime, &out.Updatetime
*out = (*in).DeepCopy()
}
return
} }
func (f *crdclient) Create(obj *FluentBit) (*FluentBit, error) { // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutputPlugin.
var result FluentBit func (in *OutputPlugin) DeepCopy() *OutputPlugin {
err := f.cl.Post(). if in == nil {
Namespace(f.ns).Resource(f.plural). return nil
Body(obj).Do().Into(&result) }
return &result, err out := new(OutputPlugin)
in.DeepCopyInto(out)
return out
} }
func (f *crdclient) Update(name string, obj *FluentBit) (*FluentBit, error) { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
var result FluentBit func (in *Parameter) DeepCopyInto(out *Parameter) {
err := f.cl.Put(). *out = *in
Namespace(f.ns).Resource(f.plural). if in.ValueFrom != nil {
Name(name).Body(obj).Do().Into(&result) in, out := &in.ValueFrom, &out.ValueFrom
return &result, err *out = new(ValueFrom)
**out = **in
}
return
} }
func (f *crdclient) Delete(name string, options *metav1.DeleteOptions) error { // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Parameter.
return f.cl.Delete(). func (in *Parameter) DeepCopy() *Parameter {
Namespace(f.ns).Resource(f.plural). if in == nil {
Name(name).Body(options).Do(). return nil
Error() }
out := new(Parameter)
in.DeepCopyInto(out)
return out
} }
func (f *crdclient) Get(name string) (*FluentBit, error) { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
var result FluentBit func (in *Plugin) DeepCopyInto(out *Plugin) {
err := f.cl.Get(). *out = *in
Namespace(f.ns).Resource(f.plural). if in.Parameters != nil {
Name(name).Do().Into(&result) in, out := &in.Parameters, &out.Parameters
return &result, err *out = make([]Parameter, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
} }
func (f *crdclient) List(opts metav1.ListOptions) (*FluentBitList, error) { // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin.
var result FluentBitList func (in *Plugin) DeepCopy() *Plugin {
err := f.cl.Get(). if in == nil {
Namespace(f.ns).Resource(f.plural). return nil
VersionedParams(&opts, f.codec). }
Do().Into(&result) out := new(Plugin)
return &result, err in.DeepCopyInto(out)
return out
} }
// Create a new List watch for our TPR // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (f *crdclient) NewListWatch() *cache.ListWatch { func (in *ValueFrom) DeepCopyInto(out *ValueFrom) {
return cache.NewListWatchFromClient(f.cl, f.plural, f.ns, fields.Everything()) *out = *in
out.SecretKeyRef = in.SecretKeyRef
return
} }
// return rest config, if path not specified assume in cluster config // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValueFrom.
func GetClientConfig(kubeconfig string) (*rest.Config, error) { func (in *ValueFrom) DeepCopy() *ValueFrom {
if kubeconfig != "" { if in == nil {
return clientcmd.BuildConfigFromFlags("", kubeconfig) return nil
} }
return rest.InClusterConfig() out := new(ValueFrom)
in.DeepCopyInto(out)
return out
} }
...@@ -168,7 +168,7 @@ func (in *NamespaceNetworkPolicy) DeepCopyObject() runtime.Object { ...@@ -168,7 +168,7 @@ func (in *NamespaceNetworkPolicy) DeepCopyObject() runtime.Object {
func (in *NamespaceNetworkPolicyList) DeepCopyInto(out *NamespaceNetworkPolicyList) { func (in *NamespaceNetworkPolicyList) DeepCopyInto(out *NamespaceNetworkPolicyList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]NamespaceNetworkPolicy, len(*in)) *out = make([]NamespaceNetworkPolicy, len(*in))
...@@ -398,7 +398,7 @@ func (in *WorkspaceNetworkPolicyIngressRule) DeepCopy() *WorkspaceNetworkPolicyI ...@@ -398,7 +398,7 @@ func (in *WorkspaceNetworkPolicyIngressRule) DeepCopy() *WorkspaceNetworkPolicyI
func (in *WorkspaceNetworkPolicyList) DeepCopyInto(out *WorkspaceNetworkPolicyList) { func (in *WorkspaceNetworkPolicyList) DeepCopyInto(out *WorkspaceNetworkPolicyList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]WorkspaceNetworkPolicy, len(*in)) *out = make([]WorkspaceNetworkPolicy, len(*in))
......
...@@ -93,7 +93,7 @@ func (in *ServicePolicyCondition) DeepCopy() *ServicePolicyCondition { ...@@ -93,7 +93,7 @@ func (in *ServicePolicyCondition) DeepCopy() *ServicePolicyCondition {
func (in *ServicePolicyList) DeepCopyInto(out *ServicePolicyList) { func (in *ServicePolicyList) DeepCopyInto(out *ServicePolicyList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]ServicePolicy, len(*in)) *out = make([]ServicePolicy, len(*in))
...@@ -225,7 +225,7 @@ func (in *StrategyCondition) DeepCopy() *StrategyCondition { ...@@ -225,7 +225,7 @@ func (in *StrategyCondition) DeepCopy() *StrategyCondition {
func (in *StrategyList) DeepCopyInto(out *StrategyList) { func (in *StrategyList) DeepCopyInto(out *StrategyList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]Strategy, len(*in)) *out = make([]Strategy, len(*in))
......
...@@ -56,7 +56,7 @@ func (in *Workspace) DeepCopyObject() runtime.Object { ...@@ -56,7 +56,7 @@ func (in *Workspace) DeepCopyObject() runtime.Object {
func (in *WorkspaceList) DeepCopyInto(out *WorkspaceList) { func (in *WorkspaceList) DeepCopyInto(out *WorkspaceList) {
*out = *in *out = *in
out.TypeMeta = in.TypeMeta out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil { if in.Items != nil {
in, out := &in.Items, &out.Items in, out := &in.Items, &out.Items
*out = make([]Workspace, len(*in)) *out = make([]Workspace, len(*in))
......
package apiserver
import (
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/informers"
resourcev1alpha3 "kubesphere.io/kubesphere/pkg/kapis/resources/v1alpha3"
"kubesphere.io/kubesphere/pkg/server/options"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
"kubesphere.io/kubesphere/pkg/simple/client/db"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/logging"
"kubesphere.io/kubesphere/pkg/simple/client/monitoring"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
)
const (
// ApiRootPath defines the root path of all KubeSphere apis.
ApiRootPath = "/kapis"
// MimeMergePatchJson is the mime header used in merge request
MimeMergePatchJson = "application/merge-patch+json"
//
MimeJsonPatchJson = "application/json-patch+json"
)
// Dependencies is objects constructed at runtime that are necessary for running apiserver.
type Dependencies struct {
// Injected Dependencies
KubeClient k8s.Client
S3 s3.Interface
OpenPitrix openpitrix.Interface
Monitoring monitoring.Interface
Logging logging.Interface
Devops devops.Interface
DB db.Interface
}
type APIServer struct {
// number of kubesphere apiserver
apiserverCount int
//
genericServerOptions *options.ServerRunOptions
// webservice container, where all webservice defines
container *restful.Container
// kubeClient is a collection of all kubernetes(include CRDs) objects clientset
kubeClient k8s.Client
// informerFactory is a collection of all kubernetes(include CRDs) objects informers,
// mainly for fast query
informerFactory informers.InformerFactory
// cache is used for short lived objects, like session
cache cache.Interface
//
}
func New(deps *Dependencies) *APIServer {
server := &APIServer{}
return server
}
func (s *APIServer) InstallKubeSphereAPIs() {
resourcev1alpha3.AddWebService(s.container, s.kubeClient)
}
func (s *APIServer) Serve() error {
panic("implement me")
}
/*
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 components
import (
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/models/components"
"kubesphere.io/kubesphere/pkg/server/errors"
"net/http"
)
func GetSystemHealthStatus(request *restful.Request, response *restful.Response) {
result, err := components.GetSystemHealthStatus()
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(result)
}
// get a specific component status
func GetComponentStatus(request *restful.Request, response *restful.Response) {
component := request.PathParameter("component")
result, err := components.GetComponentStatus(component)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(result)
}
// get all componentsHandler
func GetComponents(request *restful.Request, response *restful.Response) {
result, err := components.GetAllComponentsStatus()
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(result)
}
package git
import (
"net/http"
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/models/git"
"kubesphere.io/kubesphere/pkg/server/errors"
)
func GitReadVerify(request *restful.Request, response *restful.Response) {
authInfo := git.AuthInfo{}
err := request.ReadEntity(&authInfo)
ns := request.PathParameter("namespace")
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
err = git.GitReadVerify(ns, authInfo)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(errors.None)
}
...@@ -28,7 +28,6 @@ import ( ...@@ -28,7 +28,6 @@ import (
"kubesphere.io/kubesphere/pkg/models/log" "kubesphere.io/kubesphere/pkg/models/log"
"kubesphere.io/kubesphere/pkg/server/errors" "kubesphere.io/kubesphere/pkg/server/errors"
cs "kubesphere.io/kubesphere/pkg/simple/client" cs "kubesphere.io/kubesphere/pkg/simple/client"
fb "kubesphere.io/kubesphere/pkg/simple/client/fluentbit"
"kubesphere.io/kubesphere/pkg/utils/stringutils" "kubesphere.io/kubesphere/pkg/utils/stringutils"
"net/http" "net/http"
"strconv" "strconv"
......
...@@ -28,7 +28,7 @@ import ( ...@@ -28,7 +28,7 @@ import (
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/openpitrix" "kubesphere.io/kubesphere/pkg/models/openpitrix"
"kubesphere.io/kubesphere/pkg/models/resources" "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/server/errors" "kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/server/params" "kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/simple/client" "kubesphere.io/kubesphere/pkg/simple/client"
...@@ -53,7 +53,7 @@ func ListApplications(req *restful.Request, resp *restful.Response) { ...@@ -53,7 +53,7 @@ func ListApplications(req *restful.Request, resp *restful.Response) {
} }
if namespaceName != "" { if namespaceName != "" {
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName) namespace, err := v1alpha2.GetResource("", v1alpha2.Namespaces, namespaceName)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
...@@ -109,7 +109,7 @@ func DescribeApplication(req *restful.Request, resp *restful.Response) { ...@@ -109,7 +109,7 @@ func DescribeApplication(req *restful.Request, resp *restful.Response) {
return return
} }
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName) namespace, err := resources.GetResource("", v1alpha2.Namespaces, namespaceName)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
...@@ -186,7 +186,7 @@ func ModifyApplication(req *restful.Request, resp *restful.Response) { ...@@ -186,7 +186,7 @@ func ModifyApplication(req *restful.Request, resp *restful.Response) {
return return
} }
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName) namespace, err := resources.GetResource("", v1alpha2.Namespaces, namespaceName)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
...@@ -243,7 +243,7 @@ func DeleteApplication(req *restful.Request, resp *restful.Response) { ...@@ -243,7 +243,7 @@ func DeleteApplication(req *restful.Request, resp *restful.Response) {
return return
} }
namespace, err := resources.GetResource("", resources.Namespaces, namespaceName) namespace, err := resources.GetResource("", v1alpha2.Namespaces, namespaceName)
if err != nil { if err != nil {
klog.Errorln(err) klog.Errorln(err)
......
/*
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 operations
import (
k8serr "k8s.io/apimachinery/pkg/api/errors"
"kubesphere.io/kubesphere/pkg/models/workloads"
"kubesphere.io/kubesphere/pkg/server/errors"
"net/http"
"github.com/emicklei/go-restful"
"fmt"
)
func RerunJob(req *restful.Request, resp *restful.Response) {
var err error
job := req.PathParameter("job")
namespace := req.PathParameter("namespace")
action := req.QueryParameter("action")
resourceVersion := req.QueryParameter("resourceVersion")
switch action {
case "rerun":
err = workloads.JobReRun(namespace, job, resourceVersion)
default:
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("invalid operation %s", action)))
return
}
if err != nil {
if k8serr.IsConflict(err) {
resp.WriteHeaderAndEntity(http.StatusConflict, errors.Wrap(err))
return
}
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(errors.None)
}
/*
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 operations
import (
"github.com/emicklei/go-restful"
"net/http"
"kubesphere.io/kubesphere/pkg/models/nodes"
"kubesphere.io/kubesphere/pkg/server/errors"
)
func DrainNode(request *restful.Request, response *restful.Response) {
nodeName := request.PathParameter("node")
err := nodes.DrainNode(nodeName)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(errors.None)
}
package query
type Field string
const (
FieldName = "name"
FieldCreationTimeStamp = "creationTimestamp"
FieldLastUpdateTimestamp = "lastUpdateTimestamp"
FieldNamespace = "namespace"
FieldStatus = "status"
FieldApplication = "application"
FieldOwner = "owner"
FieldOwnerKind = "ownerKind"
)
var SortableFields = []Field{
FieldCreationTimeStamp,
FieldLastUpdateTimestamp,
FieldName,
}
// Field contains all the query field that can be compared
var ComparableFields = []Field{
FieldName,
FieldNamespace,
FieldStatus,
FieldApplication,
FieldOwner,
FieldOwnerKind,
}
package query
import (
"github.com/emicklei/go-restful"
"strconv"
"strings"
)
const (
ParameterName = "name"
ParameterLabelSelector = "labelSelector"
ParameterFieldSelector = "fieldSelector"
ParameterPage = "page"
ParameterLimit = "limit"
ParameterOrderBy = "sortBy"
ParameterAscending = "ascending"
)
type Comparable interface {
Compare(Comparable) int
Contains(Comparable) bool
}
type ComparableString string
func (c ComparableString) Compare(comparable Comparable) int {
other := comparable.(ComparableString)
return strings.Compare(string(c), string(other))
}
func (c ComparableString) Contains(comparable Comparable) bool {
other := comparable.(ComparableString)
return strings.Contains(string(c), string(other))
}
// Query represents api search terms
type Query struct {
Pagination *Pagination
// sort result in which field, default to FieldCreationTimeStamp
SortBy Field
// sort result in ascending or descending order, default to descending
Ascending bool
//
Filters []Filter
}
type Pagination struct {
// items per page
Limit int
// page number
Page int
}
var NoPagination = newPagination(-1, -1)
func newPagination(limit int, page int) *Pagination {
return &Pagination{
Limit: limit,
Page: page,
}
}
func (p *Pagination) IsValidPagintaion() bool {
return p.Limit >= 0 && p.Page >= 0
}
func (p *Pagination) IsPageAvailable(total, startIndex int) bool {
return total > startIndex && p.Limit > 0
}
func (p *Pagination) GetPaginationSettings(total int) (startIndex, endIndex int) {
startIndex = p.Limit * p.Page
endIndex = startIndex + p.Limit
if endIndex > total {
endIndex = total
}
return startIndex, endIndex
}
func New() *Query {
return &Query{
Pagination: &Pagination{
Limit: -1,
Page: -1,
},
SortBy: "",
Ascending: false,
Filters: []Filter{},
}
}
type Filter struct {
Field Field
Value Comparable
}
func ParseQueryParameter(request *restful.Request) *Query {
query := New()
limit, err := strconv.ParseInt(request.QueryParameter("limit"), 10, 0)
if err != nil {
query.Pagination = NoPagination
}
page, err := strconv.ParseInt(request.QueryParameter("page"), 10, 0)
if err == nil {
query.Pagination = newPagination(int(limit), int(page-1))
}
query.SortBy = Field(defaultString(request.QueryParameter("sortBy"), FieldCreationTimeStamp))
ascending, err := strconv.ParseBool(defaultString(request.QueryParameter("ascending"), "false"))
if err != nil {
query.Ascending = false
} else {
query.Ascending = ascending
}
for _, field := range ComparableFields {
f := request.QueryParameter(string(field))
if len(f) != 0 {
query.Filters = append(query.Filters, Filter{
Field: field,
Value: ComparableString(f),
})
}
}
return query
}
func defaultString(value, defaultValue string) string {
if len(value) == 0 {
return defaultValue
}
return value
}
package query
import (
"fmt"
"github.com/emicklei/go-restful"
"github.com/google/go-cmp/cmp"
"net/http"
"testing"
)
func TestParseQueryParameter(t *testing.T) {
tests := []struct {
description string
queryString string
expected *Query
}{
{
"test normal case",
"name=foo&status=Running&application=book&page=1&limit=10&ascending=true",
&Query{
Pagination: newPagination(10, 0),
SortBy: FieldCreationTimeStamp,
Ascending: true,
Filters: []Filter{
{
FieldName,
ComparableString("foo"),
},
{
FieldStatus,
ComparableString("Running"),
},
{
FieldApplication,
ComparableString("book"),
},
},
},
},
{
"test bad case",
"xxxx=xxxx&dsfsw=xxxx&page=abc&limit=add&ascending=ssss",
&Query{
Pagination: &Pagination{
Limit: -1,
Page: -1,
},
SortBy: FieldCreationTimeStamp,
Ascending: false,
Filters: []Filter{},
},
},
}
for _, test := range tests {
req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost?%s", test.queryString), nil)
if err != nil {
t.Fatal(err)
}
request := restful.NewRequest(req)
t.Run(test.description, func(t *testing.T) {
got := ParseQueryParameter(request)
if diff := cmp.Diff(got, test.expected); diff != "" {
t.Errorf("%T differ (-got, +want): %s", test.expected, diff)
return
}
})
}
}
/*
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 quotas
import (
"github.com/emicklei/go-restful"
"net/http"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/models/quotas"
)
func GetNamespaceQuotas(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
quota, err := quotas.GetNamespaceQuotas(namespace)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(quota)
}
func GetClusterQuotas(req *restful.Request, resp *restful.Response) {
quota, err := quotas.GetClusterQuotas()
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(quota)
}
/*
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 registries
import (
"github.com/emicklei/go-restful"
"net/http"
"kubesphere.io/kubesphere/pkg/models/registries"
"kubesphere.io/kubesphere/pkg/server/errors"
k8serror "k8s.io/apimachinery/pkg/api/errors"
log "k8s.io/klog"
)
func RegistryVerify(request *restful.Request, response *restful.Response) {
authInfo := registries.AuthInfo{}
err := request.ReadEntity(&authInfo)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
err = registries.RegistryVerify(authInfo)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(errors.None)
}
func RegistryImageBlob(request *restful.Request, response *restful.Response) {
imageName := request.QueryParameter("image")
namespace := request.QueryParameter("namespace")
secretName := request.QueryParameter("secret")
// get entry
entry, err := registries.GetEntryBySecret(namespace, secretName)
if err != nil {
log.Errorf("%+v", err)
if k8serror.IsNotFound(err) {
log.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), response)
return
}
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
return
}
// parse image
image, err := registries.ParseImage(imageName)
if err != nil {
log.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), response)
return
}
// Create the registry client.
r, err := registries.CreateRegistryClient(entry.Username, entry.Password, image.Domain)
if err != nil {
log.Errorf("%+v", err)
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
return
}
digestUrl := r.GetDigestUrl(image)
// Get token.
token, err := r.Token(digestUrl)
if err != nil {
log.Errorf("%+v", err)
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
return
}
// Get digest.
imageManifest, err := r.ImageManifest(image, token)
if err != nil {
if serviceError, ok := err.(restful.ServiceError); ok {
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: serviceError.Message})
return
}
log.Errorf("%+v", err)
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
return
}
image.Digest = imageManifest.ManifestConfig.Digest
// Get blob.
imageBlob, err := r.ImageBlob(image, token)
if err != nil {
log.Errorf("%+v", err)
response.WriteAsJson(&registries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
return
}
imageDetails := &registries.ImageDetails{
Status: registries.StatusSuccess,
ImageManifest: imageManifest,
ImageBlob: imageBlob,
ImageTag: image.Tag,
Registry: image.Domain,
}
response.WriteAsJson(imageDetails)
}
/*
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 resources
import (
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/models/resources"
"net/http"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/server/params"
)
func ListNamespacedResources(req *restful.Request, resp *restful.Response) {
ListResources(req, resp)
}
func ListResources(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
resourceName := req.PathParameter("resources")
conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
orderBy := params.GetStringValueWithDefault(req, params.OrderByParam, resources.CreateTime)
limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(req)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := resources.ListResources(namespace, resourceName, conditions, orderBy, reverse, limit, offset)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
/*
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 resources
import (
"github.com/emicklei/go-restful"
"k8s.io/api/core/v1"
"net/http"
"kubesphere.io/kubesphere/pkg/models/storage"
"kubesphere.io/kubesphere/pkg/server/errors"
)
type pvcList struct {
Name string `json:"name"`
Items []*v1.PersistentVolumeClaim `json:"items"`
}
type podListByPvc struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Pods []*v1.Pod `json:"pods"`
}
// List all pods of a specific PVC
// Extended API URL: "GET /api/v1alpha2/namespaces/{namespace}/persistentvolumeclaims/{name}/pods"
func GetPodListByPvc(request *restful.Request, response *restful.Response) {
pvcName := request.PathParameter("pvc")
nsName := request.PathParameter("namespace")
pods, err := storage.GetPodListByPvc(pvcName, nsName)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
result := podListByPvc{Name: pvcName, Namespace: nsName, Pods: pods}
response.WriteAsJson(result)
}
// List all PersistentVolumeClaims of a specific StorageClass
// Extended API URL: "GET /api/v1alpha2/storageclasses/{storageclass}/persistentvolumeclaims"
func GetPvcListBySc(request *restful.Request, response *restful.Response) {
scName := request.PathParameter("storageclass")
claims, err := storage.GetPvcListBySc(scName)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
result := pvcList{
Name: scName, Items: claims,
}
response.WriteAsJson(result)
}
/*
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 revisions
import (
"net/http"
"strconv"
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/models/revisions"
"kubesphere.io/kubesphere/pkg/server/errors"
)
func GetDaemonSetRevision(req *restful.Request, resp *restful.Response) {
daemonset := req.PathParameter("daemonset")
namespace := req.PathParameter("namespace")
revision, err := strconv.Atoi(req.PathParameter("revision"))
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := revisions.GetDaemonSetRevision(namespace, daemonset, revision)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
func GetDeployRevision(req *restful.Request, resp *restful.Response) {
deploy := req.PathParameter("deployment")
namespace := req.PathParameter("namespace")
revision := req.PathParameter("revision")
result, err := revisions.GetDeployRevision(namespace, deploy, revision)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
func GetStatefulSetRevision(req *restful.Request, resp *restful.Response) {
statefulset := req.PathParameter("statefulset")
namespace := req.PathParameter("namespace")
revision, err := strconv.Atoi(req.PathParameter("revision"))
if err != nil {
resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := revisions.GetStatefulSetRevision(namespace, statefulset, revision)
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(result)
}
/*
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 routers
import (
"fmt"
"github.com/emicklei/go-restful"
k8serr "k8s.io/apimachinery/pkg/api/errors"
"net/http"
"kubesphere.io/kubesphere/pkg/server/errors"
"strings"
"k8s.io/api/core/v1"
"kubesphere.io/kubesphere/pkg/models/routers"
)
type Router struct {
RouterType string `json:"type"`
Annotations map[string]string `json:"annotations"`
}
// Get all namespace ingress controller services
func GetAllRouters(request *restful.Request, response *restful.Response) {
routers, err := routers.GetAllRouters()
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(routers)
}
// Get ingress controller service for specified namespace
func GetRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
router, err := routers.GetRouter(namespace)
if err != nil {
if k8serr.IsNotFound(err) {
response.WriteHeaderAndEntity(http.StatusNotFound, errors.Wrap(err))
} else {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
}
return
}
response.WriteAsJson(router)
}
// Create ingress controller and related services
func CreateRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
newRouter := Router{}
err := request.ReadEntity(&newRouter)
if err != nil {
response.WriteAsJson(err)
return
}
var router *v1.Service
serviceType, annotationMap, err := parseParameter(newRouter)
if err != nil {
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("wrong annotations, missing key or value")))
return
}
router, err = routers.CreateRouter(namespace, serviceType, annotationMap)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(router)
}
// Delete ingress controller and services
func DeleteRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
router, err := routers.DeleteRouter(namespace)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(router)
}
func UpdateRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
newRouter := Router{}
err := request.ReadEntity(&newRouter)
if err != nil {
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
serviceType, annotationMap, err := parseParameter(newRouter)
router, err := routers.UpdateRouter(namespace, serviceType, annotationMap)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(router)
}
func parseParameter(router Router) (routerType v1.ServiceType, annotationMap map[string]string, err error) {
routerType = v1.ServiceTypeNodePort
if strings.Compare(strings.ToLower(router.RouterType), "loadbalancer") == 0 {
routerType = v1.ServiceTypeLoadBalancer
}
return routerType, router.Annotations, nil
}
...@@ -31,7 +31,7 @@ import ( ...@@ -31,7 +31,7 @@ import (
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models/iam" "kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/metrics" "kubesphere.io/kubesphere/pkg/models/metrics"
"kubesphere.io/kubesphere/pkg/models/resources" "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/tenant" "kubesphere.io/kubesphere/pkg/models/tenant"
"kubesphere.io/kubesphere/pkg/models/workspaces" "kubesphere.io/kubesphere/pkg/models/workspaces"
"kubesphere.io/kubesphere/pkg/server/errors" "kubesphere.io/kubesphere/pkg/server/errors"
...@@ -64,7 +64,7 @@ func ListWorkspaces(req *restful.Request, resp *restful.Response) { ...@@ -64,7 +64,7 @@ func ListWorkspaces(req *restful.Request, resp *restful.Response) {
reverse := params.ParseReverse(req) reverse := params.ParseReverse(req)
if orderBy == "" { if orderBy == "" {
orderBy = resources.CreateTime orderBy = v1alpha2.CreateTime
reverse = true reverse = true
} }
......
/*
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 workloadstatuses
import (
"github.com/emicklei/go-restful"
"net/http"
"kubesphere.io/kubesphere/pkg/models/status"
"kubesphere.io/kubesphere/pkg/server/errors"
)
func GetClusterAbnormalWorkloads(req *restful.Request, resp *restful.Response) {
res, err := status.GetClusterResourceStatus()
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(res)
}
func GetNamespacedAbnormalWorkloads(req *restful.Request, resp *restful.Response) {
res, err := status.GetNamespacesResourceStatus(req.PathParameter("namespace"))
if err != nil {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
resp.WriteAsJson(res)
}
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
rest "k8s.io/client-go/rest" rest "k8s.io/client-go/rest"
flowcontrol "k8s.io/client-go/util/flowcontrol" flowcontrol "k8s.io/client-go/util/flowcontrol"
devopsv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/devops/v1alpha1" devopsv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/devops/v1alpha1"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/logging/v1alpha2"
networkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1" networkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/tenant/v1alpha1"
...@@ -33,6 +34,7 @@ import ( ...@@ -33,6 +34,7 @@ import (
type Interface interface { type Interface interface {
Discovery() discovery.DiscoveryInterface Discovery() discovery.DiscoveryInterface
DevopsV1alpha1() devopsv1alpha1.DevopsV1alpha1Interface DevopsV1alpha1() devopsv1alpha1.DevopsV1alpha1Interface
LoggingV1alpha2() loggingv1alpha2.LoggingV1alpha2Interface
NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface
ServicemeshV1alpha2() servicemeshv1alpha2.ServicemeshV1alpha2Interface ServicemeshV1alpha2() servicemeshv1alpha2.ServicemeshV1alpha2Interface
TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface
...@@ -43,6 +45,7 @@ type Interface interface { ...@@ -43,6 +45,7 @@ type Interface interface {
type Clientset struct { type Clientset struct {
*discovery.DiscoveryClient *discovery.DiscoveryClient
devopsV1alpha1 *devopsv1alpha1.DevopsV1alpha1Client devopsV1alpha1 *devopsv1alpha1.DevopsV1alpha1Client
loggingV1alpha2 *loggingv1alpha2.LoggingV1alpha2Client
networkV1alpha1 *networkv1alpha1.NetworkV1alpha1Client networkV1alpha1 *networkv1alpha1.NetworkV1alpha1Client
servicemeshV1alpha2 *servicemeshv1alpha2.ServicemeshV1alpha2Client servicemeshV1alpha2 *servicemeshv1alpha2.ServicemeshV1alpha2Client
tenantV1alpha1 *tenantv1alpha1.TenantV1alpha1Client tenantV1alpha1 *tenantv1alpha1.TenantV1alpha1Client
...@@ -53,6 +56,11 @@ func (c *Clientset) DevopsV1alpha1() devopsv1alpha1.DevopsV1alpha1Interface { ...@@ -53,6 +56,11 @@ func (c *Clientset) DevopsV1alpha1() devopsv1alpha1.DevopsV1alpha1Interface {
return c.devopsV1alpha1 return c.devopsV1alpha1
} }
// LoggingV1alpha2 retrieves the LoggingV1alpha2Client
func (c *Clientset) LoggingV1alpha2() loggingv1alpha2.LoggingV1alpha2Interface {
return c.loggingV1alpha2
}
// NetworkV1alpha1 retrieves the NetworkV1alpha1Client // NetworkV1alpha1 retrieves the NetworkV1alpha1Client
func (c *Clientset) NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface { func (c *Clientset) NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface {
return c.networkV1alpha1 return c.networkV1alpha1
...@@ -93,6 +101,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { ...@@ -93,6 +101,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
cs.loggingV1alpha2, err = loggingv1alpha2.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.networkV1alpha1, err = networkv1alpha1.NewForConfig(&configShallowCopy) cs.networkV1alpha1, err = networkv1alpha1.NewForConfig(&configShallowCopy)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -118,6 +130,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { ...@@ -118,6 +130,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
func NewForConfigOrDie(c *rest.Config) *Clientset { func NewForConfigOrDie(c *rest.Config) *Clientset {
var cs Clientset var cs Clientset
cs.devopsV1alpha1 = devopsv1alpha1.NewForConfigOrDie(c) cs.devopsV1alpha1 = devopsv1alpha1.NewForConfigOrDie(c)
cs.loggingV1alpha2 = loggingv1alpha2.NewForConfigOrDie(c)
cs.networkV1alpha1 = networkv1alpha1.NewForConfigOrDie(c) cs.networkV1alpha1 = networkv1alpha1.NewForConfigOrDie(c)
cs.servicemeshV1alpha2 = servicemeshv1alpha2.NewForConfigOrDie(c) cs.servicemeshV1alpha2 = servicemeshv1alpha2.NewForConfigOrDie(c)
cs.tenantV1alpha1 = tenantv1alpha1.NewForConfigOrDie(c) cs.tenantV1alpha1 = tenantv1alpha1.NewForConfigOrDie(c)
...@@ -130,6 +143,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { ...@@ -130,6 +143,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
func New(c rest.Interface) *Clientset { func New(c rest.Interface) *Clientset {
var cs Clientset var cs Clientset
cs.devopsV1alpha1 = devopsv1alpha1.New(c) cs.devopsV1alpha1 = devopsv1alpha1.New(c)
cs.loggingV1alpha2 = loggingv1alpha2.New(c)
cs.networkV1alpha1 = networkv1alpha1.New(c) cs.networkV1alpha1 = networkv1alpha1.New(c)
cs.servicemeshV1alpha2 = servicemeshv1alpha2.New(c) cs.servicemeshV1alpha2 = servicemeshv1alpha2.New(c)
cs.tenantV1alpha1 = tenantv1alpha1.New(c) cs.tenantV1alpha1 = tenantv1alpha1.New(c)
......
...@@ -27,6 +27,8 @@ import ( ...@@ -27,6 +27,8 @@ import (
clientset "kubesphere.io/kubesphere/pkg/client/clientset/versioned" clientset "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
devopsv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/devops/v1alpha1" devopsv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/devops/v1alpha1"
fakedevopsv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/devops/v1alpha1/fake" fakedevopsv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/devops/v1alpha1/fake"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/logging/v1alpha2"
fakeloggingv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/logging/v1alpha2/fake"
networkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1" networkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1"
fakenetworkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1/fake" fakenetworkv1alpha1 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1/fake"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/servicemesh/v1alpha2"
...@@ -87,6 +89,11 @@ func (c *Clientset) DevopsV1alpha1() devopsv1alpha1.DevopsV1alpha1Interface { ...@@ -87,6 +89,11 @@ func (c *Clientset) DevopsV1alpha1() devopsv1alpha1.DevopsV1alpha1Interface {
return &fakedevopsv1alpha1.FakeDevopsV1alpha1{Fake: &c.Fake} return &fakedevopsv1alpha1.FakeDevopsV1alpha1{Fake: &c.Fake}
} }
// LoggingV1alpha2 retrieves the LoggingV1alpha2Client
func (c *Clientset) LoggingV1alpha2() loggingv1alpha2.LoggingV1alpha2Interface {
return &fakeloggingv1alpha2.FakeLoggingV1alpha2{Fake: &c.Fake}
}
// NetworkV1alpha1 retrieves the NetworkV1alpha1Client // NetworkV1alpha1 retrieves the NetworkV1alpha1Client
func (c *Clientset) NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface { func (c *Clientset) NetworkV1alpha1() networkv1alpha1.NetworkV1alpha1Interface {
return &fakenetworkv1alpha1.FakeNetworkV1alpha1{Fake: &c.Fake} return &fakenetworkv1alpha1.FakeNetworkV1alpha1{Fake: &c.Fake}
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
serializer "k8s.io/apimachinery/pkg/runtime/serializer" serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1" devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
...@@ -35,6 +36,7 @@ var codecs = serializer.NewCodecFactory(scheme) ...@@ -35,6 +36,7 @@ var codecs = serializer.NewCodecFactory(scheme)
var parameterCodec = runtime.NewParameterCodec(scheme) var parameterCodec = runtime.NewParameterCodec(scheme)
var localSchemeBuilder = runtime.SchemeBuilder{ var localSchemeBuilder = runtime.SchemeBuilder{
devopsv1alpha1.AddToScheme, devopsv1alpha1.AddToScheme,
loggingv1alpha2.AddToScheme,
networkv1alpha1.AddToScheme, networkv1alpha1.AddToScheme,
servicemeshv1alpha2.AddToScheme, servicemeshv1alpha2.AddToScheme,
tenantv1alpha1.AddToScheme, tenantv1alpha1.AddToScheme,
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
serializer "k8s.io/apimachinery/pkg/runtime/serializer" serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1" devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
...@@ -35,6 +36,7 @@ var Codecs = serializer.NewCodecFactory(Scheme) ...@@ -35,6 +36,7 @@ var Codecs = serializer.NewCodecFactory(Scheme)
var ParameterCodec = runtime.NewParameterCodec(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme)
var localSchemeBuilder = runtime.SchemeBuilder{ var localSchemeBuilder = runtime.SchemeBuilder{
devopsv1alpha1.AddToScheme, devopsv1alpha1.AddToScheme,
loggingv1alpha2.AddToScheme,
networkv1alpha1.AddToScheme, networkv1alpha1.AddToScheme,
servicemeshv1alpha2.AddToScheme, servicemeshv1alpha2.AddToScheme,
tenantv1alpha1.AddToScheme, tenantv1alpha1.AddToScheme,
......
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1alpha2
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
)
// FakeFluentBits implements FluentBitInterface
type FakeFluentBits struct {
Fake *FakeLoggingV1alpha2
ns string
}
var fluentbitsResource = schema.GroupVersionResource{Group: "logging.kubesphere.io", Version: "v1alpha2", Resource: "fluentbits"}
var fluentbitsKind = schema.GroupVersionKind{Group: "logging.kubesphere.io", Version: "v1alpha2", Kind: "FluentBit"}
// Get takes name of the fluentBit, and returns the corresponding fluentBit object, and an error if there is any.
func (c *FakeFluentBits) Get(name string, options v1.GetOptions) (result *v1alpha2.FluentBit, err error) {
obj, err := c.Fake.
Invokes(testing.NewGetAction(fluentbitsResource, c.ns, name), &v1alpha2.FluentBit{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.FluentBit), err
}
// List takes label and field selectors, and returns the list of FluentBits that match those selectors.
func (c *FakeFluentBits) List(opts v1.ListOptions) (result *v1alpha2.FluentBitList, err error) {
obj, err := c.Fake.
Invokes(testing.NewListAction(fluentbitsResource, fluentbitsKind, c.ns, opts), &v1alpha2.FluentBitList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha2.FluentBitList{ListMeta: obj.(*v1alpha2.FluentBitList).ListMeta}
for _, item := range obj.(*v1alpha2.FluentBitList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested fluentBits.
func (c *FakeFluentBits) Watch(opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(fluentbitsResource, c.ns, opts))
}
// Create takes the representation of a fluentBit and creates it. Returns the server's representation of the fluentBit, and an error, if there is any.
func (c *FakeFluentBits) Create(fluentBit *v1alpha2.FluentBit) (result *v1alpha2.FluentBit, err error) {
obj, err := c.Fake.
Invokes(testing.NewCreateAction(fluentbitsResource, c.ns, fluentBit), &v1alpha2.FluentBit{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.FluentBit), err
}
// Update takes the representation of a fluentBit and updates it. Returns the server's representation of the fluentBit, and an error, if there is any.
func (c *FakeFluentBits) Update(fluentBit *v1alpha2.FluentBit) (result *v1alpha2.FluentBit, err error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(fluentbitsResource, c.ns, fluentBit), &v1alpha2.FluentBit{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.FluentBit), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeFluentBits) UpdateStatus(fluentBit *v1alpha2.FluentBit) (*v1alpha2.FluentBit, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(fluentbitsResource, "status", c.ns, fluentBit), &v1alpha2.FluentBit{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.FluentBit), err
}
// Delete takes name of the fluentBit and deletes it. Returns an error if one occurs.
func (c *FakeFluentBits) Delete(name string, options *v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(fluentbitsResource, c.ns, name), &v1alpha2.FluentBit{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeFluentBits) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(fluentbitsResource, c.ns, listOptions)
_, err := c.Fake.Invokes(action, &v1alpha2.FluentBitList{})
return err
}
// Patch applies the patch and returns the patched fluentBit.
func (c *FakeFluentBits) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.FluentBit, err error) {
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(fluentbitsResource, c.ns, name, pt, data, subresources...), &v1alpha2.FluentBit{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha2.FluentBit), err
}
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
v1alpha2 "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/logging/v1alpha2"
)
type FakeLoggingV1alpha2 struct {
*testing.Fake
}
func (c *FakeLoggingV1alpha2) FluentBits(namespace string) v1alpha2.FluentBitInterface {
return &FakeFluentBits{c, namespace}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeLoggingV1alpha2) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha2
import (
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
// FluentBitsGetter has a method to return a FluentBitInterface.
// A group's client should implement this interface.
type FluentBitsGetter interface {
FluentBits(namespace string) FluentBitInterface
}
// FluentBitInterface has methods to work with FluentBit resources.
type FluentBitInterface interface {
Create(*v1alpha2.FluentBit) (*v1alpha2.FluentBit, error)
Update(*v1alpha2.FluentBit) (*v1alpha2.FluentBit, error)
UpdateStatus(*v1alpha2.FluentBit) (*v1alpha2.FluentBit, error)
Delete(name string, options *v1.DeleteOptions) error
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
Get(name string, options v1.GetOptions) (*v1alpha2.FluentBit, error)
List(opts v1.ListOptions) (*v1alpha2.FluentBitList, error)
Watch(opts v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.FluentBit, err error)
FluentBitExpansion
}
// fluentBits implements FluentBitInterface
type fluentBits struct {
client rest.Interface
ns string
}
// newFluentBits returns a FluentBits
func newFluentBits(c *LoggingV1alpha2Client, namespace string) *fluentBits {
return &fluentBits{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the fluentBit, and returns the corresponding fluentBit object, and an error if there is any.
func (c *fluentBits) Get(name string, options v1.GetOptions) (result *v1alpha2.FluentBit, err error) {
result = &v1alpha2.FluentBit{}
err = c.client.Get().
Namespace(c.ns).
Resource("fluentbits").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of FluentBits that match those selectors.
func (c *fluentBits) List(opts v1.ListOptions) (result *v1alpha2.FluentBitList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha2.FluentBitList{}
err = c.client.Get().
Namespace(c.ns).
Resource("fluentbits").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested fluentBits.
func (c *fluentBits) Watch(opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("fluentbits").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch()
}
// Create takes the representation of a fluentBit and creates it. Returns the server's representation of the fluentBit, and an error, if there is any.
func (c *fluentBits) Create(fluentBit *v1alpha2.FluentBit) (result *v1alpha2.FluentBit, err error) {
result = &v1alpha2.FluentBit{}
err = c.client.Post().
Namespace(c.ns).
Resource("fluentbits").
Body(fluentBit).
Do().
Into(result)
return
}
// Update takes the representation of a fluentBit and updates it. Returns the server's representation of the fluentBit, and an error, if there is any.
func (c *fluentBits) Update(fluentBit *v1alpha2.FluentBit) (result *v1alpha2.FluentBit, err error) {
result = &v1alpha2.FluentBit{}
err = c.client.Put().
Namespace(c.ns).
Resource("fluentbits").
Name(fluentBit.Name).
Body(fluentBit).
Do().
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *fluentBits) UpdateStatus(fluentBit *v1alpha2.FluentBit) (result *v1alpha2.FluentBit, err error) {
result = &v1alpha2.FluentBit{}
err = c.client.Put().
Namespace(c.ns).
Resource("fluentbits").
Name(fluentBit.Name).
SubResource("status").
Body(fluentBit).
Do().
Into(result)
return
}
// Delete takes name of the fluentBit and deletes it. Returns an error if one occurs.
func (c *fluentBits) Delete(name string, options *v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("fluentbits").
Name(name).
Body(options).
Do().
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *fluentBits) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
var timeout time.Duration
if listOptions.TimeoutSeconds != nil {
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("fluentbits").
VersionedParams(&listOptions, scheme.ParameterCodec).
Timeout(timeout).
Body(options).
Do().
Error()
}
// Patch applies the patch and returns the patched fluentBit.
func (c *fluentBits) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.FluentBit, err error) {
result = &v1alpha2.FluentBit{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("fluentbits").
SubResource(subresources...).
Name(name).
Body(data).
Do().
Into(result)
return
}
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha2
type FluentBitExpansion interface{}
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1alpha2
import (
rest "k8s.io/client-go/rest"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme"
)
type LoggingV1alpha2Interface interface {
RESTClient() rest.Interface
FluentBitsGetter
}
// LoggingV1alpha2Client is used to interact with features provided by the logging.kubesphere.io group.
type LoggingV1alpha2Client struct {
restClient rest.Interface
}
func (c *LoggingV1alpha2Client) FluentBits(namespace string) FluentBitInterface {
return newFluentBits(c, namespace)
}
// NewForConfig creates a new LoggingV1alpha2Client for the given config.
func NewForConfig(c *rest.Config) (*LoggingV1alpha2Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &LoggingV1alpha2Client{client}, nil
}
// NewForConfigOrDie creates a new LoggingV1alpha2Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *LoggingV1alpha2Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new LoggingV1alpha2Client for the given RESTClient.
func New(c rest.Interface) *LoggingV1alpha2Client {
return &LoggingV1alpha2Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1alpha2.SchemeGroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *LoggingV1alpha2Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned" versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
devops "kubesphere.io/kubesphere/pkg/client/informers/externalversions/devops" devops "kubesphere.io/kubesphere/pkg/client/informers/externalversions/devops"
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces" internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
logging "kubesphere.io/kubesphere/pkg/client/informers/externalversions/logging"
network "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network" network "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network"
servicemesh "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh" servicemesh "kubesphere.io/kubesphere/pkg/client/informers/externalversions/servicemesh"
tenant "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant" tenant "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant"
...@@ -176,6 +177,7 @@ type SharedInformerFactory interface { ...@@ -176,6 +177,7 @@ type SharedInformerFactory interface {
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
Devops() devops.Interface Devops() devops.Interface
Logging() logging.Interface
Network() network.Interface Network() network.Interface
Servicemesh() servicemesh.Interface Servicemesh() servicemesh.Interface
Tenant() tenant.Interface Tenant() tenant.Interface
...@@ -185,6 +187,10 @@ func (f *sharedInformerFactory) Devops() devops.Interface { ...@@ -185,6 +187,10 @@ func (f *sharedInformerFactory) Devops() devops.Interface {
return devops.New(f, f.namespace, f.tweakListOptions) return devops.New(f, f.namespace, f.tweakListOptions)
} }
func (f *sharedInformerFactory) Logging() logging.Interface {
return logging.New(f, f.namespace, f.tweakListOptions)
}
func (f *sharedInformerFactory) Network() network.Interface { func (f *sharedInformerFactory) Network() network.Interface {
return network.New(f, f.namespace, f.tweakListOptions) return network.New(f, f.namespace, f.tweakListOptions)
} }
......
...@@ -24,8 +24,9 @@ import ( ...@@ -24,8 +24,9 @@ import (
schema "k8s.io/apimachinery/pkg/runtime/schema" schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache" cache "k8s.io/client-go/tools/cache"
v1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1" v1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/apis/servicemesh/v1alpha2"
tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" tenantv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
) )
...@@ -59,6 +60,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource ...@@ -59,6 +60,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
case v1alpha1.SchemeGroupVersion.WithResource("s2ibinaries"): case v1alpha1.SchemeGroupVersion.WithResource("s2ibinaries"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Devops().V1alpha1().S2iBinaries().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Devops().V1alpha1().S2iBinaries().Informer()}, nil
// Group=logging.kubesphere.io, Version=v1alpha2
case v1alpha2.SchemeGroupVersion.WithResource("fluentbits"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Logging().V1alpha2().FluentBits().Informer()}, nil
// Group=network.kubesphere.io, Version=v1alpha1 // Group=network.kubesphere.io, Version=v1alpha1
case networkv1alpha1.SchemeGroupVersion.WithResource("namespacenetworkpolicies"): case networkv1alpha1.SchemeGroupVersion.WithResource("namespacenetworkpolicies"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Network().V1alpha1().NamespaceNetworkPolicies().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Network().V1alpha1().NamespaceNetworkPolicies().Informer()}, nil
...@@ -66,9 +71,9 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource ...@@ -66,9 +71,9 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
return &genericInformer{resource: resource.GroupResource(), informer: f.Network().V1alpha1().WorkspaceNetworkPolicies().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Network().V1alpha1().WorkspaceNetworkPolicies().Informer()}, nil
// Group=servicemesh.kubesphere.io, Version=v1alpha2 // Group=servicemesh.kubesphere.io, Version=v1alpha2
case v1alpha2.SchemeGroupVersion.WithResource("servicepolicies"): case servicemeshv1alpha2.SchemeGroupVersion.WithResource("servicepolicies"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Servicemesh().V1alpha2().ServicePolicies().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Servicemesh().V1alpha2().ServicePolicies().Informer()}, nil
case v1alpha2.SchemeGroupVersion.WithResource("strategies"): case servicemeshv1alpha2.SchemeGroupVersion.WithResource("strategies"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Servicemesh().V1alpha2().Strategies().Informer()}, nil return &genericInformer{resource: resource.GroupResource(), informer: f.Servicemesh().V1alpha2().Strategies().Informer()}, nil
// Group=tenant.kubesphere.io, Version=v1alpha1 // Group=tenant.kubesphere.io, Version=v1alpha1
......
/*
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package logging
import (
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
v1alpha2 "kubesphere.io/kubesphere/pkg/client/informers/externalversions/logging/v1alpha2"
)
// Interface provides access to each of this group's versions.
type Interface interface {
// V1alpha2 provides access to shared informers for resources in V1alpha2.
V1alpha2() v1alpha2.Interface
}
type group struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// V1alpha2 returns a new v1alpha2.Interface.
func (g *group) V1alpha2() v1alpha2.Interface {
return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions)
}
/*
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha2
import (
time "time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
v1alpha2 "kubesphere.io/kubesphere/pkg/client/listers/logging/v1alpha2"
)
// FluentBitInformer provides access to a shared informer and lister for
// FluentBits.
type FluentBitInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha2.FluentBitLister
}
type fluentBitInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}
// NewFluentBitInformer constructs a new informer for FluentBit type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFluentBitInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredFluentBitInformer(client, namespace, resyncPeriod, indexers, nil)
}
// NewFilteredFluentBitInformer constructs a new informer for FluentBit type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredFluentBitInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.LoggingV1alpha2().FluentBits(namespace).List(options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.LoggingV1alpha2().FluentBits(namespace).Watch(options)
},
},
&loggingv1alpha2.FluentBit{},
resyncPeriod,
indexers,
)
}
func (f *fluentBitInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredFluentBitInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *fluentBitInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&loggingv1alpha2.FluentBit{}, f.defaultInformer)
}
func (f *fluentBitInformer) Lister() v1alpha2.FluentBitLister {
return v1alpha2.NewFluentBitLister(f.Informer().GetIndexer())
}
/*
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha2
import (
internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces"
)
// Interface provides access to all the informers in this group version.
type Interface interface {
// FluentBits returns a FluentBitInformer.
FluentBits() FluentBitInformer
}
type version struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// FluentBits returns a FluentBitInformer.
func (v *version) FluentBits() FluentBitInformer {
return &fluentBitInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
/*
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha2
// FluentBitListerExpansion allows custom methods to be added to
// FluentBitLister.
type FluentBitListerExpansion interface{}
// FluentBitNamespaceListerExpansion allows custom methods to be added to
// FluentBitNamespaceLister.
type FluentBitNamespaceListerExpansion interface{}
/*
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha2
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1alpha2 "kubesphere.io/kubesphere/pkg/apis/logging/v1alpha2"
)
// FluentBitLister helps list FluentBits.
type FluentBitLister interface {
// List lists all FluentBits in the indexer.
List(selector labels.Selector) (ret []*v1alpha2.FluentBit, err error)
// FluentBits returns an object that can list and get FluentBits.
FluentBits(namespace string) FluentBitNamespaceLister
FluentBitListerExpansion
}
// fluentBitLister implements the FluentBitLister interface.
type fluentBitLister struct {
indexer cache.Indexer
}
// NewFluentBitLister returns a new FluentBitLister.
func NewFluentBitLister(indexer cache.Indexer) FluentBitLister {
return &fluentBitLister{indexer: indexer}
}
// List lists all FluentBits in the indexer.
func (s *fluentBitLister) List(selector labels.Selector) (ret []*v1alpha2.FluentBit, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha2.FluentBit))
})
return ret, err
}
// FluentBits returns an object that can list and get FluentBits.
func (s *fluentBitLister) FluentBits(namespace string) FluentBitNamespaceLister {
return fluentBitNamespaceLister{indexer: s.indexer, namespace: namespace}
}
// FluentBitNamespaceLister helps list and get FluentBits.
type FluentBitNamespaceLister interface {
// List lists all FluentBits in the indexer for a given namespace.
List(selector labels.Selector) (ret []*v1alpha2.FluentBit, err error)
// Get retrieves the FluentBit from the indexer for a given namespace and name.
Get(name string) (*v1alpha2.FluentBit, error)
FluentBitNamespaceListerExpansion
}
// fluentBitNamespaceLister implements the FluentBitNamespaceLister
// interface.
type fluentBitNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all FluentBits in the indexer for a given namespace.
func (s fluentBitNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.FluentBit, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha2.FluentBit))
})
return ret, err
}
// Get retrieves the FluentBit from the indexer for a given namespace and name.
func (s fluentBitNamespaceLister) Get(name string) (*v1alpha2.FluentBit, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha2.Resource("fluentbit"), name)
}
return obj.(*v1alpha2.FluentBit), nil
}
...@@ -31,8 +31,6 @@ const ( ...@@ -31,8 +31,6 @@ const (
PorterNamespace = "porter-system" PorterNamespace = "porter-system"
IngressControllerNamespace = KubeSphereControlNamespace IngressControllerNamespace = KubeSphereControlNamespace
AdminUserName = "admin" AdminUserName = "admin"
DataHome = "/etc/kubesphere"
IngressControllerFolder = DataHome + "/ingress-controller"
IngressControllerPrefix = "kubesphere-router-" IngressControllerPrefix = "kubesphere-router-"
WorkspaceLabelKey = "kubesphere.io/workspace" WorkspaceLabelKey = "kubesphere.io/workspace"
......
...@@ -32,7 +32,6 @@ import ( ...@@ -32,7 +32,6 @@ import (
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
cs "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix" "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/utils/k8sutil" "kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
...@@ -101,7 +100,8 @@ var _ reconcile.Reconciler = &ReconcileNamespace{} ...@@ -101,7 +100,8 @@ var _ reconcile.Reconciler = &ReconcileNamespace{}
// ReconcileNamespace reconciles a Namespace object // ReconcileNamespace reconciles a Namespace object
type ReconcileNamespace struct { type ReconcileNamespace struct {
client.Client client.Client
scheme *runtime.Scheme openpitrixClient *openpitrix.Client
scheme *runtime.Scheme
} }
// Reconcile reads that state of the cluster for a Namespace object and makes changes based on the state read // Reconcile reads that state of the cluster for a Namespace object and makes changes based on the state read
...@@ -359,18 +359,9 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace) ...@@ -359,18 +359,9 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace)
return nil return nil
} }
openPitrixClient, err := cs.ClientSets().OpenPitrix()
if _, notEnabled := err.(cs.ClientSetNotEnabledError); notEnabled {
return nil
} else if err != nil {
klog.Error(fmt.Sprintf("create runtime, namespace: %s, error: %s", namespace.Name, err))
return err
}
adminKubeConfigName := fmt.Sprintf("kubeconfig-%s", constants.AdminUserName) adminKubeConfigName := fmt.Sprintf("kubeconfig-%s", constants.AdminUserName)
runtimeCredentials, err := openPitrixClient.Runtime().DescribeRuntimeCredentials(openpitrix.SystemContext(), &pb.DescribeRuntimeCredentialsRequest{SearchWord: &wrappers.StringValue{Value: adminKubeConfigName}, Limit: 1}) runtimeCredentials, err := r.openpitrixClient.Runtime().DescribeRuntimeCredentials(openpitrix.SystemContext(), &pb.DescribeRuntimeCredentialsRequest{SearchWord: &wrappers.StringValue{Value: adminKubeConfigName}, Limit: 1})
if err != nil { if err != nil {
klog.Error(fmt.Sprintf("create runtime, namespace: %s, error: %s", namespace.Name, err)) klog.Error(fmt.Sprintf("create runtime, namespace: %s, error: %s", namespace.Name, err))
...@@ -391,7 +382,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace) ...@@ -391,7 +382,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace)
return err return err
} }
resp, err := openPitrixClient.Runtime().CreateRuntimeCredential(openpitrix.SystemContext(), &pb.CreateRuntimeCredentialRequest{ resp, err := r.openpitrixClient.Runtime().CreateRuntimeCredential(openpitrix.SystemContext(), &pb.CreateRuntimeCredentialRequest{
Name: &wrappers.StringValue{Value: adminKubeConfigName}, Name: &wrappers.StringValue{Value: adminKubeConfigName},
Provider: &wrappers.StringValue{Value: "kubernetes"}, Provider: &wrappers.StringValue{Value: "kubernetes"},
Description: &wrappers.StringValue{Value: "kubeconfig"}, Description: &wrappers.StringValue{Value: "kubeconfig"},
...@@ -408,7 +399,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace) ...@@ -408,7 +399,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace)
} }
// TODO runtime id is invalid when recreate runtime // TODO runtime id is invalid when recreate runtime
runtimeId, err := openPitrixClient.Runtime().CreateRuntime(openpitrix.SystemContext(), &pb.CreateRuntimeRequest{ runtimeId, err := r.openpitrixClient.Runtime().CreateRuntime(openpitrix.SystemContext(), &pb.CreateRuntimeRequest{
Name: &wrappers.StringValue{Value: namespace.Name}, Name: &wrappers.StringValue{Value: namespace.Name},
RuntimeCredentialId: &wrappers.StringValue{Value: kubesphereRuntimeCredentialId}, RuntimeCredentialId: &wrappers.StringValue{Value: kubesphereRuntimeCredentialId},
Provider: &wrappers.StringValue{Value: openpitrix.KubernetesProvider}, Provider: &wrappers.StringValue{Value: openpitrix.KubernetesProvider},
...@@ -429,17 +420,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace) ...@@ -429,17 +420,7 @@ func (r *ReconcileNamespace) checkAndCreateRuntime(namespace *corev1.Namespace)
func (r *ReconcileNamespace) deleteRuntime(namespace *corev1.Namespace) error { func (r *ReconcileNamespace) deleteRuntime(namespace *corev1.Namespace) error {
if runtimeId := namespace.Annotations[constants.OpenPitrixRuntimeAnnotationKey]; runtimeId != "" { if runtimeId := namespace.Annotations[constants.OpenPitrixRuntimeAnnotationKey]; runtimeId != "" {
_, err := r.openpitrixClient.Runtime().DeleteRuntimes(openpitrix.SystemContext(), &pb.DeleteRuntimesRequest{RuntimeId: []string{runtimeId}, Force: &wrappers.BoolValue{Value: true}})
openPitrixClient, err := cs.ClientSets().OpenPitrix()
if _, notEnabled := err.(cs.ClientSetNotEnabledError); notEnabled {
return nil
} else if err != nil {
klog.Errorf("delete openpitrix runtime: %s, error: %s", runtimeId, err)
return err
}
_, err = openPitrixClient.Runtime().DeleteRuntimes(openpitrix.SystemContext(), &pb.DeleteRuntimesRequest{RuntimeId: []string{runtimeId}, Force: &wrappers.BoolValue{Value: true}})
if err == nil || openpitrix.IsNotFound(err) || openpitrix.IsDeleted(err) { if err == nil || openpitrix.IsNotFound(err) || openpitrix.IsDeleted(err) {
return nil return nil
......
...@@ -2,9 +2,6 @@ package s2ibinary ...@@ -2,9 +2,6 @@ package s2ibinary
import ( import (
"fmt" "fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/s3"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
...@@ -16,7 +13,7 @@ import ( ...@@ -16,7 +13,7 @@ import (
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/simple/client" "kubesphere.io/kubesphere/pkg/simple/client/s3"
"kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/utils/sliceutil"
"time" "time"
...@@ -39,6 +36,8 @@ type S2iBinaryController struct { ...@@ -39,6 +36,8 @@ type S2iBinaryController struct {
workqueue workqueue.RateLimitingInterface workqueue workqueue.RateLimitingInterface
workerLoopPeriod time.Duration workerLoopPeriod time.Duration
s3Client s3.Interface
} }
func NewController(devopsclientset devopsclient.Interface, func NewController(devopsclientset devopsclient.Interface,
...@@ -205,29 +204,12 @@ func (c *S2iBinaryController) syncHandler(key string) error { ...@@ -205,29 +204,12 @@ func (c *S2iBinaryController) syncHandler(key string) error {
} }
func (c *S2iBinaryController) deleteBinaryInS3(s2ibin *devopsv1alpha1.S2iBinary) error { func (c *S2iBinaryController) deleteBinaryInS3(s2ibin *devopsv1alpha1.S2iBinary) error {
s3Client, err := client.ClientSets().S3()
if err != nil {
return err
}
input := &s3.DeleteObjectInput{ key := fmt.Sprintf("%s-%s", s2ibin.Namespace, s2ibin.Name)
Bucket: s3Client.Bucket(), err := c.s3Client.Delete(key)
Key: aws.String(fmt.Sprintf("%s-%s", s2ibin.Namespace, s2ibin.Name)),
}
_, err = s3Client.Client().DeleteObject(input)
if err != nil { if err != nil {
if aerr, ok := err.(awserr.Error); ok { klog.Errorf("error happened while deleting %s, %v", key, err)
switch aerr.Code() {
case s3.ErrCodeNoSuchKey:
return nil
default:
klog.Error(err, fmt.Sprintf("failed to delete s2ibin %s/%s in s3", s2ibin.Namespace, s2ibin.Name))
return err
}
} else {
klog.Error(err, fmt.Sprintf("failed to delete s2ibin %s/%s in s3", s2ibin.Namespace, s2ibin.Name))
return err
}
} }
return nil return nil
} }
...@@ -324,15 +324,6 @@ func (r *ReconcileWorkspace) deleteGroup(instance *tenantv1alpha1.Workspace) err ...@@ -324,15 +324,6 @@ func (r *ReconcileWorkspace) deleteGroup(instance *tenantv1alpha1.Workspace) err
} }
func (r *ReconcileWorkspace) deleteDevOpsProjects(instance *tenantv1alpha1.Workspace) error { func (r *ReconcileWorkspace) deleteDevOpsProjects(instance *tenantv1alpha1.Workspace) error {
if _, err := cs.ClientSets().Devops(); err != nil {
// skip if devops is not enabled
if _, notEnabled := err.(cs.ClientSetNotEnabledError); notEnabled {
return nil
} else {
log.Error(err, "")
return err
}
}
var wg sync.WaitGroup var wg sync.WaitGroup
log.Info("Delete DevOps Projects") log.Info("Delete DevOps Projects")
......
...@@ -18,56 +18,67 @@ ...@@ -18,56 +18,67 @@
package informers package informers
import ( import (
applicationclient "github.com/kubernetes-sigs/application/pkg/client/clientset/versioned"
applicationinformers "github.com/kubernetes-sigs/application/pkg/client/informers/externalversions" applicationinformers "github.com/kubernetes-sigs/application/pkg/client/informers/externalversions"
s2i "github.com/kubesphere/s2ioperator/pkg/client/clientset/versioned"
s2iinformers "github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions" s2iinformers "github.com/kubesphere/s2ioperator/pkg/client/informers/externalversions"
k8sinformers "k8s.io/client-go/informers" k8sinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions" ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
"kubesphere.io/kubesphere/pkg/simple/client"
"sync"
"time" "time"
) )
const defaultResync = 600 * time.Second const defaultResync = 600 * time.Second
var ( type InformerFactory interface {
k8sOnce sync.Once KubernetesSharedInformerFactory() k8sinformers.SharedInformerFactory
s2iOnce sync.Once S2iSharedInformerFactory() s2iinformers.SharedInformerFactory
ksOnce sync.Once KubeSphereSharedInformerFactory() ksinformers.SharedInformerFactory
appOnce sync.Once ApplicationSharedInformerFactory() applicationinformers.SharedInformerFactory
}
type informerFactories struct {
informerFactory k8sinformers.SharedInformerFactory informerFactory k8sinformers.SharedInformerFactory
s2iInformerFactory s2iinformers.SharedInformerFactory s2iInformerFactory s2iinformers.SharedInformerFactory
ksInformerFactory ksinformers.SharedInformerFactory ksInformerFactory ksinformers.SharedInformerFactory
appInformerFactory applicationinformers.SharedInformerFactory appInformerFactory applicationinformers.SharedInformerFactory
) }
func NewInformerFactories(client kubernetes.Interface, ksClient versioned.Interface, s2iClient s2i.Interface, appClient applicationclient.Interface) InformerFactory {
factory := &informerFactories{}
if client != nil {
factory.informerFactory = k8sinformers.NewSharedInformerFactory(client, defaultResync)
}
if ksClient != nil {
factory.ksInformerFactory = ksinformers.NewSharedInformerFactory(ksClient, defaultResync)
}
if s2iClient != nil {
factory.s2iInformerFactory = s2iinformers.NewSharedInformerFactory(s2iClient, defaultResync)
}
if appClient != nil {
factory.appInformerFactory = applicationinformers.NewSharedInformerFactory(appClient, defaultResync)
}
return factory
}
func SharedInformerFactory() k8sinformers.SharedInformerFactory { func (f *informerFactories) KubernetesSharedInformerFactory() k8sinformers.SharedInformerFactory {
k8sOnce.Do(func() { return f.informerFactory
k8sClient := client.ClientSets().K8s().Kubernetes()
informerFactory = k8sinformers.NewSharedInformerFactory(k8sClient, defaultResync)
})
return informerFactory
} }
func S2iSharedInformerFactory() s2iinformers.SharedInformerFactory { func (f *informerFactories) S2iSharedInformerFactory() s2iinformers.SharedInformerFactory {
s2iOnce.Do(func() { return f.s2iInformerFactory
k8sClient := client.ClientSets().K8s().S2i()
s2iInformerFactory = s2iinformers.NewSharedInformerFactory(k8sClient, defaultResync)
})
return s2iInformerFactory
} }
func KsSharedInformerFactory() ksinformers.SharedInformerFactory { func (f *informerFactories) KubeSphereSharedInformerFactory() ksinformers.SharedInformerFactory {
ksOnce.Do(func() { return f.ksInformerFactory
k8sClient := client.ClientSets().K8s().KubeSphere()
ksInformerFactory = ksinformers.NewSharedInformerFactory(k8sClient, defaultResync)
})
return ksInformerFactory
} }
func AppSharedInformerFactory() applicationinformers.SharedInformerFactory { func (f *informerFactories) ApplicationSharedInformerFactory() applicationinformers.SharedInformerFactory {
appOnce.Do(func() { return f.appInformerFactory
appClient := client.ClientSets().K8s().Application()
appInformerFactory = applicationinformers.NewSharedInformerFactory(appClient, defaultResync)
})
return appInformerFactory
} }
...@@ -13,16 +13,17 @@ import ( ...@@ -13,16 +13,17 @@ import (
servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/servicemesh/metrics/v1alpha2" servicemeshv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/servicemesh/metrics/v1alpha2"
tenantv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2" tenantv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/tenant/v1alpha2"
terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2" terminalv1alpha2 "kubesphere.io/kubesphere/pkg/kapis/terminal/v1alpha2"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
) )
func InstallAPIs(container *restful.Container) { func InstallAPIs(container *restful.Container, client k8s.Client) {
urlruntime.Must(servicemeshv1alpha2.AddToContainer(container)) urlruntime.Must(servicemeshv1alpha2.AddToContainer(container))
urlruntime.Must(devopsv1alpha2.AddToContainer(container)) urlruntime.Must(devopsv1alpha2.AddToContainer(container))
urlruntime.Must(loggingv1alpha2.AddToContainer(container)) urlruntime.Must(loggingv1alpha2.AddToContainer(container))
urlruntime.Must(monitoringv1alpha2.AddToContainer(container)) urlruntime.Must(monitoringv1alpha2.AddToContainer(container))
urlruntime.Must(openpitrixv1.AddToContainer(container)) urlruntime.Must(openpitrixv1.AddToContainer(container))
urlruntime.Must(operationsv1alpha2.AddToContainer(container)) urlruntime.Must(operationsv1alpha2.AddToContainer(container, client))
urlruntime.Must(resourcesv1alpha2.AddToContainer(container)) urlruntime.Must(resourcesv1alpha2.AddToContainer(container, client))
urlruntime.Must(tenantv1alpha2.AddToContainer(container)) urlruntime.Must(tenantv1alpha2.AddToContainer(container))
urlruntime.Must(terminalv1alpha2.AddToContainer(container)) urlruntime.Must(terminalv1alpha2.AddToContainer(container))
} }
......
...@@ -26,7 +26,6 @@ import ( ...@@ -26,7 +26,6 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models/log" "kubesphere.io/kubesphere/pkg/models/log"
fluentbitclient "kubesphere.io/kubesphere/pkg/simple/client/fluentbit"
"net/http" "net/http"
) )
......
package v1
import "github.com/emicklei/go-restful"
type openpitrixHandler struct {
}
func newOpenpitrixHandler() *openpitrixHandler {
return &openpitrixHandler{}
}
func (h *openpitrixHandler) handleListApplications(request *restful.Request, response *restful.Response) {
}
...@@ -29,5 +29,5 @@ func init() { ...@@ -29,5 +29,5 @@ func init() {
} }
func Install(container *restful.Container) { func Install(container *restful.Container) {
urlruntime.Must(v1alpha2.AddToContainer(container)) urlruntime.Must(v1alpha2.AddToContainer(container, nil))
} }
package v1alpha2
import (
"fmt"
"github.com/emicklei/go-restful"
k8serr "k8s.io/apimachinery/pkg/api/errors"
"kubesphere.io/kubesphere/pkg/models/workloads"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"net/http"
)
type operationHandler struct {
jobRunner workloads.JobRunner
}
func newOperationHandler(client k8s.Client) *operationHandler {
return &operationHandler{
jobRunner: workloads.NewJobRunner(client.Kubernetes()),
}
}
func (r *operationHandler) handleJobReRun(request *restful.Request, response *restful.Response) {
var err error
job := request.PathParameter("job")
namespace := request.PathParameter("namespace")
action := request.QueryParameter("action")
resourceVersion := request.QueryParameter("resourceVersion")
switch action {
case "rerun":
err = r.jobRunner.JobReRun(namespace, job, resourceVersion)
default:
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("invalid operation %s", action)))
return
}
if err != nil {
if k8serr.IsConflict(err) {
response.WriteHeaderAndEntity(http.StatusConflict, errors.Wrap(err))
return
}
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(errors.None)
}
...@@ -20,9 +20,9 @@ package v1alpha2 ...@@ -20,9 +20,9 @@ package v1alpha2
import ( import (
"github.com/emicklei/go-restful" "github.com/emicklei/go-restful"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apiserver/operations"
"kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/server/errors" "kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"net/http" "net/http"
) )
...@@ -30,25 +30,15 @@ const GroupName = "operations.kubesphere.io" ...@@ -30,25 +30,15 @@ const GroupName = "operations.kubesphere.io"
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"} var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
var ( func AddToContainer(c *restful.Container, client k8s.Client) error {
WebServiceBuilder = runtime.NewContainerBuilder(addWebService)
AddToContainer = WebServiceBuilder.AddToContainer
)
func addWebService(c *restful.Container) error {
ok := "ok" ok := "ok"
webservice := runtime.NewWebService(GroupVersion) webservice := runtime.NewWebService(GroupVersion)
webservice.Route(webservice.POST("/nodes/{node}/drainage"). handler := newOperationHandler(client)
To(operations.DrainNode).
Deprecate().
Doc("remove a node from service, safely evict all of your pods from a node and you can power down the node. More info: https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/").
Param(webservice.PathParameter("node", "node name")).
Returns(http.StatusOK, ok, errors.Error{}))
webservice.Route(webservice.POST("/namespaces/{namespace}/jobs/{job}"). webservice.Route(webservice.POST("/namespaces/{namespace}/jobs/{job}").
To(operations.RerunJob). To(handler.handleJobReRun).
Doc("Rerun job whether the job is complete or not"). Doc("Rerun job whether the job is complete or not").
Deprecate(). Deprecate().
Param(webservice.PathParameter("job", "job name")). Param(webservice.PathParameter("job", "job name")).
......
/*
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 install
import (
"github.com/emicklei/go-restful"
urlruntime "k8s.io/apimachinery/pkg/util/runtime"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/kapis/resources/v1alpha2"
)
func init() {
Install(runtime.Container)
}
func Install(c *restful.Container) {
urlruntime.Must(v1alpha2.AddToContainer(c))
}
package v1alpha2
import (
"fmt"
"github.com/emicklei/go-restful"
v1 "k8s.io/api/core/v1"
k8serr "k8s.io/apimachinery/pkg/api/errors"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/components"
"kubesphere.io/kubesphere/pkg/models/git"
"kubesphere.io/kubesphere/pkg/models/quotas"
"kubesphere.io/kubesphere/pkg/models/registries"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2/resource"
"kubesphere.io/kubesphere/pkg/models/revisions"
"kubesphere.io/kubesphere/pkg/models/routers"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"net/http"
"strconv"
"strings"
)
type resourceHandler struct {
resourcesGetter *resource.ResourceGetter
componentsGetter components.ComponentsGetter
resourceQuotaGetter quotas.ResourceQuotaGetter
revisionGetter revisions.RevisionGetter
routerOperator routers.RouterOperator
gitVerifier git.GitVerifier
registryGetter registries.RegistryGetter
}
func newResourceHandler(client k8s.Client) *resourceHandler {
factory := informers.NewInformerFactories(client.Kubernetes(), client.KubeSphere(), client.S2i(), client.Application())
return &resourceHandler{
resourcesGetter: resource.NewResourceGetter(factory),
componentsGetter: components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()),
resourceQuotaGetter: quotas.NewResourceQuotaGetter(factory.KubernetesSharedInformerFactory()),
revisionGetter: revisions.NewRevisionGetter(factory.KubernetesSharedInformerFactory()),
routerOperator: routers.NewRouterOperator(client.Kubernetes(), factory.KubernetesSharedInformerFactory()),
gitVerifier: git.NewGitVerifier(factory.KubernetesSharedInformerFactory()),
registryGetter: registries.NewRegistryGetter(factory.KubernetesSharedInformerFactory()),
}
}
func (r *resourceHandler) handleGetNamespacedResources(request *restful.Request, response *restful.Response) {
r.handleListNamespaceResources(request, response)
}
func (r *resourceHandler) handleListNamespaceResources(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
resourceName := request.PathParameter("resources")
conditions, err := params.ParseConditions(request.QueryParameter(params.ConditionsParam))
orderBy := params.GetStringValueWithDefault(request, params.OrderByParam, v1alpha2.CreateTime)
limit, offset := params.ParsePaging(request.QueryParameter(params.PagingParam))
reverse := params.ParseReverse(request)
if err != nil {
response.WriteHeaderAndEntity(http.StatusBadRequest, err)
return
}
result, err := r.resourcesGetter.ListResources(namespace, resourceName, conditions, orderBy, reverse, limit, offset)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetSystemHealthStatus(_ *restful.Request, response *restful.Response) {
result, err := r.componentsGetter.GetSystemHealthStatus()
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetComponentStatus(request *restful.Request, response *restful.Response) {
component := request.PathParameter("component")
result, err := r.componentsGetter.GetComponentStatus(component)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetComponents(_ *restful.Request, response *restful.Response) {
result, err := r.componentsGetter.GetAllComponentsStatus()
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetClusterQuotas(_ *restful.Request, response *restful.Response) {
result, err := r.resourceQuotaGetter.GetClusterQuota()
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetNamespaceQuotas(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
quota, err := r.resourceQuotaGetter.GetNamespaceQuota(namespace)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(quota)
}
func (r *resourceHandler) handleGetDaemonSetRevision(request *restful.Request, response *restful.Response) {
daemonset := request.PathParameter("daemonset")
namespace := request.PathParameter("namespace")
revision, err := strconv.Atoi(request.PathParameter("revision"))
if err != nil {
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := r.revisionGetter.GetDaemonSetRevision(namespace, daemonset, revision)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetDeploymentRevision(request *restful.Request, response *restful.Response) {
deploy := request.PathParameter("deployment")
namespace := request.PathParameter("namespace")
revision := request.PathParameter("revision")
result, err := r.revisionGetter.GetDeploymentRevision(namespace, deploy, revision)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
return
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetStatefulSetRevision(request *restful.Request, response *restful.Response) {
statefulset := request.PathParameter("statefulset")
namespace := request.PathParameter("namespace")
revision, err := strconv.Atoi(request.PathParameter("revision"))
if err != nil {
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
result, err := r.revisionGetter.GetStatefulSetRevision(namespace, statefulset, revision)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(result)
}
// Get ingress controller service for specified namespace
func (r *resourceHandler) handleGetRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
router, err := r.routerOperator.GetRouter(namespace)
if err != nil {
if k8serr.IsNotFound(err) {
response.WriteHeaderAndEntity(http.StatusNotFound, errors.Wrap(err))
} else {
api.HandleInternalError(response, err)
}
return
}
response.WriteAsJson(router)
}
// Create ingress controller and related services
func (r *resourceHandler) handleCreateRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
newRouter := api.Router{}
err := request.ReadEntity(&newRouter)
if err != nil {
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(fmt.Errorf("wrong annotations, missing key or value")))
return
}
routerType := v1.ServiceTypeNodePort
if strings.Compare(strings.ToLower(newRouter.RouterType), "loadbalancer") == 0 {
routerType = v1.ServiceTypeLoadBalancer
}
router, err := r.routerOperator.CreateRouter(namespace, routerType, newRouter.Annotations)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(router)
}
// Delete ingress controller and services
func (r *resourceHandler) handleDeleteRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
router, err := r.routerOperator.DeleteRouter(namespace)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(router)
}
func (r *resourceHandler) handleUpdateRouter(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
newRouter := api.Router{}
err := request.ReadEntity(&newRouter)
if err != nil {
response.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
return
}
var routerType = v1.ServiceTypeNodePort
if strings.Compare(strings.ToLower(newRouter.RouterType), "loadbalancer") == 0 {
routerType = v1.ServiceTypeLoadBalancer
}
router, err := r.routerOperator.UpdateRouter(namespace, routerType, newRouter.Annotations)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteAsJson(router)
}
func (r *resourceHandler) handleVerifyGitCredential(request *restful.Request, response *restful.Response) {
var credential api.GitCredential
err := request.ReadEntity(&credential)
if err != nil {
api.HandleBadRequest(response, err)
return
}
err = r.gitVerifier.VerifyGitCredential(credential.RemoteUrl, credential.SecretRef.Namespace, credential.SecretRef.Name)
if err != nil {
api.HandleBadRequest(response, err)
return
}
response.WriteHeader(http.StatusOK)
}
func (r *resourceHandler) handleVerifyRegistryCredential(request *restful.Request, response *restful.Response) {
var credential api.RegistryCredential
err := request.ReadEntity(&credential)
if err != nil {
api.HandleBadRequest(response, err)
return
}
err = r.registryGetter.VerifyRegistryCredential(credential)
if err != nil {
api.HandleBadRequest(response, err)
return
}
response.WriteHeader(http.StatusOK)
}
func (r *resourceHandler) handleGetRegistryEntry(request *restful.Request, response *restful.Response) {
imageName := request.QueryParameter("image")
namespace := request.QueryParameter("namespace")
secretName := request.QueryParameter("secret")
detail, err := r.registryGetter.GetEntry(namespace, secretName, imageName)
if err != nil {
api.HandleBadRequest(response, err)
return
}
response.WriteAsJson(detail)
}
func (r *resourceHandler) handleGetNamespacedAbnormalWorkloads(request *restful.Request, response *restful.Response) {
namespace := request.PathParameter("namespace")
result := api.Workloads{
Namespace: namespace,
Count: make(map[string]int),
}
for _, workloadType := range []string{api.ResourceKindDeployment, api.ResourceKindStatefulSet, api.ResourceKindDaemonSet, api.ResourceKindJob, api.ResourceKindPersistentVolumeClaim} {
var notReadyStatus string
switch workloadType {
case api.ResourceKindPersistentVolumeClaim:
notReadyStatus = strings.Join([]string{v1alpha2.StatusPending, v1alpha2.StatusLost}, "|")
case api.ResourceKindJob:
notReadyStatus = v1alpha2.StatusFailed
default:
notReadyStatus = v1alpha2.StatusUpdating
}
res, err := r.resourcesGetter.ListResources(namespace, workloadType, &params.Conditions{Match: map[string]string{v1alpha2.Status: notReadyStatus}}, "", false, -1, 0)
if err != nil {
api.HandleInternalError(response, err)
}
result.Count[workloadType] = len(res.Items)
}
response.WriteAsJson(result)
}
func (r *resourceHandler) handleGetAbnormalWorkloads(request *restful.Request, response *restful.Response) {
r.handleGetNamespacedAbnormalWorkloads(request, response)
}
...@@ -23,43 +23,32 @@ import ( ...@@ -23,43 +23,32 @@ import (
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/apiserver/components" "kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/git" "kubesphere.io/kubesphere/pkg/api/resource/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/operations"
"kubesphere.io/kubesphere/pkg/apiserver/quotas"
"kubesphere.io/kubesphere/pkg/apiserver/registries"
"kubesphere.io/kubesphere/pkg/apiserver/resources" "kubesphere.io/kubesphere/pkg/apiserver/resources"
"kubesphere.io/kubesphere/pkg/apiserver/revisions"
"kubesphere.io/kubesphere/pkg/apiserver/routers"
"kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/apiserver/workloadstatuses"
"kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/models"
gitmodel "kubesphere.io/kubesphere/pkg/models/git" gitmodel "kubesphere.io/kubesphere/pkg/models/git"
registriesmodel "kubesphere.io/kubesphere/pkg/models/registries" registriesmodel "kubesphere.io/kubesphere/pkg/models/registries"
"kubesphere.io/kubesphere/pkg/models/status"
"kubesphere.io/kubesphere/pkg/server/errors" "kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/server/params" "kubesphere.io/kubesphere/pkg/server/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"net/http" "net/http"
) )
const GroupName = "resources.kubesphere.io" const (
GroupName = "resources.kubesphere.io"
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
var (
WebServiceBuilder = runtime.NewContainerBuilder(addWebService)
AddToContainer = WebServiceBuilder.AddToContainer
) )
func addWebService(c *restful.Container) error { var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
func AddToContainer(c *restful.Container, client k8s.Client) error {
webservice := runtime.NewWebService(GroupVersion) webservice := runtime.NewWebService(GroupVersion)
handler := newResourceHandler(client)
ok := "ok"
webservice.Route(webservice.GET("/namespaces/{namespace}/{resources}"). webservice.Route(webservice.GET("/namespaces/{namespace}/{resources}").
To(resources.ListNamespacedResources). To(handler.handleListNamespaceResources).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Doc("Namespace level resource query"). Doc("Namespace level resource query").
Param(webservice.PathParameter("namespace", "the name of the project")). Param(webservice.PathParameter("namespace", "the name of the project")).
...@@ -73,21 +62,11 @@ func addWebService(c *restful.Container) error { ...@@ -73,21 +62,11 @@ func addWebService(c *restful.Container) error {
DefaultValue("limit=10,page=1")). DefaultValue("limit=10,page=1")).
Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")).
Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")). Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")).
Returns(http.StatusOK, ok, models.PageableResponse{})) Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}))
webservice.Route(webservice.POST("/namespaces/{namespace}/jobs/{job}").
To(operations.RerunJob).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Doc("Rerun job whether the job is complete or not").
Param(webservice.PathParameter("job", "job name")).
Param(webservice.PathParameter("namespace", "the name of the namespace where the job runs in")).
Param(webservice.QueryParameter("action", "action must be \"rerun\"")).
Param(webservice.QueryParameter("resourceVersion", "version of job, rerun when the version matches")).
Returns(http.StatusOK, ok, errors.Error{}))
webservice.Route(webservice.GET("/{resources}"). webservice.Route(webservice.GET("/{resources}").
To(resources.ListResources). To(handler.handleListNamespaceResources).
Returns(http.StatusOK, ok, models.PageableResponse{}). Returns(http.StatusOK, api.StatusOK, models.PageableResponse{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}).
Doc("Cluster level resource query"). Doc("Cluster level resource query").
Param(webservice.PathParameter("resources", "cluster level resource type, e.g. nodes,workspaces,storageclasses,clusterroles.")). Param(webservice.PathParameter("resources", "cluster level resource type, e.g. nodes,workspaces,storageclasses,clusterroles.")).
...@@ -102,67 +81,60 @@ func addWebService(c *restful.Container) error { ...@@ -102,67 +81,60 @@ func addWebService(c *restful.Container) error {
Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")). Param(webservice.QueryParameter(params.ReverseParam, "sort parameters, e.g. reverse=true")).
Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime"))) Param(webservice.QueryParameter(params.OrderByParam, "sort parameters, e.g. orderBy=createTime")))
webservice.Route(webservice.POST("/nodes/{node}/drainage").
To(operations.DrainNode).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}).
Doc("remove a node from service, safely evict all of your pods from a node and you can power down the node. More info: https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/").
Param(webservice.PathParameter("node", "node name")).
Returns(http.StatusOK, ok, errors.Error{}))
webservice.Route(webservice.GET("/users/{user}/kubectl"). webservice.Route(webservice.GET("/users/{user}/kubectl").
To(resources.GetKubectl). To(resources.GetKubectl).
Doc("get user's kubectl pod"). Doc("get user's kubectl pod").
Param(webservice.PathParameter("user", "username")). Param(webservice.PathParameter("user", "username")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourcesTag}).
Returns(http.StatusOK, ok, models.PodInfo{})) Returns(http.StatusOK, api.StatusOK, models.PodInfo{}))
webservice.Route(webservice.GET("/users/{user}/kubeconfig"). webservice.Route(webservice.GET("/users/{user}/kubeconfig").
Produces("text/plain", restful.MIME_JSON). Produces("text/plain", restful.MIME_JSON).
To(resources.GetKubeconfig). To(resources.GetKubeconfig).
Doc("get users' kubeconfig"). Doc("get users' kubeconfig").
Param(webservice.PathParameter("user", "username")). Param(webservice.PathParameter("user", "username")).
Returns(http.StatusOK, ok, ""). Returns(http.StatusOK, api.StatusOK, "").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourcesTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.UserResourcesTag}))
webservice.Route(webservice.GET("/components"). webservice.Route(webservice.GET("/components").
To(components.GetComponents). To(handler.handleGetComponents).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ComponentStatusTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.ComponentStatusTag}).
Doc("List the system components."). Doc("List the system components.").
Returns(http.StatusOK, ok, []models.ComponentStatus{})) Returns(http.StatusOK, api.StatusOK, []v1alpha2.ComponentStatus{}))
webservice.Route(webservice.GET("/components/{component}"). webservice.Route(webservice.GET("/components/{component}").
To(components.GetComponentStatus). To(handler.handleGetComponentStatus).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ComponentStatusTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.ComponentStatusTag}).
Doc("Describe the specified system component."). Doc("Describe the specified system component.").
Param(webservice.PathParameter("component", "component name")). Param(webservice.PathParameter("component", "component name")).
Returns(http.StatusOK, ok, models.ComponentStatus{})) Returns(http.StatusOK, api.StatusOK, v1alpha2.ComponentStatus{}))
webservice.Route(webservice.GET("/componenthealth"). webservice.Route(webservice.GET("/componenthealth").
To(components.GetSystemHealthStatus). To(handler.handleGetSystemHealthStatus).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ComponentStatusTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.ComponentStatusTag}).
Doc("Get the health status of system components."). Doc("Get the health status of system components.").
Returns(http.StatusOK, ok, models.HealthStatus{})) Returns(http.StatusOK, api.StatusOK, v1alpha2.HealthStatus{}))
webservice.Route(webservice.GET("/quotas"). webservice.Route(webservice.GET("/quotas").
To(quotas.GetClusterQuotas). To(handler.handleGetClusterQuotas).
Doc("get whole cluster's resource usage"). Doc("get whole cluster's resource usage").
Returns(http.StatusOK, ok, models.ResourceQuota{}). Returns(http.StatusOK, api.StatusOK, api.ResourceQuota{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag})) Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}))
webservice.Route(webservice.GET("/namespaces/{namespace}/quotas"). webservice.Route(webservice.GET("/namespaces/{namespace}/quotas").
Doc("get specified namespace's resource quota and usage"). Doc("get specified namespace's resource quota and usage").
Param(webservice.PathParameter("namespace", "the name of the project")). Param(webservice.PathParameter("namespace", "the name of the project")).
Returns(http.StatusOK, ok, models.ResourceQuota{}). Returns(http.StatusOK, api.StatusOK, api.ResourceQuota{}).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
To(quotas.GetNamespaceQuotas)) To(handler.handleGetNamespaceQuotas))
webservice.Route(webservice.POST("registry/verify"). webservice.Route(webservice.POST("registry/verify").
To(registries.RegistryVerify). To(handler.handleVerifyRegistryCredential).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.VerificationTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.VerificationTag}).
Doc("verify if a user has access to the docker registry"). Doc("verify if a user has access to the docker registry").
Reads(registriesmodel.AuthInfo{}). Reads(api.RegistryCredential{}).
Returns(http.StatusOK, ok, errors.Error{})) Returns(http.StatusOK, api.StatusOK, errors.Error{}))
webservice.Route(webservice.GET("/registry/blob"). webservice.Route(webservice.GET("/registry/blob").
To(registries.RegistryImageBlob). To(handler.handleGetRegistryEntry).
Param(webservice.QueryParameter("image", "query image, condition for filtering."). Param(webservice.QueryParameter("image", "query image, condition for filtering.").
Required(true). Required(true).
DataFormat("image=%s")). DataFormat("image=%s")).
...@@ -175,87 +147,80 @@ func addWebService(c *restful.Container) error { ...@@ -175,87 +147,80 @@ func addWebService(c *restful.Container) error {
Metadata(restfulspec.KeyOpenAPITags, []string{constants.RegistryTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.RegistryTag}).
Doc("Retrieve the blob from the registry identified"). Doc("Retrieve the blob from the registry identified").
Writes(registriesmodel.ImageDetails{}). Writes(registriesmodel.ImageDetails{}).
Returns(http.StatusOK, ok, registriesmodel.ImageDetails{}), Returns(http.StatusOK, api.StatusOK, registriesmodel.ImageDetails{}),
) )
webservice.Route(webservice.POST("git/verify"). webservice.Route(webservice.POST("git/verify").
To(git.GitReadVerify). To(handler.handleVerifyGitCredential).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.VerificationTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.VerificationTag}).
Doc("Verify if the kubernetes secret has read access to the git repository"). Doc("Verify if the kubernetes secret has read access to the git repository").
Reads(gitmodel.AuthInfo{}). Reads(gitmodel.AuthInfo{}).
Returns(http.StatusOK, ok, errors.Error{}), Returns(http.StatusOK, api.StatusOK, errors.Error{}),
) )
webservice.Route(webservice.GET("/namespaces/{namespace}/daemonsets/{daemonset}/revisions/{revision}"). webservice.Route(webservice.GET("/namespaces/{namespace}/daemonsets/{daemonset}/revisions/{revision}").
To(revisions.GetDaemonSetRevision). To(handler.handleGetDaemonSetRevision).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Doc("Get the specified daemonset revision"). Doc("Get the specified daemonset revision").
Param(webservice.PathParameter("daemonset", "the name of the daemonset")). Param(webservice.PathParameter("daemonset", "the name of the daemonset")).
Param(webservice.PathParameter("namespace", "the namespace of the daemonset")). Param(webservice.PathParameter("namespace", "the namespace of the daemonset")).
Param(webservice.PathParameter("revision", "the revision of the daemonset")). Param(webservice.PathParameter("revision", "the revision of the daemonset")).
Returns(http.StatusOK, ok, appsv1.DaemonSet{})) Returns(http.StatusOK, api.StatusOK, appsv1.DaemonSet{}))
webservice.Route(webservice.GET("/namespaces/{namespace}/deployments/{deployment}/revisions/{revision}"). webservice.Route(webservice.GET("/namespaces/{namespace}/deployments/{deployment}/revisions/{revision}").
To(revisions.GetDeployRevision). To(handler.handleGetDeploymentRevision).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Doc("Get the specified deployment revision"). Doc("Get the specified deployment revision").
Param(webservice.PathParameter("deployment", "the name of deployment")). Param(webservice.PathParameter("deployment", "the name of deployment")).
Param(webservice.PathParameter("namespace", "the namespace of the deployment")). Param(webservice.PathParameter("namespace", "the namespace of the deployment")).
Param(webservice.PathParameter("revision", "the revision of the deployment")). Param(webservice.PathParameter("revision", "the revision of the deployment")).
Returns(http.StatusOK, ok, appsv1.ReplicaSet{})) Returns(http.StatusOK, api.StatusOK, appsv1.ReplicaSet{}))
webservice.Route(webservice.GET("/namespaces/{namespace}/statefulsets/{statefulset}/revisions/{revision}"). webservice.Route(webservice.GET("/namespaces/{namespace}/statefulsets/{statefulset}/revisions/{revision}").
To(revisions.GetStatefulSetRevision). To(handler.handleGetStatefulSetRevision).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Doc("Get the specified statefulset revision"). Doc("Get the specified statefulset revision").
Param(webservice.PathParameter("statefulset", "the name of the statefulset")). Param(webservice.PathParameter("statefulset", "the name of the statefulset")).
Param(webservice.PathParameter("namespace", "the namespace of the statefulset")). Param(webservice.PathParameter("namespace", "the namespace of the statefulset")).
Param(webservice.PathParameter("revision", "the revision of the statefulset")). Param(webservice.PathParameter("revision", "the revision of the statefulset")).
Returns(http.StatusOK, ok, appsv1.StatefulSet{})) Returns(http.StatusOK, api.StatusOK, appsv1.StatefulSet{}))
webservice.Route(webservice.GET("/routers").
To(routers.GetAllRouters).
Doc("List all routers of all projects").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}).
Returns(http.StatusOK, ok, corev1.ServiceList{}))
webservice.Route(webservice.GET("/namespaces/{namespace}/router"). webservice.Route(webservice.GET("/namespaces/{namespace}/router").
To(routers.GetRouter). To(handler.handleGetRouter).
Doc("List router of a specified project"). Doc("List router of a specified project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Returns(http.StatusOK, ok, corev1.Service{}). Returns(http.StatusOK, api.StatusOK, corev1.Service{}).
Param(webservice.PathParameter("namespace", "the name of the project"))) Param(webservice.PathParameter("namespace", "the name of the project")))
webservice.Route(webservice.DELETE("/namespaces/{namespace}/router"). webservice.Route(webservice.DELETE("/namespaces/{namespace}/router").
To(routers.DeleteRouter). To(handler.handleDeleteRouter).
Doc("List router of a specified project"). Doc("List router of a specified project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Returns(http.StatusOK, ok, corev1.Service{}). Returns(http.StatusOK, api.StatusOK, corev1.Service{}).
Param(webservice.PathParameter("namespace", "the name of the project"))) Param(webservice.PathParameter("namespace", "the name of the project")))
webservice.Route(webservice.POST("/namespaces/{namespace}/router"). webservice.Route(webservice.POST("/namespaces/{namespace}/router").
To(routers.CreateRouter). To(handler.handleCreateRouter).
Doc("Create a router for a specified project"). Doc("Create a router for a specified project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Returns(http.StatusOK, ok, corev1.Service{}). Returns(http.StatusOK, api.StatusOK, corev1.Service{}).
Param(webservice.PathParameter("namespace", "the name of the project"))) Param(webservice.PathParameter("namespace", "the name of the project")))
webservice.Route(webservice.PUT("/namespaces/{namespace}/router"). webservice.Route(webservice.PUT("/namespaces/{namespace}/router").
To(routers.UpdateRouter). To(handler.handleUpdateRouter).
Doc("Update a router for a specified project"). Doc("Update a router for a specified project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Returns(http.StatusOK, ok, corev1.Service{}). Returns(http.StatusOK, api.StatusOK, corev1.Service{}).
Param(webservice.PathParameter("namespace", "the name of the project"))) Param(webservice.PathParameter("namespace", "the name of the project")))
webservice.Route(webservice.GET("/abnormalworkloads"). webservice.Route(webservice.GET("/abnormalworkloads").
Doc("get abnormal workloads' count of whole cluster"). Doc("get abnormal workloads' count of whole cluster").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.ClusterResourcesTag}).
Returns(http.StatusOK, ok, status.WorkLoadStatus{}). Returns(http.StatusOK, api.StatusOK, api.Workloads{}).
To(workloadstatuses.GetClusterAbnormalWorkloads)) To(handler.handleGetAbnormalWorkloads))
webservice.Route(webservice.GET("/namespaces/{namespace}/abnormalworkloads"). webservice.Route(webservice.GET("/namespaces/{namespace}/abnormalworkloads").
Doc("get abnormal workloads' count of specified namespace"). Doc("get abnormal workloads' count of specified namespace").
Param(webservice.PathParameter("namespace", "the name of the project")). Param(webservice.PathParameter("namespace", "the name of the project")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}). Metadata(restfulspec.KeyOpenAPITags, []string{constants.NamespaceResourcesTag}).
Returns(http.StatusOK, ok, status.WorkLoadStatus{}). Returns(http.StatusOK, api.StatusOK, api.Workloads{}).
To(workloadstatuses.GetNamespacedAbnormalWorkloads)) To(handler.handleGetNamespacedAbnormalWorkloads))
c.Add(webservice) c.Add(webservice)
......
package v1alpha3
import (
"github.com/emicklei/go-restful"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/models/components"
"kubesphere.io/kubesphere/pkg/models/resources/v1alpha3/resource"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"net/http"
)
type Handler struct {
namespacedResourceGetter *resource.NamespacedResourceGetter
componentsGetter components.ComponentsGetter
}
func New(client k8s.Client) *Handler {
factory := informers.NewInformerFactories(client.Kubernetes(), nil, nil, nil)
return &Handler{
namespacedResourceGetter: resource.New(factory.KubernetesSharedInformerFactory()),
componentsGetter: components.NewComponentsGetter(factory.KubernetesSharedInformerFactory()),
}
}
func (h Handler) handleGetNamespacedResource(request *restful.Request, response *restful.Response) {
resource := request.PathParameter("resources")
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := h.namespacedResourceGetter.Get(resource, namespace, name)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
// handleListNamedResource retrieves namespaced scope resources
func (h Handler) handleListNamespacedResource(request *restful.Request, response *restful.Response) {
query := query.ParseQueryParameter(request)
resource := request.PathParameter("resources")
namespace := request.PathParameter("namespace")
result, err := h.namespacedResourceGetter.List(resource, namespace, query)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (h Handler) handleGetComponentStatus(request *restful.Request, response *restful.Response) {
component := request.PathParameter("component")
result, err := h.componentsGetter.GetComponentStatus(component)
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (h Handler) handleGetSystemHealthStatus(request *restful.Request, response *restful.Response) {
result, err := h.componentsGetter.GetSystemHealthStatus()
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
// get all componentsHandler
func (h Handler) handleGetComponents(request *restful.Request, response *restful.Response) {
result, err := h.componentsGetter.GetAllComponentsStatus()
if err != nil {
api.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
package v1alpha3
import "testing"
func TestComponentHandler(t *testing.T) {
}
/*
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 v1alpha3
import (
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful-openapi"
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/api"
"kubesphere.io/kubesphere/pkg/api/resource/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/query"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"net/http"
)
const (
GroupName = "resources.kubesphere.io"
tagComponentStatus = "Component Status"
tagNamespacedResource = "Namespaced Resource"
ok = "OK"
)
var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"}
func AddWebService(c *restful.Container, client k8s.Client) error {
webservice := runtime.NewWebService(GroupVersion)
handler := New(client)
webservice.Route(webservice.GET("/namespaces/{namespace}/{resources}").
To(handler.handleGetNamespacedResource).
Metadata(restfulspec.KeyOpenAPITags, []string{tagNamespacedResource}).
Doc("Namespace level resource query").
Param(webservice.PathParameter("namespace", "the name of the project")).
Param(webservice.PathParameter("resources", "namespace level resource type, e.g. pods,jobs,configmaps,services.")).
Param(webservice.QueryParameter(query.ParameterName, "name used to do filtering").Required(false)).
Param(webservice.QueryParameter(query.ParameterPage, "page").Required(false).DataFormat("page=%d").DefaultValue("page=0")).
Param(webservice.QueryParameter(query.ParameterLimit, "limit").Required(false)).
Param(webservice.QueryParameter(query.ParameterAscending, "sort parameters, e.g. reverse=true").Required(false).DefaultValue("ascending=false")).
Param(webservice.QueryParameter(query.ParameterOrderBy, "sort parameters, e.g. orderBy=createTime")).
Returns(http.StatusOK, ok, api.ListResult{}))
webservice.Route(webservice.GET("/components").
To(handler.handleGetComponents).
Metadata(restfulspec.KeyOpenAPITags, []string{tagComponentStatus}).
Doc("List the system components.").
Returns(http.StatusOK, ok, []v1alpha2.ComponentStatus{}))
webservice.Route(webservice.GET("/components/{component}").
To(handler.handleGetComponentStatus).
Metadata(restfulspec.KeyOpenAPITags, []string{tagComponentStatus}).
Doc("Describe the specified system component.").
Param(webservice.PathParameter("component", "component name")).
Returns(http.StatusOK, ok, v1alpha2.ComponentStatus{}))
webservice.Route(webservice.GET("/componenthealth").
To(handler.handleGetSystemHealthStatus).
Metadata(restfulspec.KeyOpenAPITags, []string{tagComponentStatus}).
Doc("Get the health status of system components.").
Returns(http.StatusOK, ok, v1alpha2.HealthStatus{}))
c.Add(webservice)
return nil
}
此差异已折叠。
此差异已折叠。
...@@ -42,6 +42,12 @@ const ( ...@@ -42,6 +42,12 @@ const (
cronJobLayout = "Monday, January 2, 2006 15:04:05 PM" cronJobLayout = "Monday, January 2, 2006 15:04:05 PM"
) )
type DevopsOperator interface {
}
type devopsOperator struct {
}
func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) { func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) {
devops, err := cs.ClientSets().Devops() devops, err := cs.ClientSets().Devops()
if err != nil { if err != nil {
......
...@@ -7,7 +7,7 @@ import ( ...@@ -7,7 +7,7 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/transport/http" "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
"gopkg.in/src-d/go-git.v4/storage/memory" "gopkg.in/src-d/go-git.v4/storage/memory"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"kubesphere.io/kubesphere/pkg/informers" "k8s.io/client-go/informers"
) )
type AuthInfo struct { type AuthInfo struct {
...@@ -15,12 +15,23 @@ type AuthInfo struct { ...@@ -15,12 +15,23 @@ type AuthInfo struct {
SecretRef *corev1.SecretReference `json:"secretRef,omitempty" description:"auth secret reference"` SecretRef *corev1.SecretReference `json:"secretRef,omitempty" description:"auth secret reference"`
} }
func GitReadVerify(namespace string, authInfo AuthInfo) error { type GitVerifier interface {
username := "" VerifyGitCredential(remoteUrl, namespace, secretName string) error
password := "" }
if authInfo.SecretRef != nil {
secret, err := informers.SharedInformerFactory().Core().V1().Secrets().Lister(). type gitVerifier struct {
Secrets(authInfo.SecretRef.Namespace).Get(authInfo.SecretRef.Name) informers informers.SharedInformerFactory
}
func NewGitVerifier(informers informers.SharedInformerFactory) GitVerifier {
return &gitVerifier{informers: informers}
}
func (c *gitVerifier) VerifyGitCredential(remoteUrl, namespace, secretName string) error {
var username, password string
if len(secretName) > 0 {
secret, err := c.informers.Core().V1().Secrets().Lister().Secrets(namespace).Get(secretName)
if err != nil { if err != nil {
return err return err
} }
...@@ -36,10 +47,10 @@ func GitReadVerify(namespace string, authInfo AuthInfo) error { ...@@ -36,10 +47,10 @@ func GitReadVerify(namespace string, authInfo AuthInfo) error {
password = string(passwordBytes) password = string(passwordBytes)
} }
return gitReadVerifyWithBasicAuth(string(username), string(password), authInfo.RemoteUrl) return c.gitReadVerifyWithBasicAuth(username, password, remoteUrl)
} }
func gitReadVerifyWithBasicAuth(username string, password string, remote string) error { func (c *gitVerifier) gitReadVerifyWithBasicAuth(username string, password string, remote string) error {
r, _ := git.Init(memory.NewStorage(), nil) r, _ := git.Init(memory.NewStorage(), nil)
// Add a new remote, with the default fetch refspec // Add a new remote, with the default fetch refspec
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -28,7 +28,6 @@ import ( ...@@ -28,7 +28,6 @@ import (
"k8s.io/klog" "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api/logging/v1alpha2" "kubesphere.io/kubesphere/pkg/api/logging/v1alpha2"
"kubesphere.io/kubesphere/pkg/informers" "kubesphere.io/kubesphere/pkg/informers"
fb "kubesphere.io/kubesphere/pkg/simple/client/fluentbit"
"net/http" "net/http"
"strings" "strings"
"time" "time"
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册