mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
relativize paths in kubeconfig files
This commit is contained in:
parent
55f574c267
commit
c5ef83b29b
@ -23,6 +23,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
@ -120,11 +121,6 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
|
|||||||
if err := mergeConfigWithFile(mapConfig, file); err != nil {
|
if err := mergeConfigWithFile(mapConfig, file); err != nil {
|
||||||
errlist = append(errlist, err)
|
errlist = append(errlist, err)
|
||||||
}
|
}
|
||||||
if rules.ResolvePaths() {
|
|
||||||
if err := ResolveLocalPaths(file, mapConfig); err != nil {
|
|
||||||
errlist = append(errlist, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// merge all of the struct values in the reverse order so that priority is given correctly
|
// merge all of the struct values in the reverse order so that priority is given correctly
|
||||||
@ -133,9 +129,6 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
|
|||||||
for i := len(kubeConfigFiles) - 1; i >= 0; i-- {
|
for i := len(kubeConfigFiles) - 1; i >= 0; i-- {
|
||||||
file := kubeConfigFiles[i]
|
file := kubeConfigFiles[i]
|
||||||
mergeConfigWithFile(nonMapConfig, file)
|
mergeConfigWithFile(nonMapConfig, file)
|
||||||
if rules.ResolvePaths() {
|
|
||||||
ResolveLocalPaths(file, nonMapConfig)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and
|
// since values are overwritten, but maps values are not, we can merge the non-map config on top of the map config and
|
||||||
@ -144,6 +137,12 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
|
|||||||
mergo.Merge(config, mapConfig)
|
mergo.Merge(config, mapConfig)
|
||||||
mergo.Merge(config, nonMapConfig)
|
mergo.Merge(config, nonMapConfig)
|
||||||
|
|
||||||
|
if rules.ResolvePaths() {
|
||||||
|
if err := ResolveLocalPaths(config); err != nil {
|
||||||
|
errlist = append(errlist, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return config, errors.NewAggregate(errlist)
|
return config, errors.NewAggregate(errlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,49 +212,6 @@ func mergeConfigWithFile(startingConfig *clientcmdapi.Config, filename string) e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveLocalPaths resolves all relative paths in the config object with respect to the parent directory of the filename
|
|
||||||
// this cannot be done directly inside of LoadFromFile because doing so there would make it impossible to load a file without
|
|
||||||
// modification of its contents.
|
|
||||||
func ResolveLocalPaths(filename string, config *clientcmdapi.Config) error {
|
|
||||||
if len(filename) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
configDir, err := filepath.Abs(filepath.Dir(filename))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not determine the absolute path of config file %s: %v", filename, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedClusters := make(map[string]*clientcmdapi.Cluster)
|
|
||||||
for key, cluster := range config.Clusters {
|
|
||||||
cluster.CertificateAuthority = resolveLocalPath(configDir, cluster.CertificateAuthority)
|
|
||||||
resolvedClusters[key] = cluster
|
|
||||||
}
|
|
||||||
config.Clusters = resolvedClusters
|
|
||||||
|
|
||||||
resolvedAuthInfos := make(map[string]*clientcmdapi.AuthInfo)
|
|
||||||
for key, authInfo := range config.AuthInfos {
|
|
||||||
authInfo.ClientCertificate = resolveLocalPath(configDir, authInfo.ClientCertificate)
|
|
||||||
authInfo.ClientKey = resolveLocalPath(configDir, authInfo.ClientKey)
|
|
||||||
resolvedAuthInfos[key] = authInfo
|
|
||||||
}
|
|
||||||
config.AuthInfos = resolvedAuthInfos
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolveLocalPath makes the path absolute with respect to the startingDir
|
|
||||||
func resolveLocalPath(startingDir, path string) string {
|
|
||||||
if len(path) == 0 {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
if filepath.IsAbs(path) {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Join(startingDir, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadFromFile takes a filename and deserializes the contents into Config object
|
// LoadFromFile takes a filename and deserializes the contents into Config object
|
||||||
func LoadFromFile(filename string) (*clientcmdapi.Config, error) {
|
func LoadFromFile(filename string) (*clientcmdapi.Config, error) {
|
||||||
kubeconfigBytes, err := ioutil.ReadFile(filename)
|
kubeconfigBytes, err := ioutil.ReadFile(filename)
|
||||||
@ -335,3 +291,159 @@ func Write(config clientcmdapi.Config) ([]byte, error) {
|
|||||||
func (rules ClientConfigLoadingRules) ResolvePaths() bool {
|
func (rules ClientConfigLoadingRules) ResolvePaths() bool {
|
||||||
return !rules.DoNotResolvePaths
|
return !rules.DoNotResolvePaths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResolveLocalPaths resolves all relative paths in the config object with respect to the stanza's LocationOfOrigin
|
||||||
|
// this cannot be done directly inside of LoadFromFile because doing so there would make it impossible to load a file without
|
||||||
|
// modification of its contents.
|
||||||
|
func ResolveLocalPaths(config *clientcmdapi.Config) error {
|
||||||
|
for _, cluster := range config.Clusters {
|
||||||
|
if len(cluster.LocationOfOrigin) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
base, err := filepath.Abs(filepath.Dir(cluster.LocationOfOrigin))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Could not determine the absolute path of config file %s: %v", cluster.LocationOfOrigin, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ResolvePaths(GetClusterFileReferences(cluster), base); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, authInfo := range config.AuthInfos {
|
||||||
|
if len(authInfo.LocationOfOrigin) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
base, err := filepath.Abs(filepath.Dir(authInfo.LocationOfOrigin))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Could not determine the absolute path of config file %s: %v", authInfo.LocationOfOrigin, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ResolvePaths(GetAuthInfoFileReferences(authInfo), base); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RelativizeClusterLocalPaths first absolutizes the paths by calling ResolveLocalPaths. This assumes that any NEW path is already
|
||||||
|
// absolute, but any existing path will be resolved relative to LocationOfOrigin
|
||||||
|
func RelativizeClusterLocalPaths(cluster *clientcmdapi.Cluster) error {
|
||||||
|
if len(cluster.LocationOfOrigin) == 0 {
|
||||||
|
return fmt.Errorf("no location of origin for %s", cluster.Server)
|
||||||
|
}
|
||||||
|
base, err := filepath.Abs(filepath.Dir(cluster.LocationOfOrigin))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not determine the absolute path of config file %s: %v", cluster.LocationOfOrigin, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ResolvePaths(GetClusterFileReferences(cluster), base); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := RelativizePathWithNoBacksteps(GetClusterFileReferences(cluster), base); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RelativizeAuthInfoLocalPaths first absolutizes the paths by calling ResolveLocalPaths. This assumes that any NEW path is already
|
||||||
|
// absolute, but any existing path will be resolved relative to LocationOfOrigin
|
||||||
|
func RelativizeAuthInfoLocalPaths(authInfo *clientcmdapi.AuthInfo) error {
|
||||||
|
if len(authInfo.LocationOfOrigin) == 0 {
|
||||||
|
return fmt.Errorf("no location of origin for %v", authInfo)
|
||||||
|
}
|
||||||
|
base, err := filepath.Abs(filepath.Dir(authInfo.LocationOfOrigin))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not determine the absolute path of config file %s: %v", authInfo.LocationOfOrigin, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ResolvePaths(GetAuthInfoFileReferences(authInfo), base); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := RelativizePathWithNoBacksteps(GetAuthInfoFileReferences(authInfo), base); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RelativizeConfigPaths(config *clientcmdapi.Config, base string) error {
|
||||||
|
return RelativizePathWithNoBacksteps(GetConfigFileReferences(config), base)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResolveConfigPaths(config *clientcmdapi.Config, base string) error {
|
||||||
|
return ResolvePaths(GetConfigFileReferences(config), base)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConfigFileReferences(config *clientcmdapi.Config) []*string {
|
||||||
|
refs := []*string{}
|
||||||
|
|
||||||
|
for _, cluster := range config.Clusters {
|
||||||
|
refs = append(refs, GetClusterFileReferences(cluster)...)
|
||||||
|
}
|
||||||
|
for _, authInfo := range config.AuthInfos {
|
||||||
|
refs = append(refs, GetAuthInfoFileReferences(authInfo)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return refs
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetClusterFileReferences(cluster *clientcmdapi.Cluster) []*string {
|
||||||
|
return []*string{&cluster.CertificateAuthority}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAuthInfoFileReferences(authInfo *clientcmdapi.AuthInfo) []*string {
|
||||||
|
return []*string{&authInfo.ClientCertificate, &authInfo.ClientKey}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolvePaths updates the given refs to be absolute paths, relative to the given base directory
|
||||||
|
func ResolvePaths(refs []*string, base string) error {
|
||||||
|
for _, ref := range refs {
|
||||||
|
// Don't resolve empty paths
|
||||||
|
if len(*ref) > 0 {
|
||||||
|
// Don't resolve absolute paths
|
||||||
|
if !filepath.IsAbs(*ref) {
|
||||||
|
*ref = filepath.Join(base, *ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RelativizePathWithNoBacksteps updates the given refs to be relative paths, relative to the given base directory as long as they do not require backsteps.
|
||||||
|
// Any path requiring a backstep is left as-is as long it is absolute. Any non-absolute path that can't be relativized produces an error
|
||||||
|
func RelativizePathWithNoBacksteps(refs []*string, base string) error {
|
||||||
|
for _, ref := range refs {
|
||||||
|
// Don't relativize empty paths
|
||||||
|
if len(*ref) > 0 {
|
||||||
|
rel, err := MakeRelative(*ref, base)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have a backstep, don't mess with the path
|
||||||
|
if strings.HasPrefix(rel, "../") {
|
||||||
|
if filepath.IsAbs(*ref) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("%v requires backsteps and is not absolute", *ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
*ref = rel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeRelative(path, base string) (string, error) {
|
||||||
|
if len(path) > 0 {
|
||||||
|
rel, err := filepath.Rel(base, path)
|
||||||
|
if err != nil {
|
||||||
|
return path, err
|
||||||
|
}
|
||||||
|
return rel, nil
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
@ -187,8 +187,9 @@ func (o *PathOptions) GetExplicitFile() string {
|
|||||||
// uses the default destination file to write the results into. This results in multiple file reads, but it's very easy to follow.
|
// uses the default destination file to write the results into. This results in multiple file reads, but it's very easy to follow.
|
||||||
// Preferences and CurrentContext should always be set in the default destination file. Since we can't distinguish between empty and missing values
|
// Preferences and CurrentContext should always be set in the default destination file. Since we can't distinguish between empty and missing values
|
||||||
// (no nil strings), we're forced have separate handling for them. In the kubeconfig cases, newConfig should have at most one difference,
|
// (no nil strings), we're forced have separate handling for them. In the kubeconfig cases, newConfig should have at most one difference,
|
||||||
// that means that this code will only write into a single file.
|
// that means that this code will only write into a single file. If you want to relativizePaths, you must provide a fully qualified path in any
|
||||||
func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config) error {
|
// modified element.
|
||||||
|
func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config, relativizePaths bool) error {
|
||||||
startingConfig, err := configAccess.GetStartingConfig()
|
startingConfig, err := configAccess.GetStartingConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -223,7 +224,14 @@ func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
configToWrite := getConfigFromFileOrDie(destinationFile)
|
configToWrite := getConfigFromFileOrDie(destinationFile)
|
||||||
configToWrite.Clusters[key] = cluster
|
t := *cluster
|
||||||
|
configToWrite.Clusters[key] = &t
|
||||||
|
configToWrite.Clusters[key].LocationOfOrigin = destinationFile
|
||||||
|
if relativizePaths {
|
||||||
|
if err := clientcmd.RelativizeClusterLocalPaths(configToWrite.Clusters[key]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
|
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -257,7 +265,14 @@ func ModifyConfig(configAccess ConfigAccess, newConfig clientcmdapi.Config) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
configToWrite := getConfigFromFileOrDie(destinationFile)
|
configToWrite := getConfigFromFileOrDie(destinationFile)
|
||||||
configToWrite.AuthInfos[key] = authInfo
|
t := *authInfo
|
||||||
|
configToWrite.AuthInfos[key] = &t
|
||||||
|
configToWrite.AuthInfos[key].LocationOfOrigin = destinationFile
|
||||||
|
if relativizePaths {
|
||||||
|
if err := clientcmd.RelativizeAuthInfoLocalPaths(configToWrite.AuthInfos[key]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
|
if err := clientcmd.WriteToFile(*configToWrite, destinationFile); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -79,10 +80,9 @@ func TestSetCurrentContext(t *testing.T) {
|
|||||||
startingConfig := newRedFederalCowHammerConfig()
|
startingConfig := newRedFederalCowHammerConfig()
|
||||||
|
|
||||||
newContextName := "the-new-context"
|
newContextName := "the-new-context"
|
||||||
newContext := clientcmdapi.NewContext()
|
|
||||||
|
|
||||||
startingConfig.Contexts[newContextName] = *newContext
|
startingConfig.Contexts[newContextName] = clientcmdapi.NewContext()
|
||||||
expectedConfig.Contexts[newContextName] = *newContext
|
expectedConfig.Contexts[newContextName] = clientcmdapi.NewContext()
|
||||||
|
|
||||||
expectedConfig.CurrentContext = newContextName
|
expectedConfig.CurrentContext = newContextName
|
||||||
|
|
||||||
@ -287,13 +287,15 @@ func TestEmbedNoKeyOrCertDisallowed(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyTokenAndCertAllowed(t *testing.T) {
|
func TestEmptyTokenAndCertAllowed(t *testing.T) {
|
||||||
|
fakeCertFile, _ := ioutil.TempFile("", "cert-file")
|
||||||
|
|
||||||
expectedConfig := newRedFederalCowHammerConfig()
|
expectedConfig := newRedFederalCowHammerConfig()
|
||||||
authInfo := clientcmdapi.NewAuthInfo()
|
authInfo := clientcmdapi.NewAuthInfo()
|
||||||
authInfo.ClientCertificate = "cert-file"
|
authInfo.ClientCertificate = path.Base(fakeCertFile.Name())
|
||||||
expectedConfig.AuthInfos["another-user"] = authInfo
|
expectedConfig.AuthInfos["another-user"] = authInfo
|
||||||
|
|
||||||
test := configCommandTest{
|
test := configCommandTest{
|
||||||
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=cert-file", "--" + clientcmd.FlagBearerToken + "="},
|
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=" + fakeCertFile.Name(), "--" + clientcmd.FlagBearerToken + "="},
|
||||||
startingConfig: newRedFederalCowHammerConfig(),
|
startingConfig: newRedFederalCowHammerConfig(),
|
||||||
expectedConfig: expectedConfig,
|
expectedConfig: expectedConfig,
|
||||||
}
|
}
|
||||||
@ -305,10 +307,10 @@ func TestTokenAndCertAllowed(t *testing.T) {
|
|||||||
expectedConfig := newRedFederalCowHammerConfig()
|
expectedConfig := newRedFederalCowHammerConfig()
|
||||||
authInfo := clientcmdapi.NewAuthInfo()
|
authInfo := clientcmdapi.NewAuthInfo()
|
||||||
authInfo.Token = "token"
|
authInfo.Token = "token"
|
||||||
authInfo.ClientCertificate = "cert-file"
|
authInfo.ClientCertificate = "/cert-file"
|
||||||
expectedConfig.AuthInfos["another-user"] = authInfo
|
expectedConfig.AuthInfos["another-user"] = authInfo
|
||||||
test := configCommandTest{
|
test := configCommandTest{
|
||||||
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=cert-file", "--" + clientcmd.FlagBearerToken + "=token"},
|
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=/cert-file", "--" + clientcmd.FlagBearerToken + "=token"},
|
||||||
startingConfig: newRedFederalCowHammerConfig(),
|
startingConfig: newRedFederalCowHammerConfig(),
|
||||||
expectedConfig: expectedConfig,
|
expectedConfig: expectedConfig,
|
||||||
}
|
}
|
||||||
@ -409,8 +411,8 @@ func TestCertLeavesToken(t *testing.T) {
|
|||||||
|
|
||||||
authInfoWithTokenAndCerts := clientcmdapi.NewAuthInfo()
|
authInfoWithTokenAndCerts := clientcmdapi.NewAuthInfo()
|
||||||
authInfoWithTokenAndCerts.Token = "token"
|
authInfoWithTokenAndCerts.Token = "token"
|
||||||
authInfoWithTokenAndCerts.ClientCertificate = "cert"
|
authInfoWithTokenAndCerts.ClientCertificate = "/cert"
|
||||||
authInfoWithTokenAndCerts.ClientKey = "key"
|
authInfoWithTokenAndCerts.ClientKey = "/key"
|
||||||
|
|
||||||
startingConfig := newRedFederalCowHammerConfig()
|
startingConfig := newRedFederalCowHammerConfig()
|
||||||
startingConfig.AuthInfos["another-user"] = authInfoWithToken
|
startingConfig.AuthInfos["another-user"] = authInfoWithToken
|
||||||
@ -419,7 +421,7 @@ func TestCertLeavesToken(t *testing.T) {
|
|||||||
expectedConfig.AuthInfos["another-user"] = authInfoWithTokenAndCerts
|
expectedConfig.AuthInfos["another-user"] = authInfoWithTokenAndCerts
|
||||||
|
|
||||||
test := configCommandTest{
|
test := configCommandTest{
|
||||||
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=cert", "--" + clientcmd.FlagKeyFile + "=key"},
|
args: []string{"set-credentials", "another-user", "--" + clientcmd.FlagCertFile + "=/cert", "--" + clientcmd.FlagKeyFile + "=/key"},
|
||||||
startingConfig: startingConfig,
|
startingConfig: startingConfig,
|
||||||
expectedConfig: expectedConfig,
|
expectedConfig: expectedConfig,
|
||||||
}
|
}
|
||||||
@ -428,11 +430,13 @@ func TestCertLeavesToken(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCAClearsInsecure(t *testing.T) {
|
func TestCAClearsInsecure(t *testing.T) {
|
||||||
|
fakeCAFile, _ := ioutil.TempFile("", "ca-file")
|
||||||
|
|
||||||
clusterInfoWithInsecure := clientcmdapi.NewCluster()
|
clusterInfoWithInsecure := clientcmdapi.NewCluster()
|
||||||
clusterInfoWithInsecure.InsecureSkipTLSVerify = true
|
clusterInfoWithInsecure.InsecureSkipTLSVerify = true
|
||||||
|
|
||||||
clusterInfoWithCA := clientcmdapi.NewCluster()
|
clusterInfoWithCA := clientcmdapi.NewCluster()
|
||||||
clusterInfoWithCA.CertificateAuthority = "cafile"
|
clusterInfoWithCA.CertificateAuthority = path.Base(fakeCAFile.Name())
|
||||||
|
|
||||||
startingConfig := newRedFederalCowHammerConfig()
|
startingConfig := newRedFederalCowHammerConfig()
|
||||||
startingConfig.Clusters["another-cluster"] = clusterInfoWithInsecure
|
startingConfig.Clusters["another-cluster"] = clusterInfoWithInsecure
|
||||||
@ -441,7 +445,7 @@ func TestCAClearsInsecure(t *testing.T) {
|
|||||||
expectedConfig.Clusters["another-cluster"] = clusterInfoWithCA
|
expectedConfig.Clusters["another-cluster"] = clusterInfoWithCA
|
||||||
|
|
||||||
test := configCommandTest{
|
test := configCommandTest{
|
||||||
args: []string{"set-cluster", "another-cluster", "--" + clientcmd.FlagCAFile + "=cafile"},
|
args: []string{"set-cluster", "another-cluster", "--" + clientcmd.FlagCAFile + "=" + fakeCAFile.Name()},
|
||||||
startingConfig: startingConfig,
|
startingConfig: startingConfig,
|
||||||
expectedConfig: expectedConfig,
|
expectedConfig: expectedConfig,
|
||||||
}
|
}
|
||||||
@ -454,7 +458,7 @@ func TestCAClearsCAData(t *testing.T) {
|
|||||||
clusterInfoWithCAData.CertificateAuthorityData = []byte("cadata")
|
clusterInfoWithCAData.CertificateAuthorityData = []byte("cadata")
|
||||||
|
|
||||||
clusterInfoWithCA := clientcmdapi.NewCluster()
|
clusterInfoWithCA := clientcmdapi.NewCluster()
|
||||||
clusterInfoWithCA.CertificateAuthority = "cafile"
|
clusterInfoWithCA.CertificateAuthority = "/cafile"
|
||||||
|
|
||||||
startingConfig := newRedFederalCowHammerConfig()
|
startingConfig := newRedFederalCowHammerConfig()
|
||||||
startingConfig.Clusters["another-cluster"] = clusterInfoWithCAData
|
startingConfig.Clusters["another-cluster"] = clusterInfoWithCAData
|
||||||
@ -463,7 +467,7 @@ func TestCAClearsCAData(t *testing.T) {
|
|||||||
expectedConfig.Clusters["another-cluster"] = clusterInfoWithCA
|
expectedConfig.Clusters["another-cluster"] = clusterInfoWithCA
|
||||||
|
|
||||||
test := configCommandTest{
|
test := configCommandTest{
|
||||||
args: []string{"set-cluster", "another-cluster", "--" + clientcmd.FlagCAFile + "=cafile", "--" + clientcmd.FlagInsecure + "=false"},
|
args: []string{"set-cluster", "another-cluster", "--" + clientcmd.FlagCAFile + "=/cafile", "--" + clientcmd.FlagInsecure + "=false"},
|
||||||
startingConfig: startingConfig,
|
startingConfig: startingConfig,
|
||||||
expectedConfig: expectedConfig,
|
expectedConfig: expectedConfig,
|
||||||
}
|
}
|
||||||
@ -547,10 +551,10 @@ func TestCAAndInsecureDisallowed(t *testing.T) {
|
|||||||
func TestMergeExistingAuth(t *testing.T) {
|
func TestMergeExistingAuth(t *testing.T) {
|
||||||
expectedConfig := newRedFederalCowHammerConfig()
|
expectedConfig := newRedFederalCowHammerConfig()
|
||||||
authInfo := expectedConfig.AuthInfos["red-user"]
|
authInfo := expectedConfig.AuthInfos["red-user"]
|
||||||
authInfo.ClientKey = "key"
|
authInfo.ClientKey = "/key"
|
||||||
expectedConfig.AuthInfos["red-user"] = authInfo
|
expectedConfig.AuthInfos["red-user"] = authInfo
|
||||||
test := configCommandTest{
|
test := configCommandTest{
|
||||||
args: []string{"set-credentials", "red-user", "--" + clientcmd.FlagKeyFile + "=key"},
|
args: []string{"set-credentials", "red-user", "--" + clientcmd.FlagKeyFile + "=/key"},
|
||||||
startingConfig: newRedFederalCowHammerConfig(),
|
startingConfig: newRedFederalCowHammerConfig(),
|
||||||
expectedConfig: expectedConfig,
|
expectedConfig: expectedConfig,
|
||||||
}
|
}
|
||||||
@ -574,12 +578,12 @@ func TestAdditionalCluster(t *testing.T) {
|
|||||||
expectedConfig := newRedFederalCowHammerConfig()
|
expectedConfig := newRedFederalCowHammerConfig()
|
||||||
cluster := clientcmdapi.NewCluster()
|
cluster := clientcmdapi.NewCluster()
|
||||||
cluster.APIVersion = testapi.Version()
|
cluster.APIVersion = testapi.Version()
|
||||||
cluster.CertificateAuthority = "ca-location"
|
cluster.CertificateAuthority = "/ca-location"
|
||||||
cluster.InsecureSkipTLSVerify = false
|
cluster.InsecureSkipTLSVerify = false
|
||||||
cluster.Server = "serverlocation"
|
cluster.Server = "serverlocation"
|
||||||
expectedConfig.Clusters["different-cluster"] = cluster
|
expectedConfig.Clusters["different-cluster"] = cluster
|
||||||
test := configCommandTest{
|
test := configCommandTest{
|
||||||
args: []string{"set-cluster", "different-cluster", "--" + clientcmd.FlagAPIServer + "=serverlocation", "--" + clientcmd.FlagInsecure + "=false", "--" + clientcmd.FlagCAFile + "=ca-location", "--" + clientcmd.FlagAPIVersion + "=" + testapi.Version()},
|
args: []string{"set-cluster", "different-cluster", "--" + clientcmd.FlagAPIServer + "=serverlocation", "--" + clientcmd.FlagInsecure + "=false", "--" + clientcmd.FlagCAFile + "=/ca-location", "--" + clientcmd.FlagAPIVersion + "=" + testapi.Version()},
|
||||||
startingConfig: newRedFederalCowHammerConfig(),
|
startingConfig: newRedFederalCowHammerConfig(),
|
||||||
expectedConfig: expectedConfig,
|
expectedConfig: expectedConfig,
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -115,7 +116,7 @@ func (o createAuthInfoOptions) run() error {
|
|||||||
authInfo := o.modifyAuthInfo(*startingStanza)
|
authInfo := o.modifyAuthInfo(*startingStanza)
|
||||||
config.AuthInfos[o.name] = &authInfo
|
config.AuthInfos[o.name] = &authInfo
|
||||||
|
|
||||||
if err := ModifyConfig(o.configAccess, *config); err != nil {
|
if err := ModifyConfig(o.configAccess, *config, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +135,7 @@ func (o *createAuthInfoOptions) modifyAuthInfo(existingAuthInfo clientcmdapi.Aut
|
|||||||
modifiedAuthInfo.ClientCertificateData, _ = ioutil.ReadFile(certPath)
|
modifiedAuthInfo.ClientCertificateData, _ = ioutil.ReadFile(certPath)
|
||||||
modifiedAuthInfo.ClientCertificate = ""
|
modifiedAuthInfo.ClientCertificate = ""
|
||||||
} else {
|
} else {
|
||||||
|
certPath, _ = filepath.Abs(certPath)
|
||||||
modifiedAuthInfo.ClientCertificate = certPath
|
modifiedAuthInfo.ClientCertificate = certPath
|
||||||
if len(modifiedAuthInfo.ClientCertificate) > 0 {
|
if len(modifiedAuthInfo.ClientCertificate) > 0 {
|
||||||
modifiedAuthInfo.ClientCertificateData = nil
|
modifiedAuthInfo.ClientCertificateData = nil
|
||||||
@ -146,6 +148,7 @@ func (o *createAuthInfoOptions) modifyAuthInfo(existingAuthInfo clientcmdapi.Aut
|
|||||||
modifiedAuthInfo.ClientKeyData, _ = ioutil.ReadFile(keyPath)
|
modifiedAuthInfo.ClientKeyData, _ = ioutil.ReadFile(keyPath)
|
||||||
modifiedAuthInfo.ClientKey = ""
|
modifiedAuthInfo.ClientKey = ""
|
||||||
} else {
|
} else {
|
||||||
|
keyPath, _ = filepath.Abs(keyPath)
|
||||||
modifiedAuthInfo.ClientKey = keyPath
|
modifiedAuthInfo.ClientKey = keyPath
|
||||||
if len(modifiedAuthInfo.ClientKey) > 0 {
|
if len(modifiedAuthInfo.ClientKey) > 0 {
|
||||||
modifiedAuthInfo.ClientKeyData = nil
|
modifiedAuthInfo.ClientKeyData = nil
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ func (o createClusterOptions) run() error {
|
|||||||
cluster := o.modifyCluster(*startingStanza)
|
cluster := o.modifyCluster(*startingStanza)
|
||||||
config.Clusters[o.name] = &cluster
|
config.Clusters[o.name] = &cluster
|
||||||
|
|
||||||
if err := ModifyConfig(o.configAccess, *config); err != nil {
|
if err := ModifyConfig(o.configAccess, *config, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +134,7 @@ func (o *createClusterOptions) modifyCluster(existingCluster clientcmdapi.Cluste
|
|||||||
modifiedCluster.InsecureSkipTLSVerify = false
|
modifiedCluster.InsecureSkipTLSVerify = false
|
||||||
modifiedCluster.CertificateAuthority = ""
|
modifiedCluster.CertificateAuthority = ""
|
||||||
} else {
|
} else {
|
||||||
|
caPath, _ = filepath.Abs(caPath)
|
||||||
modifiedCluster.CertificateAuthority = caPath
|
modifiedCluster.CertificateAuthority = caPath
|
||||||
// Specifying a certificate authority file clears certificate authority data and insecure mode
|
// Specifying a certificate authority file clears certificate authority data and insecure mode
|
||||||
if caPath != "" {
|
if caPath != "" {
|
||||||
|
@ -88,7 +88,7 @@ func (o createContextOptions) run() error {
|
|||||||
context := o.modifyContext(*startingStanza)
|
context := o.modifyContext(*startingStanza)
|
||||||
config.Contexts[o.name] = &context
|
config.Contexts[o.name] = &context
|
||||||
|
|
||||||
if err := ModifyConfig(o.configAccess, *config); err != nil {
|
if err := ModifyConfig(o.configAccess, *config, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ func (o setOptions) run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ModifyConfig(o.configAccess, *config); err != nil {
|
if err := ModifyConfig(o.configAccess, *config, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ func (o unsetOptions) run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ModifyConfig(o.configAccess, *config); err != nil {
|
if err := ModifyConfig(o.configAccess, *config, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ func (o useContextOptions) run() error {
|
|||||||
|
|
||||||
config.CurrentContext = o.contextName
|
config.CurrentContext = o.contextName
|
||||||
|
|
||||||
if err := ModifyConfig(o.configAccess, *config); err != nil {
|
if err := ModifyConfig(o.configAccess, *config, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user