Provide hints after update cluster

This should make kops more discoverable

Issue #166

Issue #263
This commit is contained in:
Justin Santa Barbara 2016-08-14 22:13:34 -04:00
parent 6ef55682b7
commit e778c792fe
4 changed files with 94 additions and 32 deletions

View File

@ -1,16 +0,0 @@
package main
type kubectlConfig struct {
Kind string `json:"kind`
ApiVersion string `json:"apiVersion`
Clusters []*kubectlClusterWithName `json:"clusters`
}
type kubectlClusterWithName struct {
Name string `json:"name`
Cluster kubectlCluster `json:"cluster`
}
type kubectlCluster struct {
Server string `json:"server`
}

View File

@ -5,7 +5,6 @@ import (
"fmt"
"os"
"encoding/json"
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@ -114,7 +113,7 @@ func (c *RootCmd) ClusterName() string {
return c.clusterName
}
func readKubectlClusterConfig() (*kubectlClusterWithName, error) {
func readKubectlClusterConfig() (*kutil.KubectlClusterWithName, error) {
kubectl := &kutil.Kubectl{}
context, err := kubectl.GetCurrentContext()
if err != nil {
@ -122,19 +121,13 @@ func readKubectlClusterConfig() (*kubectlClusterWithName, error) {
}
glog.V(4).Infof("context = %q", context)
configString, err := kubectl.GetConfig(true, "json")
config, err := kubectl.GetConfig(true)
if err != nil {
return nil, fmt.Errorf("error getting current config from kubectl: %v", err)
}
glog.V(8).Infof("config = %q", configString)
config := &kubectlConfig{}
err = json.Unmarshal([]byte(configString), config)
if err != nil {
return nil, fmt.Errorf("cannot parse current config from kubectl: %v", err)
}
if len(config.Clusters) != 1 {
// Minify should have done this
if len(config.Clusters) != 1 {
return nil, fmt.Errorf("expected exactly one cluster in kubectl config, found %d", len(config.Clusters))
}

View File

@ -134,6 +134,12 @@ func (c *UpdateClusterCmd) Run(args []string) error {
// TODO: Only if not yet set?
if !isDryrun {
hasKubecfg, err := hasKubecfg(cluster.Name)
if err != nil {
glog.Warningf("error reading kubecfg: %v", err)
hasKubecfg = true
}
keyStore := clusterRegistry.KeyStore(cluster.Name)
kubecfgCert, err := keyStore.FindCert("kubecfg")
@ -158,7 +164,35 @@ func (c *UpdateClusterCmd) Run(args []string) error {
} else {
glog.Infof("kubecfg cert not found; won't export kubecfg")
}
if !hasKubecfg {
// Assume initial creation
fmt.Printf("\n")
fmt.Printf("Cluster is starting. It should be ready in a few minutes.\n")
fmt.Printf("\n")
fmt.Printf("Suggestions:\n")
fmt.Printf(" * list nodes: kubectl get nodes --show-labels\n")
fmt.Printf(" * ssh to the master: ssh -i ~/.ssh/id_rsa admin@%s\n", cluster.Spec.MasterPublicName)
fmt.Printf(" * read about installing addons: https://github.com/kubernetes/kops/blob/master/docs/addons.md\n")
fmt.Printf("\n")
}
}
return nil
}
func hasKubecfg(contextName string) (bool, error) {
kubectl := &kutil.Kubectl{}
config, err := kubectl.GetConfig(false)
if err != nil {
return false, fmt.Errorf("error getting config from kubectl: %v", err)
}
for _, context := range config.Contexts {
if context.Name == contextName {
return true, nil
}
}
return false, nil
}

View File

@ -1,6 +1,7 @@
package kutil
import (
"encoding/json"
"fmt"
"github.com/golang/glog"
"os"
@ -21,7 +22,8 @@ func (k *Kubectl) GetCurrentContext() (string, error) {
return s, nil
}
func (k *Kubectl) GetConfig(minify bool, output string) (string, error) {
func (k *Kubectl) GetConfig(minify bool) (*KubectlConfig, error) {
output := "json"
// TODO: --context doesn't seem to work
args := []string{"config", "view"}
@ -33,12 +35,21 @@ func (k *Kubectl) GetConfig(minify bool, output string) (string, error) {
args = append(args, "--output", output)
}
s, err := k.execKubectl(args...)
configString, err := k.execKubectl(args...)
if err != nil {
return "", err
return nil, err
}
s = strings.TrimSpace(s)
return s, nil
configString = strings.TrimSpace(configString)
glog.V(8).Infof("config = %q", configString)
config := &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, error) {
@ -61,3 +72,43 @@ func (k *Kubectl) execKubectl(args ...string) (string, error) {
return string(output), err
}
type KubectlConfig struct {
Kind string `json:"kind"`
ApiVersion string `json:"apiVersion"`
CurrentContext string `json:"current-context"`
Clusters []*KubectlClusterWithName `json:"clusters"`
Contexts []*KubectlContextWithName `json:"contexts"`
Users []*KubectlUserWithName `json:"users"`
}
type KubectlClusterWithName struct {
Name string `json:"name"`
Cluster KubectlCluster `json:"cluster"`
}
type KubectlCluster struct {
Server string `json:"server"`
}
type KubectlContextWithName struct {
Name string `json:"name"`
Context KubectlContext `json:"context"`
}
type KubectlContext struct {
Cluster string `json:"cluster"`
User string `json:"user"`
}
type KubectlUserWithName struct {
Name string `json:"name"`
User KubectlUser `json:"user"`
}
type KubectlUser struct {
ClientCertificateData string `json:"client-certificate-data"`
ClientKeyData string `json:"client-key-data"`
Password string `json:"password"`
Username string `json:"username"`
}