check if context is invalid during update-context

pull/15032/head
Steven Powell 2022-09-28 16:35:10 -07:00
parent a86a9dfc69
commit be4ee85d64
2 changed files with 132 additions and 18 deletions

View File

@ -103,13 +103,32 @@ func Endpoint(contextName string, configPath ...string) (string, int, error) {
return u.Hostname(), port, nil
}
// verifyKubeconfig verifies that the cluster and context entries in the kubeconfig are valid
func verifyKubeconfig(contextName string, hostname string, port int, configPath ...string) error {
if err := VerifyEndpoint(contextName, hostname, port, configPath...); err != nil {
return err
}
path := PathFromEnv()
if configPath != nil {
path = configPath[0]
}
apiCfg, err := readOrNew(path)
if err != nil {
return errors.Wrap(err, "read")
}
if _, ok := apiCfg.Contexts[contextName]; !ok {
return errors.Errorf("%q does not appear in %s", contextName, path)
}
return nil
}
// UpdateEndpoint overwrites the IP stored in kubeconfig with the provided IP.
func UpdateEndpoint(contextName string, hostname string, port int, confpath string, ext *Extension) (bool, error) {
if hostname == "" {
return false, fmt.Errorf("empty ip")
}
err := VerifyEndpoint(contextName, hostname, port, confpath)
err := verifyKubeconfig(contextName, hostname, port, confpath)
if err == nil {
return false, nil
}
@ -122,8 +141,8 @@ func UpdateEndpoint(contextName string, hostname string, port int, confpath stri
address := "https://" + hostname + ":" + strconv.Itoa(port)
// if the cluster setting is missed in the kubeconfig, create new one
if _, ok := cfg.Clusters[contextName]; !ok {
// if the cluster or context setting is missing in the kubeconfig, create it
if configNeedsRepair(contextName, cfg) {
klog.Infof("%q context is missing from %s - will repair!", contextName, confpath)
lp := localpath.Profile(contextName)
gp := localpath.MiniPath()
@ -154,6 +173,16 @@ func UpdateEndpoint(contextName string, hostname string, port int, confpath stri
return true, nil
}
func configNeedsRepair(contextName string, cfg *api.Config) bool {
if _, ok := cfg.Clusters[contextName]; !ok {
return true
}
if _, ok := cfg.Contexts[contextName]; !ok {
return true
}
return false
}
// writeToFile encodes the configuration and writes it to the given file.
// If the file exists, it's contents will be overwritten.
func writeToFile(config runtime.Object, configPath ...string) error {

View File

@ -94,14 +94,14 @@ clusters:
name: minikube
contexts:
- context:
cluster: la-croix
user: la-croix
name: la-croix
current-context: la-croix
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: la-croix
- name: minikube
user:
client-certificate: /home/la-croix/apiserver.crt
client-key: /home/la-croix/apiserver.key
@ -116,14 +116,14 @@ clusters:
name: minikube
contexts:
- context:
cluster: la-croix
user: la-croix
name: la-croix
current-context: la-croix
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: la-croix
- name: minikube
user:
client-certificate: /home/la-croix/apiserver.crt
client-key: /home/la-croix/apiserver.key
@ -138,14 +138,14 @@ clusters:
name: minikube
contexts:
- context:
cluster: la-croix
user: la-croix
name: la-croix
current-context: la-croix
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: la-croix
- name: minikube
user:
client-certificate: /home/la-croix/apiserver.crt
client-key: /home/la-croix/apiserver.key
@ -182,6 +182,70 @@ users:
client-key: /home/la-croix/.minikube/profiles/minikube/client.key
`)
var kubeConfigMissingContext = []byte(`
apiVersion: v1
clusters:
- cluster:
certificate-authority: /home/la-croix/apiserver.crt
server: https://192.168.10.100:8443
name: la-croix
- cluster:
certificate-authority: /home/la-croix/.minikube/ca.crt
server: https://192.168.10.100:8080
name: minikube
contexts:
- context:
cluster: la-croix
user: la-croix
name: la-croix
current-context: la-croix
kind: Config
preferences: {}
users:
- name: la-croix
user:
client-certificate: /home/la-croix/apiserver.crt
client-key: /home/la-croix/apiserver.key
- name: minikube
user:
client-certificate: /home/la-croix/.minikube/profiles/minikube/client.crt
client-key: /home/la-croix/.minikube/profiles/minikube/client.key
`)
var kubeConfigFixedContext = []byte(`
apiVersion: v1
clusters:
- cluster:
certificate-authority: /home/la-croix/apiserver.crt
server: https://192.168.10.100:8443
name: la-croix
- cluster:
certificate-authority: /home/la-croix/.minikube/ca.crt
server: https://192.168.10.100:8080
name: minikube
contexts:
- context:
cluster: la-croix
user: la-croix
name: la-croix
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: la-croix
user:
client-certificate: /home/la-croix/apiserver.crt
client-key: /home/la-croix/apiserver.key
- name: minikube
user:
client-certificate: /home/la-croix/.minikube/profiles/minikube/client.crt
client-key: /home/la-croix/.minikube/profiles/minikube/client.key
`)
func TestUpdate(t *testing.T) {
setupCfg := &Settings{
ClusterName: "test",
@ -427,6 +491,27 @@ func TestUpdateIP(t *testing.T) {
}
}
func TestMissingContext(t *testing.T) {
t.Parallel()
os.Setenv(localpath.MinikubeHome, "/home/la-croix")
configFilename := tempFile(t, kubeConfigMissingContext)
defer os.Remove(configFilename)
if _, err := UpdateEndpoint("minikube", "192.168.10.100", 8080, configFilename, nil); err != nil {
t.Fatal(err)
}
actual, err := readOrNew(configFilename)
if err != nil {
t.Fatal(err)
}
expected, err := decode(kubeConfigFixedContext)
if err != nil {
t.Fatal(err)
}
if !configEquals(actual, expected) {
t.Fatalf("configs did not match: Actual:\n%+v\n Expected:\n%+v", actual, expected)
}
}
func TestEmptyConfig(t *testing.T) {
tmp := tempFile(t, []byte{})
defer os.Remove(tmp)