use go 1.12

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2019-03-12 15:47:56 +08:00
parent b59c244ca2
commit 4144404b0b
1110 changed files with 161100 additions and 14519 deletions

View File

@@ -0,0 +1,91 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package k8s
import (
"flag"
"fmt"
"log"
"os"
"sync"
"k8s.io/client-go/tools/clientcmd"
"github.com/mitchellh/go-homedir"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
var (
kubeConfigFile string
k8sClient *kubernetes.Clientset
k8sClientOnce sync.Once
KubeConfig *rest.Config
)
func init() {
flag.StringVar(&kubeConfigFile, "kubeconfig", fmt.Sprintf("%s/.kube/config", os.Getenv("HOME")), "path to kubeconfig file")
}
func Client() *kubernetes.Clientset {
k8sClientOnce.Do(func() {
config, err := Config()
if err != nil {
log.Fatalln(err)
}
k8sClient = kubernetes.NewForConfigOrDie(config)
KubeConfig = config
})
return k8sClient
}
func Config() (kubeConfig *rest.Config, err error) {
if kubeConfigFile == "" {
if env := os.Getenv("KUBECONFIG"); env != "" {
kubeConfigFile = env
} else {
if home, err := homedir.Dir(); err == nil {
kubeConfigFile = fmt.Sprintf("%s/.kube/config", home)
}
}
}
if _, err = os.Stat(kubeConfigFile); err == nil {
kubeConfig, err = clientcmd.BuildConfigFromFlags("", kubeConfigFile)
} else {
kubeConfig, err = rest.InClusterConfig()
}
if err != nil {
return nil, err
}
kubeConfig.QPS = 1e6
kubeConfig.Burst = 1e6
return kubeConfig, nil
}

View File

@@ -0,0 +1,171 @@
package ldap
import (
"errors"
"log"
"sync"
"github.com/go-ldap/ldap"
)
// channelPool implements the Pool interface based on buffered channels.
type channelPool struct {
// storage for our net.Conn connections
mu sync.Mutex
conns chan ldap.Client
name string
aliveChecks bool
// net.Conn generator
factory PoolFactory
closeAt []uint16
}
// PoolFactory is a function to create new connections.
type PoolFactory func(string) (ldap.Client, error)
// NewChannelPool returns a new pool based on buffered channels with an initial
// capacity and maximum capacity. Factory is used when initial capacity is
// greater than zero to fill the pool. A zero initialCap doesn't fill the Pool
// until a new Get() is called. During a Get(), If there is no new connection
// available in the pool, a new connection will be created via the Factory()
// method.
//
// closeAt will automagically mark the connection as unusable if the return code
// of the call is one of those passed, most likely you want to set this to something
// like
// []uint8{ldap.LDAPResultTimeLimitExceeded, ldap.ErrorNetwork}
func NewChannelPool(initialCap, maxCap int, name string, factory PoolFactory, closeAt []uint16) (Pool, error) {
if initialCap < 0 || maxCap <= 0 || initialCap > maxCap {
return nil, errors.New("invalid capacity settings")
}
c := &channelPool{
conns: make(chan ldap.Client, maxCap),
name: name,
factory: factory,
closeAt: closeAt,
aliveChecks: true,
}
// create initial connections, if something goes wrong,
// just close the pool error out.
for i := 0; i < initialCap; i++ {
conn, err := factory(c.name)
if err != nil {
c.Close()
return nil, errors.New("factory is not able to fill the pool: " + err.Error())
}
c.conns <- conn
}
return c, nil
}
func (c *channelPool) AliveChecks(on bool) {
c.mu.Lock()
c.aliveChecks = on
c.mu.Unlock()
}
func (c *channelPool) getConns() chan ldap.Client {
c.mu.Lock()
conns := c.conns
c.mu.Unlock()
return conns
}
// Get implements the Pool interfaces Get() method. If there is no new
// connection available in the pool, a new connection will be created via the
// Factory() method.
func (c *channelPool) Get() (*PoolConn, error) {
conns := c.getConns()
if conns == nil {
return nil, ErrClosed
}
// wrap our connections with our ldap.Client implementation (wrapConn
// method) that puts the connection back to the pool if it's closed.
select {
case conn := <-conns:
if conn == nil {
return nil, ErrClosed
}
if !c.aliveChecks || isAlive(conn) {
return c.wrapConn(conn, c.closeAt), nil
}
conn.Close()
return c.NewConn()
default:
return c.NewConn()
}
}
func isAlive(conn ldap.Client) bool {
_, err := conn.Search(&ldap.SearchRequest{BaseDN: "", Scope: ldap.ScopeBaseObject, Filter: "(&)", Attributes: []string{"1.1"}})
return err == nil
}
func (c *channelPool) NewConn() (*PoolConn, error) {
conn, err := c.factory(c.name)
if err != nil {
return nil, err
}
return c.wrapConn(conn, c.closeAt), nil
}
// put puts the connection back to the pool. If the pool is full or closed,
// conn is simply closed. A nil conn will be rejected.
func (c *channelPool) put(conn ldap.Client) {
if conn == nil {
log.Printf("connection is nil. rejecting")
return
}
c.mu.Lock()
defer c.mu.Unlock()
if c.conns == nil {
// pool is closed, close passed connection
conn.Close()
return
}
// put the resource back into the pool. If the pool is full, this will
// block and the default case will be executed.
select {
case c.conns <- conn:
return
default:
// pool is full, close passed connection
conn.Close()
return
}
}
func (c *channelPool) Close() {
c.mu.Lock()
conns := c.conns
c.conns = nil
c.factory = nil
c.mu.Unlock()
if conns == nil {
return
}
close(conns)
for conn := range conns {
conn.Close()
}
return
}
func (c *channelPool) Len() int { return len(c.getConns()) }
func (c *channelPool) wrapConn(conn ldap.Client, closeAt []uint16) *PoolConn {
p := &PoolConn{c: c, closeAt: closeAt}
p.Conn = conn
return p
}

View File

@@ -0,0 +1,96 @@
package ldap
import (
"crypto/tls"
"log"
"time"
"github.com/go-ldap/ldap"
)
// PoolConn implements Client to override the Close() method
type PoolConn struct {
Conn ldap.Client
c *channelPool
unusable bool
closeAt []uint16
}
func (p *PoolConn) Start() {
p.Conn.Start()
}
func (p *PoolConn) StartTLS(config *tls.Config) error {
// FIXME - check if already TLS and then ignore?
return p.Conn.StartTLS(config)
}
// Close() puts the given connects back to the pool instead of closing it.
func (p *PoolConn) Close() {
if p.unusable {
log.Printf("Closing unusable connection")
if p.Conn != nil {
p.Conn.Close()
}
return
}
p.c.put(p.Conn)
}
func (p *PoolConn) SimpleBind(simpleBindRequest *ldap.SimpleBindRequest) (*ldap.SimpleBindResult, error) {
return p.Conn.SimpleBind(simpleBindRequest)
}
func (p *PoolConn) Bind(username, password string) error {
return p.Conn.Bind(username, password)
}
func (p *PoolConn) ModifyDN(modifyDNRequest *ldap.ModifyDNRequest) error {
return p.Conn.ModifyDN(modifyDNRequest)
}
// MarkUnusable() marks the connection not usable any more, to let the pool close it
// instead of returning it to pool.
func (p *PoolConn) MarkUnusable() {
p.unusable = true
}
func (p *PoolConn) autoClose(err error) {
for _, code := range p.closeAt {
if ldap.IsErrorWithCode(err, code) {
p.MarkUnusable()
return
}
}
}
func (p *PoolConn) SetTimeout(t time.Duration) {
p.Conn.SetTimeout(t)
}
func (p *PoolConn) Add(addRequest *ldap.AddRequest) error {
return p.Conn.Add(addRequest)
}
func (p *PoolConn) Del(delRequest *ldap.DelRequest) error {
return p.Conn.Del(delRequest)
}
func (p *PoolConn) Modify(modifyRequest *ldap.ModifyRequest) error {
return p.Conn.Modify(modifyRequest)
}
func (p *PoolConn) Compare(dn, attribute, value string) (bool, error) {
return p.Conn.Compare(dn, attribute, value)
}
func (p *PoolConn) PasswordModify(passwordModifyRequest *ldap.PasswordModifyRequest) (*ldap.PasswordModifyResult, error) {
return p.Conn.PasswordModify(passwordModifyRequest)
}
func (p *PoolConn) Search(searchRequest *ldap.SearchRequest) (*ldap.SearchResult, error) {
return p.Conn.Search(searchRequest)
}
func (p *PoolConn) SearchWithPaging(searchRequest *ldap.SearchRequest, pagingSize uint32) (*ldap.SearchResult, error) {
return p.Conn.SearchWithPaging(searchRequest, pagingSize)
}

View File

@@ -0,0 +1,79 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ldap
import (
"flag"
"github.com/go-ldap/ldap"
"log"
"sync"
)
var (
once sync.Once
pool Pool
ldapHost string
ManagerDN string
ManagerPassword string
UserSearchBase string
GroupSearchBase string
)
func init() {
flag.StringVar(&ldapHost, "ldap-server", "localhost:389", "ldap server host")
flag.StringVar(&ManagerDN, "ldap-manager-dn", "cn=admin,dc=example,dc=org", "ldap manager dn")
flag.StringVar(&ManagerPassword, "ldap-manager-password", "admin", "ldap manager password")
flag.StringVar(&UserSearchBase, "ldap-user-search-base", "ou=Users,dc=example,dc=org", "ldap user search base")
flag.StringVar(&GroupSearchBase, "ldap-group-search-base", "ou=Groups,dc=example,dc=org", "ldap group search base")
}
func ldapClientPool() Pool {
once.Do(func() {
var err error
pool, err = NewChannelPool(8, 96, "kubesphere", func(s string) (ldap.Client, error) {
conn, err := ldap.Dial("tcp", ldapHost)
if err != nil {
return nil, err
}
return conn, nil
}, []uint16{ldap.LDAPResultTimeLimitExceeded, ldap.ErrorNetwork})
if err != nil {
log.Fatalln(err)
}
})
return pool
}
func Client() (ldap.Client, error) {
conn, err := ldapClientPool().Get()
if err != nil {
return nil, err
}
err = conn.Bind(ManagerDN, ManagerPassword)
if err != nil {
conn.Close()
return nil, err
}
return conn, nil
}

View File

@@ -0,0 +1,26 @@
package ldap
import (
"errors"
)
var (
// ErrClosed is the error resulting if the pool is closed via pool.Close().
ErrClosed = errors.New("pool is closed")
)
// Pool interface describes a pool implementation. A pool should have maximum
// capacity. An ideal pool is threadsafe and easy to use.
type Pool interface {
// Get returns a new connection from the pool. Closing the connections puts
// it back to the Pool. Closing it when the pool is destroyed or full will
// be counted as an error.
Get() (*PoolConn, error)
// Close closes the pool and all its connections. After Close() the pool is
// no longer usable.
Close()
// Len returns the current number of connections of the pool.
Len() int
}

View File

@@ -0,0 +1,61 @@
/*
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 mysql
import (
"flag"
"log"
"os"
"os/signal"
"sync"
"syscall"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
)
var (
dbClientOnce sync.Once
dbClient *gorm.DB
dsn string
)
func init() {
flag.StringVar(&dsn, "database-connection", "root@tcp(localhost:3306)/kubesphere?charset=utf8&parseTime=True", "data source name")
}
func Client() *gorm.DB {
dbClientOnce.Do(func() {
var err error
dbClient, err = gorm.Open("mysql", dsn)
if err != nil {
log.Fatalln(err)
}
c := make(chan os.Signal, 0)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
dbClient.Close()
}()
})
return dbClient
}

View File

@@ -0,0 +1,189 @@
/*
Copyright 2019 The KubeSphere Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package prometheus
import (
"flag"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/emicklei/go-restful"
"github.com/golang/glog"
)
const (
DefaultQueryStep = "10m"
DefaultQueryTimeout = "10s"
RangeQueryType = "query_range?"
DefaultQueryType = "query?"
)
var (
prometheusAPIEndpoint string
)
func init() {
flag.StringVar(&prometheusAPIEndpoint, "prometheus-endpoint", "http://prometheus-k8s.kubesphere-monitoring-system.svc:9090/api/v1/", "prometheus api endpoint")
}
type MonitoringRequestParams struct {
Params url.Values
QueryType string
SortMetricName string
SortType string
PageNum string
LimitNum string
Tp string
MetricsFilter string
NodesFilter string
WsFilter string
NsFilter string
PodsFilter string
ContainersFilter string
MetricsName string
WorkloadName string
WlFilter string
NodeId string
WsName string
NsName string
PodName string
ContainerName string
WorkloadKind string
}
func SendMonitoringRequest(queryType string, params string) string {
epurl := prometheusAPIEndpoint + queryType + params
response, err := http.DefaultClient.Get(epurl)
if err != nil {
glog.Error(err)
} else {
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
glog.Error(err)
}
return string(contents)
}
return ""
}
func ParseMonitoringRequestParams(request *restful.Request) *MonitoringRequestParams {
instantTime := strings.Trim(request.QueryParameter("time"), " ")
start := strings.Trim(request.QueryParameter("start"), " ")
end := strings.Trim(request.QueryParameter("end"), " ")
step := strings.Trim(request.QueryParameter("step"), " ")
timeout := strings.Trim(request.QueryParameter("timeout"), " ")
sortMetricName := strings.Trim(request.QueryParameter("sort_metric"), " ")
sortType := strings.Trim(request.QueryParameter("sort_type"), " ")
pageNum := strings.Trim(request.QueryParameter("page"), " ")
limitNum := strings.Trim(request.QueryParameter("limit"), " ")
tp := strings.Trim(request.QueryParameter("type"), " ")
metricsFilter := strings.Trim(request.QueryParameter("metrics_filter"), " ")
nodesFilter := strings.Trim(request.QueryParameter("nodes_filter"), " ")
wsFilter := strings.Trim(request.QueryParameter("workspaces_filter"), " ")
nsFilter := strings.Trim(request.QueryParameter("namespaces_filter"), " ")
wlFilter := strings.Trim(request.QueryParameter("workloads_filter"), " ")
podsFilter := strings.Trim(request.QueryParameter("pods_filter"), " ")
containersFilter := strings.Trim(request.QueryParameter("containers_filter"), " ")
metricsName := strings.Trim(request.QueryParameter("metrics_name"), " ")
workloadName := strings.Trim(request.QueryParameter("workload_name"), " ")
nodeId := strings.Trim(request.PathParameter("node"), " ")
wsName := strings.Trim(request.PathParameter("workspace"), " ")
nsName := strings.Trim(request.PathParameter("namespace"), " ")
podName := strings.Trim(request.PathParameter("pod"), " ")
containerName := strings.Trim(request.PathParameter("container"), " ")
workloadKind := strings.Trim(request.PathParameter("workload_kind"), " ")
var requestParams = MonitoringRequestParams{
SortMetricName: sortMetricName,
SortType: sortType,
PageNum: pageNum,
LimitNum: limitNum,
Tp: tp,
MetricsFilter: metricsFilter,
NodesFilter: nodesFilter,
WsFilter: wsFilter,
NsFilter: nsFilter,
PodsFilter: podsFilter,
ContainersFilter: containersFilter,
MetricsName: metricsName,
WorkloadName: workloadName,
WlFilter: wlFilter,
NodeId: nodeId,
WsName: wsName,
NsName: nsName,
PodName: podName,
ContainerName: containerName,
WorkloadKind: workloadKind,
}
if timeout == "" {
timeout = DefaultQueryTimeout
}
if step == "" {
step = DefaultQueryStep
}
// Whether query or query_range request
u := url.Values{}
if start != "" && end != "" {
u.Set("start", convertTimeGranularity(start))
u.Set("end", convertTimeGranularity(end))
u.Set("step", step)
u.Set("timeout", timeout)
requestParams.QueryType = RangeQueryType
requestParams.Params = u
return &requestParams
}
if instantTime != "" {
u.Set("time", instantTime)
u.Set("timeout", timeout)
requestParams.QueryType = DefaultQueryType
requestParams.Params = u
return &requestParams
} else {
//u.Set("time", strconv.FormatInt(int64(time.Now().Unix()), 10))
u.Set("timeout", timeout)
requestParams.QueryType = DefaultQueryType
requestParams.Params = u
return &requestParams
}
}
func convertTimeGranularity(ts string) string {
timeFloat, err := strconv.ParseFloat(ts, 64)
if err != nil {
glog.Errorf("convert second timestamp %s to minute timestamp failed", ts)
return strconv.FormatInt(int64(time.Now().Unix()), 10)
}
timeInt := int64(timeFloat)
// convert second timestamp to minute timestamp
secondTime := time.Unix(timeInt, 0).Truncate(time.Minute).Unix()
return strconv.FormatInt(secondTime, 10)
}

View File

@@ -0,0 +1,56 @@
/*
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 redis
import (
"flag"
"log"
"sync"
"github.com/go-redis/redis"
)
var (
redisHost string
redisPassword string
redisDB int
redisClientOnce sync.Once
redisClient *redis.Client
)
func init() {
flag.StringVar(&redisHost, "redis-server", "localhost:6379", "redis server host")
flag.StringVar(&redisPassword, "redis-password", "", "redis password")
flag.IntVar(&redisDB, "redis-db", 0, "redis db")
}
func Client() *redis.Client {
redisClientOnce.Do(func() {
redisClient = redis.NewClient(&redis.Options{
Addr: redisHost,
Password: redisPassword,
DB: redisDB,
})
if err := redisClient.Ping().Err(); err != nil {
log.Fatalln(err)
}
})
return redisClient
}