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
316 lines
7.8 KiB
Go
316 lines
7.8 KiB
Go
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
|
|
}
|
|
}
|