Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added update-context and kubeconfig to status #1578

Merged
merged 1 commit into from
Jun 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions cmd/minikube/cmd/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ import (
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/constants"
kcfg "k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/machine"
)

var statusFormat string

type Status struct {
MinikubeStatus string
LocalkubeStatus string
MinikubeStatus string
LocalkubeStatus string
KubeconfigStatus string
}

// statusCmd represents the status command
Expand All @@ -57,14 +59,32 @@ var statusCmd = &cobra.Command{
}

ls := state.None.String()
ks := state.None.String()
if ms == state.Running.String() {
ls, err = cluster.GetLocalkubeStatus(api)
if err != nil {
glog.Errorln("Error localkube status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
ip, err := cluster.GetHostDriverIP(api)
if err != nil {
glog.Errorln("Error host driver ip status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
kstatus, err := kcfg.GetKubeConfigStatus(ip, constants.KubeconfigPath)
if err != nil {
glog.Errorln("Error kubeconfig status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
if kstatus {
ks = "Correctly Configured: pointing to minikube-vm at " + ip.String()
} else {
ks = "Misconfigured: pointing to stale minikube-vm." +
"\nTo fix the kubectl context, run minikube update-context"
}
}
status := Status{ms, ls}

status := Status{ms, ls, ks}

tmpl, err := template.New("status").Parse(statusFormat)
if err != nil {
Expand Down
66 changes: 66 additions & 0 deletions cmd/minikube/cmd/update-context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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 cmd

import (
"fmt"
"os"

"github.com/golang/glog"
"github.com/spf13/cobra"
cmdUtil "k8s.io/minikube/cmd/util"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/constants"
kcfg "k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/machine"
)

// updateContextCmd represents the update-context command
var updateContextCmd = &cobra.Command{
Use: "update-context",
Short: "Verify the IP address of the running cluster in kubeconfig.",
Long: `Retrieves the IP address of the running cluster, checks it
with IP in kubeconfig, and corrects kubeconfig if incorrect.`,
Run: func(cmd *cobra.Command, args []string) {
api, err := machine.NewAPIClient(clientType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once #1544 is merged, this will become machine.NewAPIClient()

if err != nil {
fmt.Fprintf(os.Stderr, "Error getting client: %s\n", err)
os.Exit(1)
}
defer api.Close()
ip, err := cluster.GetHostDriverIP(api)
if err != nil {
glog.Errorln("Error host driver ip status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
kstatus, err := kcfg.UpdateKubeconfigIP(ip, constants.KubeconfigPath)
if err != nil {
glog.Errorln("Error kubeconfig status:", err)
cmdUtil.MaybeReportErrorAndExit(err)
}
if kstatus {
fmt.Println("Reconfigured kubeconfig IP, now pointing at " + ip.String())
} else {
fmt.Println("Kubeconfig IP correctly configured, pointing at " + ip.String())
}

},
}

func init() {
RootCmd.AddCommand(updateContextCmd)
}
18 changes: 18 additions & 0 deletions pkg/minikube/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,24 @@ func GetLocalkubeStatus(api libmachine.API) (string, error) {
}
}

// GetHostDriverIP gets the ip address of the current minikube cluster
func GetHostDriverIP(api libmachine.API) (net.IP, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I can't believe we didn't have something like this before. Out of scope for this PR, but we might want to consider moving some of our other functions that just call Driver.GetIP() directly to use this, so we can pass around a real net.IP struct.

host, err := CheckIfApiExistsAndLoad(api)
if err != nil {
return nil, err
}

ipStr, err := host.Driver.GetIP()
if err != nil {
return nil, errors.Wrap(err, "Error getting IP")
}
ip := net.ParseIP(ipStr)
if ip == nil {
return nil, errors.Wrap(err, "Error parsing IP")
}
return ip, nil
}

// StartCluster starts a k8s cluster on the specified Host.
func StartCluster(api libmachine.API, kubernetesConfig KubernetesConfig) error {
h, err := CheckIfApiExistsAndLoad(api)
Expand Down
2 changes: 1 addition & 1 deletion pkg/minikube/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const (
MinimumDiskSizeMB = 2000
DefaultVMDriver = "virtualbox"
DefaultStatusFormat = "minikube: {{.MinikubeStatus}}\n" +
"localkube: {{.LocalkubeStatus}}\n"
"localkube: {{.LocalkubeStatus}}\n" + "kubectl: {{.KubeconfigStatus}}\n"
DefaultAddonListFormat = "- {{.AddonName}}: {{.AddonStatus}}\n"
DefaultConfigViewFormat = "- {{.ConfigKey}}: {{.ConfigValue}}\n"
GithubMinikubeReleasesURL = "https://storage.googleapis.com/minikube/releases.json"
Expand Down
71 changes: 71 additions & 0 deletions pkg/minikube/kubeconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,22 @@ limitations under the License.
package kubeconfig

import (
"fmt"
"io/ioutil"
"net"
"net/url"
"os"
"path/filepath"
"strconv"
"sync/atomic"

"github.com/golang/glog"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/tools/clientcmd/api/latest"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
)

type KubeConfigSetup struct {
Expand Down Expand Up @@ -178,3 +184,68 @@ func decode(data []byte) (*api.Config, error) {

return config.(*api.Config), nil
}

// GetKubeConfigStatus verifys the ip stored in kubeconfig.
func GetKubeConfigStatus(ip net.IP, filename string) (bool, error) {
if ip == nil {
return false, fmt.Errorf("Error, empty ip passed")
}
kip, err := getIPFromKubeConfig(filename)
if err != nil {
return false, err
}
if kip.Equal(ip) {
return true, nil
}
// Kubeconfig IP misconfigured
return false, nil

}

// UpdateKubeconfigIP overwrites the IP stored in kubeconfig with the provided IP.
func UpdateKubeconfigIP(ip net.IP, filename string) (bool, error) {
if ip == nil {
return false, fmt.Errorf("Error, empty ip passed")
}
kip, err := getIPFromKubeConfig(filename)
if err != nil {
return false, err
}
if kip.Equal(ip) {
return false, nil
}
con, err := ReadConfigOrNew(filename)
if err != nil {
return false, errors.Wrap(err, "Error getting kubeconfig status")
}
// Safe to lookup server because if field non-existent getIPFromKubeconfig would have given an error
con.Clusters[cfg.GetMachineName()].Server = "https://" + ip.String() + ":" + strconv.Itoa(constants.APIServerPort)
err = WriteConfig(con, filename)
if err != nil {
return false, err
}
// Kubeconfig IP reconfigured
return true, nil
}

// getIPFromKubeConfig returns the IP address stored for minikube in the kubeconfig specified
func getIPFromKubeConfig(filename string) (net.IP, error) {
con, err := ReadConfigOrNew(filename)
if err != nil {
return nil, errors.Wrap(err, "Error getting kubeconfig status")
}
cluster, ok := con.Clusters[cfg.GetMachineName()]
if !ok {
return nil, errors.Errorf("Kubeconfig does not have a record of the machine cluster")
}
kurl, err := url.Parse(cluster.Server)
if err != nil {
return net.ParseIP(cluster.Server), nil
}
kip, _, err := net.SplitHostPort(kurl.Host)
if err != nil {
return net.ParseIP(kurl.Host), nil
}
ip := net.ParseIP(kip)
return ip, nil
}
Loading