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

WIP: Add support for EKS #12

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 4 additions & 4 deletions cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"os"

"github.com/spf13/cobra"
"github.com/thecasualcoder/kube-tmuxp/pkg/commander"
"github.com/thecasualcoder/kube-tmuxp/pkg/filesystem"
"github.com/thecasualcoder/kube-tmuxp/pkg/kubeconfig"
"github.com/thecasualcoder/kube-tmuxp/pkg/kubetmuxp"
"github.com/jfreeland/kube-tmuxp/pkg/commander"
Copy link
Member

Choose a reason for hiding this comment

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

Imports should not be changed. Can we keep it as before ?

Copy link
Author

@jfreeland jfreeland Mar 4, 2020

Choose a reason for hiding this comment

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

Doh! Sorry about that.

I could certainly change this and check it in as-is, but I wasn't sure if this really matched how you would want to approach this? If so, I'll clean up and push.

I think I had in mind that I should go back and by default specify that default provider is gke if no provider is specified so that it's backwards compatible.

But then again I started thinking there might be another/better ways to do this if you wanted to also add other providers.

At the time, I just did what I needed to scratch my specific itch. :)

Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

I've not seen the full code. Will have a look and let you know soon

"github.com/jfreeland/kube-tmuxp/pkg/filesystem"
"github.com/jfreeland/kube-tmuxp/pkg/kubeconfig"
"github.com/jfreeland/kube-tmuxp/pkg/kubetmuxp"
)

var generateCmd = &cobra.Command{
Expand Down
18 changes: 16 additions & 2 deletions config.sample.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
projects:
- name: gcp-project-id
provider: gke
clusters:
- name: gke-cluster-name
zone: zone # for zonal GKE clusters
region: region # for regional GKE clusters
context: name-to-be-used-for-this-context
envs:
tmux_envs:
ENV_VARIABLE: value
provider_envs:
ENV_VARIABLE: value
- name: aws-project-id
provider: eks
clusters:
- name: eks-cluster-name
region: region
context: name-to-be-used-for-this-context
tmux_envs:
AWS_PROFILE: profile-to-use-in-tmux
ENV_VARIABLE: value
provider_envs:
AWS_PROFILE: profile-to-use-to-config-kubectl
ENV_VARIABLE: value

3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/thecasualcoder/kube-tmuxp
module github.com/jfreeland/kube-tmuxp

go 1.13

Expand All @@ -8,5 +8,6 @@ require (
github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.5.0
github.com/stretchr/testify v1.2.2
github.com/thecasualcoder/kube-tmuxp v0.2.6 // indirect
gopkg.in/yaml.v2 v2.2.7
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/thecasualcoder/kube-tmuxp v0.2.6 h1:6mdNJ5aCoo2m/nkNcTCpEHaPqv5aHCo/ruiqWH1iQ7s=
github.com/thecasualcoder/kube-tmuxp v0.2.6/go.mod h1:zdbqLwPvGa0KQU+55ccIbW1T1SxpQWdrZHXyR1xg9nQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package main

import "github.com/thecasualcoder/kube-tmuxp/cmd"
import "github.com/jfreeland/kube-tmuxp/cmd"

var version string

Expand Down
2 changes: 1 addition & 1 deletion pkg/commander/commander_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/thecasualcoder/kube-tmuxp/pkg/commander"
"github.com/jfreeland/kube-tmuxp/pkg/commander"
)

func TestExecute(t *testing.T) {
Expand Down
55 changes: 49 additions & 6 deletions pkg/kubeconfig/kubeconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"os"
"path"

"github.com/thecasualcoder/kube-tmuxp/pkg/commander"
"github.com/thecasualcoder/kube-tmuxp/pkg/filesystem"
"github.com/jfreeland/kube-tmuxp/pkg/commander"
"github.com/jfreeland/kube-tmuxp/pkg/filesystem"
)

// KubeConfig exposes methods to perform actions on kubeconfig
Expand All @@ -25,11 +25,54 @@ func (k *KubeConfig) Delete(kubeCfgFile string) error {
return nil
}

// AddRegionalCluster imports Kubernetes context for
// AddRegionalEKSCluster imports Kubernetes context for a regional EKS cluster
func (k *KubeConfig) AddRegionalEKSCluster(cluster string, region string, role string, env map[string]string, kubeCfgFile string) error {
var args []string
if len(role) > 0 {
args = []string{
"eks",
"update-kubeconfig",
"--name",
cluster,
"--kubeconfig",
kubeCfgFile,
"--region",
region,
"--role-arn",
role,
}
} else {
args = []string{
"eks",
"update-kubeconfig",
"--name",
cluster,
"--kubeconfig",
kubeCfgFile,
"--region",
region,
}
}

envs := []string{}
for k, v := range env {
envs = append(envs, k+"="+v)
}
if _, err := k.commander.Execute("aws", args, envs); err != nil {
return err
}

return nil
}

// AddRegionalGKECluster imports Kubernetes context for
// a regional Kubernetes cluster
func (k *KubeConfig) AddRegionalCluster(project string, cluster string, region string, kubeCfgFile string) error {
func (k *KubeConfig) AddRegionalGKECluster(project string, cluster string, region string, kubeCfgFile string) error {
args := []string{
"beta",
// Is beta needed here? You can run into an issue where if
// you haven't updated gcloud lately, beta will stop and
// report that it needs updated, but gcloud itself will not.
"container",
"clusters",
"get-credentials",
Expand All @@ -47,9 +90,9 @@ func (k *KubeConfig) AddRegionalCluster(project string, cluster string, region s
return nil
}

// AddZonalCluster imports Kubernetes context for
// AddZonalGKECluster imports Kubernetes context for
// a zonal Kubernetes cluster
func (k *KubeConfig) AddZonalCluster(project string, cluster string, zone string, kubeCfgFile string) error {
func (k *KubeConfig) AddZonalGKECluster(project string, cluster string, zone string, kubeCfgFile string) error {
args := []string{
"container",
"clusters",
Expand Down
16 changes: 8 additions & 8 deletions pkg/kubeconfig/kubeconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/thecasualcoder/kube-tmuxp/pkg/internal/mock"
"github.com/thecasualcoder/kube-tmuxp/pkg/kubeconfig"
"github.com/jfreeland/kube-tmuxp/pkg/internal/mock"
"github.com/jfreeland/kube-tmuxp/pkg/kubeconfig"
)

func TestNew(t *testing.T) {
Expand Down Expand Up @@ -86,7 +86,7 @@ func TestDelete(t *testing.T) {
})
}

func TestAddRegionalCluster(t *testing.T) {
func TestAddRegionalGKECluster(t *testing.T) {
t.Run("should invoke command for adding regional cluster", func(*testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
Expand All @@ -110,7 +110,7 @@ func TestAddRegionalCluster(t *testing.T) {
mockCmdr.EXPECT().Execute("gcloud", args, envs).Return("Context added successfully", nil)

kubeCfg, _ := kubeconfig.New(mockFS, mockCmdr)
err := kubeCfg.AddRegionalCluster("test-project", "test-cluster", "test-region", "/Users/test/.kube/configs/test-context")
err := kubeCfg.AddRegionalGKECluster("test-project", "test-cluster", "test-region", "/Users/test/.kube/configs/test-context")

assert.Nil(t, err)
})
Expand Down Expand Up @@ -138,13 +138,13 @@ func TestAddRegionalCluster(t *testing.T) {
mockCmdr.EXPECT().Execute("gcloud", args, envs).Return("", fmt.Errorf("some error"))

kubeCfg, _ := kubeconfig.New(mockFS, mockCmdr)
err := kubeCfg.AddRegionalCluster("test-project", "test-cluster", "test-region", "/Users/test/.kube/configs/test-context")
err := kubeCfg.AddRegionalGKECluster("test-project", "test-cluster", "test-region", "/Users/test/.kube/configs/test-context")

assert.EqualError(t, err, "some error")
})
}

func TestAddZonalCluster(t *testing.T) {
func TestAddZonalGKECluster(t *testing.T) {
t.Run("should invoke command for adding zonal cluster", func(*testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
Expand All @@ -167,7 +167,7 @@ func TestAddZonalCluster(t *testing.T) {
mockCmdr.EXPECT().Execute("gcloud", args, envs).Return("Context added successfully", nil)

kubeCfg, _ := kubeconfig.New(mockFS, mockCmdr)
err := kubeCfg.AddZonalCluster("test-project", "test-cluster", "test-zone", "/Users/test/.kube/configs/test-context")
err := kubeCfg.AddZonalGKECluster("test-project", "test-cluster", "test-zone", "/Users/test/.kube/configs/test-context")

assert.Nil(t, err)
})
Expand All @@ -194,7 +194,7 @@ func TestAddZonalCluster(t *testing.T) {
mockCmdr.EXPECT().Execute("gcloud", args, envs).Return("", fmt.Errorf("some error"))

kubeCfg, _ := kubeconfig.New(mockFS, mockCmdr)
err := kubeCfg.AddZonalCluster("test-project", "test-cluster", "test-zone", "/Users/test/.kube/configs/test-context")
err := kubeCfg.AddZonalGKECluster("test-project", "test-cluster", "test-zone", "/Users/test/.kube/configs/test-context")

assert.EqualError(t, err, "some error")
})
Expand Down
84 changes: 61 additions & 23 deletions pkg/kubetmuxp/kubetmuxp.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,39 @@ import (
"io/ioutil"
"path"

"github.com/thecasualcoder/kube-tmuxp/pkg/filesystem"
"github.com/thecasualcoder/kube-tmuxp/pkg/kubeconfig"
"github.com/thecasualcoder/kube-tmuxp/pkg/tmuxp"
"github.com/jfreeland/kube-tmuxp/pkg/filesystem"
"github.com/jfreeland/kube-tmuxp/pkg/kubeconfig"
"github.com/jfreeland/kube-tmuxp/pkg/tmuxp"
yamlV2 "gopkg.in/yaml.v2"
)

// Envs reprensents environemnt variables
type Envs map[string]string
// Role represents a Role ARN required to connect to an EKS cluster
type Role string

// ProviderEnvs represents environment variables for the provider
type ProviderEnvs map[string]string

// Envs reprensents environemnt variables for Tmux
type TmuxEnvs map[string]string

//Cluster represents a Kubernetes cluster
type Cluster struct {
Name string `yaml:"name"`
Zone string `yaml:"zone"`
Region string `yaml:"region"`
Context string `yaml:"context"`
Envs `yaml:"envs"`
Name string `yaml:"name"`
Zone string `yaml:"zone"`
Region string `yaml:"region"`
Context string `yaml:"context"`
Role string `yaml:"role"`
TmuxEnvs `yaml:"tmux_envs"`
ProviderEnvs `yaml:"provider_envs"`
}

// DefaultEKSContextName returns default context name for EKS
func (c *Cluster) DefaultEKSContextName(project string) (string, error) {
return fmt.Sprintf("arn:aws:eks:%s:%s:cluster/%s", c.Region, project, c.Name), nil
}

// DefaultContextName returns default context name
func (c *Cluster) DefaultContextName(project string) (string, error) {
// DefaultGKEContextName returns default context name for GKE
func (c *Cluster) DefaultGKEContextName(project string) (string, error) {
if regional, err := c.IsRegional(); err != nil {
return "", err
} else if regional {
Expand Down Expand Up @@ -52,6 +65,7 @@ type Clusters []Cluster

//Project represents a cloud project
type Project struct {
Provider string `yaml:"provider"`
Name string `yaml:"name"`
Clusters `yaml:"clusters"`
}
Expand Down Expand Up @@ -88,7 +102,7 @@ func (c *Config) load(cfgFile string) error {
func (c *Config) saveTmuxpConfig(kubeCfgFile string, cluster Cluster) error {
windows := tmuxp.Windows{{Name: "default"}}
env := tmuxp.Environment{"KUBECONFIG": kubeCfgFile}
for k, v := range cluster.Envs {
for k, v := range cluster.TmuxEnvs {
env[k] = v
}

Expand All @@ -111,31 +125,55 @@ func (c *Config) Process() error {
for _, cluster := range project.Clusters {
kubeCfgFile := path.Join(kubeCfgsDir, cluster.Context)

if project.Provider == "" {
project.Provider = "gke"
}
fmt.Printf("Provider: %s\n", project.Provider)
fmt.Printf("Cluster: %s\n", cluster.Name)
fmt.Println("Deleting exisiting context...")
if err := c.kubeCfg.Delete(kubeCfgFile); err != nil {
return err
}

fmt.Println("Adding context...")
if regional, err := cluster.IsRegional(); err != nil {
return err
} else if regional {
if err := c.kubeCfg.AddRegionalCluster(project.Name, cluster.Name, cluster.Region, kubeCfgFile); err != nil {
if project.Provider == "gke" {
if regional, err := cluster.IsRegional(); err != nil {
return err
} else if regional {
if err := c.kubeCfg.AddRegionalGKECluster(project.Name, cluster.Name, cluster.Region, kubeCfgFile); err != nil {
return err
}
} else {
if err := c.kubeCfg.AddZonalGKECluster(project.Name, cluster.Name, cluster.Zone, kubeCfgFile); err != nil {
return err
}
}
} else {
if err := c.kubeCfg.AddZonalCluster(project.Name, cluster.Name, cluster.Zone, kubeCfgFile); err != nil {
} else if project.Provider == "eks" {
if regional, err := cluster.IsRegional(); err != nil {
return err
} else if regional {
if err := c.kubeCfg.AddRegionalEKSCluster(cluster.Name, cluster.Region, cluster.Role, cluster.ProviderEnvs, kubeCfgFile); err != nil {
return err
}
}
} else {
return fmt.Errorf("Provider must be gke or eks")
}

fmt.Println("Renaming context...")
defaultCtxName, err := cluster.DefaultContextName(project.Name)
if err != nil {
return err
if project.Provider == "gke" {
defaultCtxName, err := cluster.DefaultGKEContextName(project.Name)
if err != nil {
return err
}
c.kubeCfg.RenameContext(defaultCtxName, cluster.Context, kubeCfgFile)
} else if project.Provider == "eks" {
defaultCtxName, err := cluster.DefaultEKSContextName(project.Name)
if err != nil {
return err
}
c.kubeCfg.RenameContext(defaultCtxName, cluster.Context, kubeCfgFile)
}
c.kubeCfg.RenameContext(defaultCtxName, cluster.Context, kubeCfgFile)

fmt.Println("Creating tmuxp config...")
c.saveTmuxpConfig(kubeCfgFile, cluster)
Expand Down
Loading