Merge pull request #15828 from justinsb/dont_rely_on_kubectl

Don't rely on kubectl being installed
This commit is contained in:
Kubernetes Prow Robot 2023-08-27 21:03:21 -07:00 committed by GitHub
commit 75eb720f3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 102 deletions

View File

@ -37,7 +37,6 @@ import (
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup" "k8s.io/kops/upup/pkg/fi/cloudup"
"k8s.io/kops/upup/pkg/fi/utils" "k8s.io/kops/upup/pkg/fi/utils"
"k8s.io/kops/upup/pkg/kutil"
"k8s.io/kubectl/pkg/util/i18n" "k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates" "k8s.io/kubectl/pkg/util/templates"
) )
@ -313,12 +312,12 @@ func RunUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Up
firstRun := false firstRun := false
if !isDryrun && c.CreateKubecfg { if !isDryrun && c.CreateKubecfg {
hasKubecfg, err := hasKubecfg(cluster.ObjectMeta.Name) hasKubeconfig, err := clusterIsInKubeConfig(cluster.ObjectMeta.Name)
if err != nil { if err != nil {
klog.Warningf("error reading kubecfg: %v", err) klog.Warningf("error reading kubeconfig: %v", err)
hasKubecfg = true hasKubeconfig = true
} }
firstRun = !hasKubecfg firstRun = !hasKubeconfig
klog.Infof("Exporting kubeconfig for cluster") klog.Infof("Exporting kubeconfig for cluster")
@ -439,19 +438,21 @@ func findBastionPublicName(c *kops.Cluster) string {
return bastion.PublicName return bastion.PublicName
} }
func hasKubecfg(contextName string) (bool, error) { // clusterIsInKubeConfig checks if we have a context with the specified name (cluster name) in ~/.kube/config.
kubectl := &kutil.Kubectl{} // It is used as a check to see if this is (likely) a new cluster.
func clusterIsInKubeConfig(contextName string) (bool, error) {
config, err := kubectl.GetConfig(false) configAccess := clientcmd.NewDefaultPathOptions()
config, err := configAccess.GetStartingConfig()
if err != nil { if err != nil {
return false, fmt.Errorf("error getting config from kubectl: %v", err) return false, fmt.Errorf("error reading kubeconfig: %w", err)
} }
for _, context := range config.Contexts { for k := range config.Contexts {
if context.Name == contextName { if k == contextName {
return true, nil return true, nil
} }
} }
return false, nil return false, nil
} }

View File

@ -1,90 +0,0 @@
/*
Copyright 2019 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 kutil
import (
"bytes"
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
"k8s.io/klog/v2"
"k8s.io/kops/pkg/kubeconfig"
)
type Kubectl struct {
KubectlPath string
}
func (k *Kubectl) GetConfig(minify bool) (*kubeconfig.KubectlConfig, error) {
output := "json"
// TODO: --context doesn't seem to work
args := []string{"config", "view"}
if minify {
args = append(args, "--minify")
}
if output != "" {
args = append(args, "--output", output)
}
configString, _, err := k.execKubectl(args...)
if err != nil {
return nil, err
}
configString = strings.TrimSpace(configString)
klog.V(8).Infof("config = %q", configString)
config := &kubeconfig.KubectlConfig{}
err = json.Unmarshal([]byte(configString), config)
if err != nil {
return nil, fmt.Errorf("cannot parse current config from kubectl: %v", err)
}
return config, nil
}
func (k *Kubectl) execKubectl(args ...string) (string, string, error) {
kubectlPath := k.KubectlPath
if kubectlPath == "" {
kubectlPath = "kubectl" // Assume in PATH
}
cmd := exec.Command(kubectlPath, args...)
env := os.Environ()
cmd.Env = env
var stdout bytes.Buffer
cmd.Stdout = &stdout
var stderr bytes.Buffer
cmd.Stderr = &stderr
human := strings.Join(cmd.Args, " ")
klog.V(2).Infof("Running command: %s", human)
err := cmd.Run()
if err != nil {
klog.Infof("error running %s", human)
klog.Info(stdout.String())
klog.Info(stderr.String())
return stdout.String(), stderr.String(), fmt.Errorf("error running kubectl: %v", err)
}
return stdout.String(), stderr.String(), err
}