package k8s import ( "fmt" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd/api" "os" "strings" ) type config struct { Host string `json:"host"` // K8S地址 AuthType AuthType `json:"authType"` // 认证方式 0:config 1:token Config string `json:"config"` // 认证配置文件 Token string `json:"token"` // 认证Token IsSkipTls bool `json:"isSkipTls"` // 是否跳过TLS认证 CaCrt string `json:"caCrt"` // CA证书 ClusterName string `json:"clusterName"` // 集群名称 resetConf *rest.Config } type option func(c *config) func WithHost(host string) option { return func(c *config) { c.Host = host } } func WithAuthType(authType string) option { return func(c *config) { switch strings.ToUpper(authType) { case "CONFIG": c.AuthType = AuthConfig case "TOKEN": c.AuthType = AuthToken } } } func WithConfig(conf string) option { return func(c *config) { c.Config = conf } } func WithToken(token string) option { return func(c *config) { c.Token = token } } func WithIsSkipTls(isSkipTls bool) option { return func(c *config) { c.IsSkipTls = isSkipTls } } func WithCaCrt(caCrt string) option { return func(c *config) { c.CaCrt = caCrt } } func WithCluster(cluster string) option { return func(c *config) { c.ClusterName = cluster } } func NewConfig(opts ...option) (*config, error) { c := &config{} for _, opt := range opts { opt(c) } if err := c.valid(); err != nil { return nil, err } var restConfig *rest.Config var err error switch c.AuthType { case AuthToken: restConfig, err = clientcmd.BuildConfigFromKubeconfigGetter(c.Host, func() (*api.Config, error) { apiConf := &api.Config{ Clusters: map[string]*api.Cluster{ c.ClusterName: { Server: c.Host, InsecureSkipTLSVerify: c.IsSkipTls, CertificateAuthorityData: []byte(c.CaCrt), }, }, AuthInfos: map[string]*api.AuthInfo{ c.ClusterName: { Token: c.Token, }, }, Contexts: map[string]*api.Context{ c.ClusterName: { Cluster: c.ClusterName, AuthInfo: c.ClusterName, }, }, CurrentContext: c.ClusterName, } // 如果跳过TLS认证,则清空CA证书 if c.IsSkipTls { apiConf.Clusters[c.ClusterName].InsecureSkipTLSVerify = c.IsSkipTls apiConf.Clusters[c.ClusterName].CertificateAuthorityData = nil } return apiConf, nil }) case AuthConfig: restConfig, err = clientcmd.BuildConfigFromFlags(c.Host, c.GetConfigPath()) } if err != nil { return nil, err } c.resetConf = restConfig return c, nil } func (c *config) valid() error { if !strings.HasPrefix(c.Host, "https://") && !strings.HasPrefix(c.Host, "http://") { c.Host = fmt.Sprintf("https://%s", c.Host) } if c.Token == "" && c.Config == "" { return fmt.Errorf("auth token or auth config not empty") } if c.ClusterName == "" { c.ClusterName = "default" } return nil } func (c *config) GetConfigPath() string { if err := os.WriteFile("./kubernetes", []byte(c.Config), 0644); err != nil { panic(err) } return "./kubernetes" }