mirror of https://github.com/fluxcd/flux2.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.5 KiB
Go
150 lines
4.5 KiB
Go
/*
|
|
Copyright 2023 The Flux 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 main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/spf13/pflag"
|
|
"k8s.io/client-go/rest"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
|
)
|
|
|
|
// KubeConfigArgs contains the args related to kubeconfig and cluster access
|
|
type KubeConfigArgs struct {
|
|
KubeConfig string
|
|
KubeContext string
|
|
InsecureSkipVerify bool
|
|
Namespace *string
|
|
defaultClientConfig clientcmd.ClientConfig
|
|
}
|
|
|
|
// NewKubeConfigArgs returns a new KubeConfigArgs
|
|
func NewKubeConfigArgs() *KubeConfigArgs {
|
|
namespace := ""
|
|
return &KubeConfigArgs{
|
|
Namespace: &namespace,
|
|
}
|
|
}
|
|
|
|
// BindFlags binds the KubeConfigArgs fields to the given flag set
|
|
func (ka *KubeConfigArgs) BindFlags(flags *pflag.FlagSet) {
|
|
flags.StringVar(&ka.KubeConfig, "kubeconfig", "",
|
|
"Path to the kubeconfig file")
|
|
flags.StringVar(&ka.KubeContext, "context", "",
|
|
"Kubernetes context to use")
|
|
flags.BoolVar(&ka.InsecureSkipVerify, "insecure-skip-tls-verify", false,
|
|
"Skip TLS certificate validation when connecting to the Kubernetes API server")
|
|
flags.StringVar(ka.Namespace, "namespace", "",
|
|
"The namespace scope for this operation")
|
|
}
|
|
|
|
// loadKubeConfig loads the kubeconfig file based on the provided args and KUBECONFIG env var
|
|
func (ka *KubeConfigArgs) loadKubeConfig() (*clientcmdapi.Config, error) {
|
|
// If kubeconfig is explicitly provided, use it
|
|
if ka.KubeConfig != "" {
|
|
return clientcmd.LoadFromFile(ka.KubeConfig)
|
|
}
|
|
|
|
// Check if KUBECONFIG env var is set
|
|
kubeconfigEnv := os.Getenv("KUBECONFIG")
|
|
if kubeconfigEnv != "" {
|
|
// KUBECONFIG can contain multiple paths
|
|
paths := filepath.SplitList(kubeconfigEnv)
|
|
if len(paths) > 1 {
|
|
// Merge multiple kubeconfig files
|
|
loadingRules := clientcmd.ClientConfigLoadingRules{
|
|
Precedence: paths,
|
|
}
|
|
return loadingRules.Load()
|
|
} else if len(paths) == 1 {
|
|
// Single path in KUBECONFIG
|
|
return clientcmd.LoadFromFile(paths[0])
|
|
}
|
|
}
|
|
|
|
// Fall back to default kubeconfig location
|
|
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
|
return loadingRules.Load()
|
|
}
|
|
|
|
// kubeConfig returns a complete client config based on the provided args
|
|
func (ka *KubeConfigArgs) kubeConfig(explicitPath string) (clientcmd.ClientConfig, error) {
|
|
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
|
|
if explicitPath != "" {
|
|
loadingRules.ExplicitPath = explicitPath
|
|
} else if ka.KubeConfig != "" {
|
|
loadingRules.ExplicitPath = ka.KubeConfig
|
|
} else if kubeconfig := os.Getenv("KUBECONFIG"); kubeconfig != "" {
|
|
// KUBECONFIG is a list of files separated by path list separator
|
|
paths := filepath.SplitList(kubeconfig)
|
|
if len(paths) > 0 {
|
|
loadingRules.Precedence = paths
|
|
}
|
|
}
|
|
|
|
configOverrides := &clientcmd.ConfigOverrides{}
|
|
if ka.KubeContext != "" {
|
|
configOverrides.CurrentContext = ka.KubeContext
|
|
}
|
|
if ka.InsecureSkipVerify {
|
|
configOverrides.ClusterInfo.InsecureSkipTLSVerify = true
|
|
}
|
|
if *ka.Namespace != "" {
|
|
configOverrides.Context.Namespace = *ka.Namespace
|
|
}
|
|
|
|
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
|
loadingRules,
|
|
configOverrides,
|
|
), nil
|
|
}
|
|
|
|
// KubeConfig returns a complete rest.Config based on the provided args
|
|
func (ka *KubeConfigArgs) KubeConfig(explicitPath string) (*rest.Config, error) {
|
|
clientConfig, err := ka.kubeConfig(explicitPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config, err := clientConfig.ClientConfig()
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "context") && strings.Contains(err.Error(), "does not exist") {
|
|
return nil, err
|
|
}
|
|
if strings.Contains(err.Error(), "cluster") && strings.Contains(err.Error(), "does not exist") {
|
|
return nil, err
|
|
}
|
|
if strings.Contains(err.Error(), "user") && strings.Contains(err.Error(), "does not exist") {
|
|
return nil, err
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
// Apply InsecureSkipVerify to rest.Config
|
|
if ka.InsecureSkipVerify {
|
|
config.TLSClientConfig.Insecure = true
|
|
config.TLSClientConfig.CAData = nil
|
|
config.TLSClientConfig.CAFile = ""
|
|
}
|
|
|
|
return config, nil
|
|
}
|