mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 18:13:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			252 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			252 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2014 The Kubernetes 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 clientcmd
 | 
						|
 | 
						|
import (
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/spf13/pflag"
 | 
						|
 | 
						|
	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
 | 
						|
)
 | 
						|
 | 
						|
// ConfigOverrides holds values that should override whatever information is pulled from the actual Config object.  You can't
 | 
						|
// simply use an actual Config object, because Configs hold maps, but overrides are restricted to "at most one"
 | 
						|
type ConfigOverrides struct {
 | 
						|
	AuthInfo clientcmdapi.AuthInfo
 | 
						|
	// ClusterDefaults are applied before the configured cluster info is loaded.
 | 
						|
	ClusterDefaults clientcmdapi.Cluster
 | 
						|
	ClusterInfo     clientcmdapi.Cluster
 | 
						|
	Context         clientcmdapi.Context
 | 
						|
	CurrentContext  string
 | 
						|
	Timeout         string
 | 
						|
}
 | 
						|
 | 
						|
// ConfigOverrideFlags holds the flag names to be used for binding command line flags. Notice that this structure tightly
 | 
						|
// corresponds to ConfigOverrides
 | 
						|
type ConfigOverrideFlags struct {
 | 
						|
	AuthOverrideFlags    AuthOverrideFlags
 | 
						|
	ClusterOverrideFlags ClusterOverrideFlags
 | 
						|
	ContextOverrideFlags ContextOverrideFlags
 | 
						|
	CurrentContext       FlagInfo
 | 
						|
	Timeout              FlagInfo
 | 
						|
}
 | 
						|
 | 
						|
// AuthOverrideFlags holds the flag names to be used for binding command line flags for AuthInfo objects
 | 
						|
type AuthOverrideFlags struct {
 | 
						|
	ClientCertificate FlagInfo
 | 
						|
	ClientKey         FlagInfo
 | 
						|
	Token             FlagInfo
 | 
						|
	Impersonate       FlagInfo
 | 
						|
	ImpersonateGroups FlagInfo
 | 
						|
	Username          FlagInfo
 | 
						|
	Password          FlagInfo
 | 
						|
}
 | 
						|
 | 
						|
// ContextOverrideFlags holds the flag names to be used for binding command line flags for Cluster objects
 | 
						|
type ContextOverrideFlags struct {
 | 
						|
	ClusterName  FlagInfo
 | 
						|
	AuthInfoName FlagInfo
 | 
						|
	Namespace    FlagInfo
 | 
						|
}
 | 
						|
 | 
						|
// ClusterOverride holds the flag names to be used for binding command line flags for Cluster objects
 | 
						|
type ClusterOverrideFlags struct {
 | 
						|
	APIServer             FlagInfo
 | 
						|
	APIVersion            FlagInfo
 | 
						|
	CertificateAuthority  FlagInfo
 | 
						|
	InsecureSkipTLSVerify FlagInfo
 | 
						|
	TLSServerName         FlagInfo
 | 
						|
}
 | 
						|
 | 
						|
// FlagInfo contains information about how to register a flag.  This struct is useful if you want to provide a way for an extender to
 | 
						|
// get back a set of recommended flag names, descriptions, and defaults, but allow for customization by an extender.  This makes for
 | 
						|
// coherent extension, without full prescription
 | 
						|
type FlagInfo struct {
 | 
						|
	// LongName is the long string for a flag.  If this is empty, then the flag will not be bound
 | 
						|
	LongName string
 | 
						|
	// ShortName is the single character for a flag.  If this is empty, then there will be no short flag
 | 
						|
	ShortName string
 | 
						|
	// Default is the default value for the flag
 | 
						|
	Default string
 | 
						|
	// Description is the description for the flag
 | 
						|
	Description string
 | 
						|
}
 | 
						|
 | 
						|
// AddSecretAnnotation add secret flag to Annotation.
 | 
						|
func (f FlagInfo) AddSecretAnnotation(flags *pflag.FlagSet) FlagInfo {
 | 
						|
	flags.SetAnnotation(f.LongName, "classified", []string{"true"})
 | 
						|
	return f
 | 
						|
}
 | 
						|
 | 
						|
// BindStringFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
 | 
						|
func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) FlagInfo {
 | 
						|
	// you can't register a flag without a long name
 | 
						|
	if len(f.LongName) > 0 {
 | 
						|
		flags.StringVarP(target, f.LongName, f.ShortName, f.Default, f.Description)
 | 
						|
	}
 | 
						|
	return f
 | 
						|
}
 | 
						|
 | 
						|
// BindTransformingStringFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
 | 
						|
func (f FlagInfo) BindTransformingStringFlag(flags *pflag.FlagSet, target *string, transformer func(string) (string, error)) FlagInfo {
 | 
						|
	// you can't register a flag without a long name
 | 
						|
	if len(f.LongName) > 0 {
 | 
						|
		flags.VarP(newTransformingStringValue(f.Default, target, transformer), f.LongName, f.ShortName, f.Description)
 | 
						|
	}
 | 
						|
	return f
 | 
						|
}
 | 
						|
 | 
						|
// BindStringSliceFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
 | 
						|
func (f FlagInfo) BindStringArrayFlag(flags *pflag.FlagSet, target *[]string) FlagInfo {
 | 
						|
	// you can't register a flag without a long name
 | 
						|
	if len(f.LongName) > 0 {
 | 
						|
		sliceVal := []string{}
 | 
						|
		if len(f.Default) > 0 {
 | 
						|
			sliceVal = []string{f.Default}
 | 
						|
		}
 | 
						|
		flags.StringArrayVarP(target, f.LongName, f.ShortName, sliceVal, f.Description)
 | 
						|
	}
 | 
						|
	return f
 | 
						|
}
 | 
						|
 | 
						|
// BindBoolFlag binds the flag based on the provided info.  If LongName == "", nothing is registered
 | 
						|
func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo {
 | 
						|
	// you can't register a flag without a long name
 | 
						|
	if len(f.LongName) > 0 {
 | 
						|
		// try to parse Default as a bool.  If it fails, assume false
 | 
						|
		boolVal, err := strconv.ParseBool(f.Default)
 | 
						|
		if err != nil {
 | 
						|
			boolVal = false
 | 
						|
		}
 | 
						|
 | 
						|
		flags.BoolVarP(target, f.LongName, f.ShortName, boolVal, f.Description)
 | 
						|
	}
 | 
						|
	return f
 | 
						|
}
 | 
						|
 | 
						|
const (
 | 
						|
	FlagClusterName      = "cluster"
 | 
						|
	FlagAuthInfoName     = "user"
 | 
						|
	FlagContext          = "context"
 | 
						|
	FlagNamespace        = "namespace"
 | 
						|
	FlagAPIServer        = "server"
 | 
						|
	FlagTLSServerName    = "tls-server-name"
 | 
						|
	FlagInsecure         = "insecure-skip-tls-verify"
 | 
						|
	FlagCertFile         = "client-certificate"
 | 
						|
	FlagKeyFile          = "client-key"
 | 
						|
	FlagCAFile           = "certificate-authority"
 | 
						|
	FlagEmbedCerts       = "embed-certs"
 | 
						|
	FlagBearerToken      = "token"
 | 
						|
	FlagImpersonate      = "as"
 | 
						|
	FlagImpersonateGroup = "as-group"
 | 
						|
	FlagUsername         = "username"
 | 
						|
	FlagPassword         = "password"
 | 
						|
	FlagTimeout          = "request-timeout"
 | 
						|
)
 | 
						|
 | 
						|
// RecommendedConfigOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
 | 
						|
func RecommendedConfigOverrideFlags(prefix string) ConfigOverrideFlags {
 | 
						|
	return ConfigOverrideFlags{
 | 
						|
		AuthOverrideFlags:    RecommendedAuthOverrideFlags(prefix),
 | 
						|
		ClusterOverrideFlags: RecommendedClusterOverrideFlags(prefix),
 | 
						|
		ContextOverrideFlags: RecommendedContextOverrideFlags(prefix),
 | 
						|
 | 
						|
		CurrentContext: FlagInfo{prefix + FlagContext, "", "", "The name of the kubeconfig context to use"},
 | 
						|
		Timeout:        FlagInfo{prefix + FlagTimeout, "", "0", "The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests."},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RecommendedAuthOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
 | 
						|
func RecommendedAuthOverrideFlags(prefix string) AuthOverrideFlags {
 | 
						|
	return AuthOverrideFlags{
 | 
						|
		ClientCertificate: FlagInfo{prefix + FlagCertFile, "", "", "Path to a client certificate file for TLS"},
 | 
						|
		ClientKey:         FlagInfo{prefix + FlagKeyFile, "", "", "Path to a client key file for TLS"},
 | 
						|
		Token:             FlagInfo{prefix + FlagBearerToken, "", "", "Bearer token for authentication to the API server"},
 | 
						|
		Impersonate:       FlagInfo{prefix + FlagImpersonate, "", "", "Username to impersonate for the operation"},
 | 
						|
		ImpersonateGroups: FlagInfo{prefix + FlagImpersonateGroup, "", "", "Group to impersonate for the operation, this flag can be repeated to specify multiple groups."},
 | 
						|
		Username:          FlagInfo{prefix + FlagUsername, "", "", "Username for basic authentication to the API server"},
 | 
						|
		Password:          FlagInfo{prefix + FlagPassword, "", "", "Password for basic authentication to the API server"},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RecommendedClusterOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
 | 
						|
func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags {
 | 
						|
	return ClusterOverrideFlags{
 | 
						|
		APIServer:             FlagInfo{prefix + FlagAPIServer, "", "", "The address and port of the Kubernetes API server"},
 | 
						|
		CertificateAuthority:  FlagInfo{prefix + FlagCAFile, "", "", "Path to a cert file for the certificate authority"},
 | 
						|
		InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure"},
 | 
						|
		TLSServerName:         FlagInfo{prefix + FlagTLSServerName, "", "", "If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used."},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// RecommendedContextOverrideFlags is a convenience method to return recommended flag names prefixed with a string of your choosing
 | 
						|
func RecommendedContextOverrideFlags(prefix string) ContextOverrideFlags {
 | 
						|
	return ContextOverrideFlags{
 | 
						|
		ClusterName:  FlagInfo{prefix + FlagClusterName, "", "", "The name of the kubeconfig cluster to use"},
 | 
						|
		AuthInfoName: FlagInfo{prefix + FlagAuthInfoName, "", "", "The name of the kubeconfig user to use"},
 | 
						|
		Namespace:    FlagInfo{prefix + FlagNamespace, "n", "", "If present, the namespace scope for this CLI request"},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// BindOverrideFlags is a convenience method to bind the specified flags to their associated variables
 | 
						|
func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNames ConfigOverrideFlags) {
 | 
						|
	BindAuthInfoFlags(&overrides.AuthInfo, flags, flagNames.AuthOverrideFlags)
 | 
						|
	BindClusterFlags(&overrides.ClusterInfo, flags, flagNames.ClusterOverrideFlags)
 | 
						|
	BindContextFlags(&overrides.Context, flags, flagNames.ContextOverrideFlags)
 | 
						|
	flagNames.CurrentContext.BindStringFlag(flags, &overrides.CurrentContext)
 | 
						|
	flagNames.Timeout.BindStringFlag(flags, &overrides.Timeout)
 | 
						|
}
 | 
						|
 | 
						|
// BindAuthInfoFlags is a convenience method to bind the specified flags to their associated variables
 | 
						|
func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, flagNames AuthOverrideFlags) {
 | 
						|
	flagNames.ClientCertificate.BindStringFlag(flags, &authInfo.ClientCertificate).AddSecretAnnotation(flags)
 | 
						|
	flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey).AddSecretAnnotation(flags)
 | 
						|
	flagNames.Token.BindStringFlag(flags, &authInfo.Token).AddSecretAnnotation(flags)
 | 
						|
	flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate).AddSecretAnnotation(flags)
 | 
						|
	flagNames.ImpersonateGroups.BindStringArrayFlag(flags, &authInfo.ImpersonateGroups).AddSecretAnnotation(flags)
 | 
						|
	flagNames.Username.BindStringFlag(flags, &authInfo.Username).AddSecretAnnotation(flags)
 | 
						|
	flagNames.Password.BindStringFlag(flags, &authInfo.Password).AddSecretAnnotation(flags)
 | 
						|
}
 | 
						|
 | 
						|
// BindClusterFlags is a convenience method to bind the specified flags to their associated variables
 | 
						|
func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, flagNames ClusterOverrideFlags) {
 | 
						|
	flagNames.APIServer.BindStringFlag(flags, &clusterInfo.Server)
 | 
						|
	flagNames.CertificateAuthority.BindStringFlag(flags, &clusterInfo.CertificateAuthority)
 | 
						|
	flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify)
 | 
						|
	flagNames.TLSServerName.BindStringFlag(flags, &clusterInfo.TLSServerName)
 | 
						|
}
 | 
						|
 | 
						|
// BindFlags is a convenience method to bind the specified flags to their associated variables
 | 
						|
func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) {
 | 
						|
	flagNames.ClusterName.BindStringFlag(flags, &contextInfo.Cluster)
 | 
						|
	flagNames.AuthInfoName.BindStringFlag(flags, &contextInfo.AuthInfo)
 | 
						|
	flagNames.Namespace.BindTransformingStringFlag(flags, &contextInfo.Namespace, RemoveNamespacesPrefix)
 | 
						|
}
 | 
						|
 | 
						|
// RemoveNamespacesPrefix is a transformer that strips "ns/", "namespace/" and "namespaces/" prefixes case-insensitively
 | 
						|
func RemoveNamespacesPrefix(value string) (string, error) {
 | 
						|
	for _, prefix := range []string{"namespaces/", "namespace/", "ns/"} {
 | 
						|
		if len(value) > len(prefix) && strings.EqualFold(value[0:len(prefix)], prefix) {
 | 
						|
			value = value[len(prefix):]
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return value, nil
 | 
						|
}
 |