-
-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
410 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package actions | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/guumaster/hostctl/pkg/file" | ||
"github.com/guumaster/hostctl/pkg/k8s/minikube" | ||
"github.com/guumaster/hostctl/pkg/profile" | ||
"github.com/guumaster/hostctl/pkg/types" | ||
) | ||
|
||
func newSyncMinikubeCmd(removeCmd *cobra.Command) *cobra.Command { | ||
return &cobra.Command{ | ||
Use: "minikube [profile] [flags]", | ||
Short: "Sync a minikube profile with a hostctl profile.", | ||
Long: ` | ||
Reads from Minikube the list of ingresses and add names and IPs to a profile in your hosts file. | ||
`, | ||
Args: commonCheckArgs, | ||
PreRunE: func(cmd *cobra.Command, _ []string) error { | ||
ns, _ := cmd.Flags().GetString("namespace") | ||
allNs, _ := cmd.Flags().GetBool("all-namespaces") | ||
|
||
if ns == "" && !allNs { | ||
return types.ErrKubernetesNamespace | ||
} | ||
return nil | ||
}, | ||
RunE: func(cmd *cobra.Command, profiles []string) error { | ||
src, _ := cmd.Flags().GetString("host-file") | ||
ns, _ := cmd.Flags().GetString("namespace") | ||
allNs, _ := cmd.Flags().GetBool("all-namespace") | ||
|
||
if allNs { | ||
ns = "" | ||
} | ||
|
||
profileName := profiles[0] | ||
|
||
mini, err := minikube.GetProfile(profileName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
p, err := profile.NewProfileFromMinikube(mini, ns) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
h, err := file.NewFile(src) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
p.Name = mini.Name | ||
p.Status = types.Enabled | ||
|
||
err = h.ReplaceProfile(p) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return h.Flush() | ||
}, | ||
PostRunE: func(cmd *cobra.Command, args []string) error { | ||
return postActionCmd(cmd, args, removeCmd, true) | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package k8s | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/guumaster/cligger" | ||
"k8s.io/client-go/kubernetes" | ||
"k8s.io/client-go/tools/clientcmd" | ||
) | ||
|
||
// NewClientset returns a new clienset to interact with Kubernetes | ||
func NewClientset() (*kubernetes.Clientset, error) { | ||
kubeConfigPath := filepath.Join(os.Getenv("HOME"), ".kube", "config") | ||
|
||
if fromEnv := os.Getenv("KUBECONFIG"); fromEnv != "" { | ||
kubeConfigPath = fromEnv | ||
cligger.Info("Using config from %s", kubeConfigPath) | ||
} | ||
|
||
// use the current context in kubeConfigPath | ||
kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath) | ||
if err != nil { | ||
return nil, cligger.Errorf("fatal error kubernetes config: %s", err) | ||
} | ||
|
||
// create the clientset | ||
clientset, err := kubernetes.NewForConfig(kubeConfig) | ||
if err != nil { | ||
return nil, cligger.Errorf("error with kubernetes config:", err) | ||
} | ||
|
||
return clientset, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package k8s | ||
|
||
import ( | ||
"net" | ||
|
||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/client-go/kubernetes" | ||
) | ||
|
||
// Ingress contains information about an ingress rule | ||
type Ingress struct { | ||
IP net.IP | ||
Hostname string | ||
} | ||
|
||
// GetIngresses returns a list of ingresses presents on a namespace | ||
func GetIngresses(cli *kubernetes.Clientset, ns string) ([]Ingress, error) { | ||
if ns == "" { | ||
ns = v1.NamespaceAll | ||
} | ||
|
||
ing, err := cli.ExtensionsV1beta1().Ingresses(ns).List(v1.ListOptions{}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var list []Ingress | ||
|
||
for _, i := range ing.Items { | ||
ip := i.Status.LoadBalancer.Ingress[0].IP | ||
|
||
for _, r := range i.Spec.Rules { | ||
list = append(list, Ingress{ | ||
IP: net.ParseIP(ip), | ||
Hostname: r.Host, | ||
}) | ||
} | ||
} | ||
|
||
return list, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package minikube | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"os/exec" | ||
) | ||
|
||
// Profile contains information about a minikube profile | ||
type Profile struct { | ||
Name string | ||
IP string | ||
Status Status | ||
Driver string | ||
|
||
IngressEnabled bool | ||
IngressDNSEnabled bool | ||
} | ||
|
||
// Status represents the current state of a profile | ||
type Status string | ||
|
||
const ( | ||
// Running status of minikube profile | ||
Running Status = "Running" | ||
) | ||
|
||
// GetProfile returns information about a minikube profile | ||
func GetProfile(name string) (*Profile, error) { | ||
mini, err := exec.LookPath("minikube") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
b := bytes.NewBufferString("") | ||
c := exec.Command(mini, "profile", "list", "-o", "json") | ||
c.Stdout = b | ||
|
||
err = c.Run() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
data, err := ioutil.ReadAll(b) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var m ProfileListResponse | ||
|
||
_ = json.Unmarshal(data, &m) | ||
|
||
var profile *Profile | ||
|
||
for _, p := range m.Valid { | ||
if p.Name == name { | ||
profile = &Profile{ | ||
Name: p.Name, | ||
IP: p.Config.Nodes[0].IP, | ||
Status: Status(p.Status), | ||
Driver: p.Config.Driver, | ||
} | ||
} | ||
} | ||
|
||
if profile == nil { | ||
return nil, fmt.Errorf("can't find profile '%s' on minikube", name) | ||
} | ||
|
||
b = bytes.NewBufferString("") | ||
c = exec.Command(mini, "addons", "list", "-o", "json", "-p", profile.Name) | ||
c.Stdout = b | ||
|
||
err = c.Run() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
data, err = ioutil.ReadAll(b) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var a *AddonsResponse | ||
|
||
_ = json.Unmarshal(data, &a) | ||
|
||
if a == nil { | ||
return profile, nil | ||
} | ||
|
||
profile.IngressDNSEnabled = a.IngressDNS.Status == "enabled" | ||
profile.IngressEnabled = a.Ingress.Status == "enabled" | ||
|
||
return profile, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package minikube | ||
|
||
// ProfileListResponse represents the json response of `minikube profile list` | ||
type ProfileListResponse struct { | ||
Valid []struct { | ||
Config struct { | ||
Driver string `json:"Driver"` | ||
Name string `json:"Name"` | ||
Nodes []struct { | ||
IP string `json:"IP"` | ||
Name string `json:"Name"` | ||
} `json:"Nodes"` | ||
} `json:"Config"` | ||
Name string `json:"Name"` | ||
Status string `json:"Status"` | ||
} `json:"valid"` | ||
} | ||
|
||
// AddonsResponse represents the json response of `minikube addons list` | ||
type AddonsResponse struct { | ||
Ingress struct { | ||
Status string `json:"Status"` | ||
} `json:"ingress"` | ||
IngressDNS struct { | ||
Status string `json:"Status"` | ||
} `json:"ingress-dns"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package profile | ||
|
||
import ( | ||
"github.com/guumaster/hostctl/pkg/k8s" | ||
"github.com/guumaster/hostctl/pkg/k8s/minikube" | ||
"github.com/guumaster/hostctl/pkg/types" | ||
) | ||
|
||
// NewProfileFromMinikube creates a new profile from a minikube profile and k8s namespace | ||
func NewProfileFromMinikube(mini *minikube.Profile, ns string) (*types.Profile, error) { | ||
if mini.Status != minikube.Running { | ||
return nil, types.ErrMinikubeStatus | ||
} | ||
|
||
if !mini.IngressEnabled { | ||
return nil, types.ErrMinikubeIngress | ||
} | ||
|
||
cli, err := k8s.NewClientset() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
list, err := k8s.GetIngresses(cli, ns) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
p := &types.Profile{} | ||
|
||
for _, in := range list { | ||
p.AddRoute(types.NewRoute(in.IP.String(), in.Hostname)) | ||
} | ||
|
||
return p, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters