This is a huge commit, it does following things:

1. refactor kubesphere dependency service client creation, we can
disable dependency by config
2. dependencies can be configured by configuration file
3. refactor cmd package using cobra.Command, so we can use hypersphere
to invoke command sepearately. Later we only need to build one image to
contains all kubesphere core components. One command to rule them all!
4. live reloading configuration currently not implemented
This commit is contained in:
Jeff
2019-09-03 15:20:22 +08:00
parent 52a1c2e619
commit 96d2ac4112
233 changed files with 26414 additions and 1927 deletions

View File

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