Skip to content

Commit

Permalink
fix(drift): correctly support kube context and kubeconfig
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime1907 committed Sep 26, 2023
1 parent 6eba848 commit af4f3f6
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 46 deletions.
11 changes: 11 additions & 0 deletions cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/spf13/cobra"
)

var envSettings *EnvSettings

func getRootCommand() *cobra.Command {
rootCommand := &cobra.Command{
Use: "drift [command]",
Expand All @@ -24,6 +26,7 @@ func getRootCommand() *cobra.Command {
},
}
rootCommand.SetUsageTemplate(getUsageTemplate())
envSettings = envSettings.New()

return rootCommand
}
Expand All @@ -50,6 +53,10 @@ func getRunCommand() *cobra.Command {
drifts.SetWriter(os.Stdout)
cmd.SilenceUsage = true

drifts.SetKubeConfig(envSettings.KubeConfig)
drifts.SetKubeContext(envSettings.KubeContext)
drifts.SetNamespace(envSettings.Namespace)

drifts.SetRelease(args[0])
if !drifts.FromRelease {
drifts.SetChart(args[1])
Expand Down Expand Up @@ -88,6 +95,10 @@ Do note that this is expensive operation since multiple kubectl command would be
drifts.SetWriter(os.Stdout)
cmd.SilenceUsage = true

drifts.SetKubeConfig(envSettings.KubeConfig)
drifts.SetKubeContext(envSettings.KubeContext)
drifts.SetNamespace(envSettings.Namespace)

if !drifts.SkipValidation {
if !drifts.ValidatePrerequisite() {
return &errors.PreValidationError{Message: "validation failed, please install prerequisites to identify drifts"}
Expand Down
25 changes: 25 additions & 0 deletions cmd/settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cmd

import (
"os"

"github.com/spf13/pflag"
)

type EnvSettings struct {
KubeConfig string
KubeContext string
Namespace string
}

func (s *EnvSettings) New() *EnvSettings {
envSettings := EnvSettings{
Namespace: os.Getenv("HELM_NAMESPACE"),
KubeContext: os.Getenv("HELM_KUBECONTEXT"),
KubeConfig: os.Getenv("KUBECONFIG"),
}
return &envSettings
}

func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/olekukonko/tablewriter v0.0.5
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.6.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.2
github.com/thoas/go-funk v0.9.3
gopkg.in/yaml.v3 v3.0.1
Expand Down Expand Up @@ -99,7 +100,6 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
Expand Down
8 changes: 1 addition & 7 deletions pkg/command/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@ import (
log "github.com/sirupsen/logrus"
)

const (
HelmContext = "HELM_KUBECONTEXT"
HelmNamespace = "HELM_NAMESPACE"
KubeConfig = "KUBECONFIG"
)

// Exec implements methods that set's and run's the kubectl command.
type Exec interface {
SetKubeCmd(namespace string, args ...string)
SetKubeCmd(kubeConfig string, kubeContext string, namespace string, args ...string)
RunKubeCmd(deviation deviation.Deviation) (deviation.Deviation, error)
}

Expand Down
40 changes: 11 additions & 29 deletions pkg/command/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,19 @@ package command
import (
"fmt"
"os"
"path/filepath"

"k8s.io/client-go/util/homedir"
)

// SetKubeCmd sets the kubectl command with all predefined arguments.
func (cmd *command) SetKubeCmd(namespace string, args ...string) {
cmd.baseCmd.Env = cmd.prepareKubeEnvironments()
func (cmd *command) SetKubeCmd(kubeConfig string, kubeContext string, namespace string, args ...string) {
cmd.baseCmd.Env = os.Environ()
cmd.baseCmd.Args = append(cmd.baseCmd.Args, "diff")
cmd.baseCmd.Args = append(cmd.baseCmd.Args, args...)
cmd.baseCmd.Args = append(cmd.baseCmd.Args, cmd.getNamespace(namespace))

if len(setContext()) != 0 {
cmd.baseCmd.Args = append(cmd.baseCmd.Args, setContext())
}
cmd.baseCmd.Args = append(cmd.baseCmd.Args, getContext(kubeConfig, kubeContext)...)

cmd.log.Debugf("running command '%s' to find diff", cmd.baseCmd.String())
}

func (cmd *command) prepareKubeEnvironments() []string {
config := os.Getenv(KubeConfig)

var envs []string

if len(config) != 0 {
envs = append(envs, constructEnv(KubeConfig, config))
} else {
envs = append(envs, constructEnv(KubeConfig, filepath.Join(homedir.HomeDir(), ".kube", "config")))
}

envs = append(envs, os.Environ()...)

return envs
}

func (cmd *command) getNamespace(nameSpace string) string {
return fmt.Sprintf("-n=%s", nameSpace)
}
Expand All @@ -47,11 +25,15 @@ func constructEnv(key, value string) string {
return fmt.Sprintf("%s=%s", key, value)
}

func setContext() string {
kubeContext := os.Getenv(HelmContext)
func getContext(kubeConfig string, kubeContext string) []string {
cmds := []string{}
if len(kubeContext) != 0 {
return fmt.Sprintf("--context=%s", kubeContext)
cmds = append(cmds, fmt.Sprintf("--context=%s", kubeContext))
}

if len(kubeConfig) != 0 {
cmds = append(cmds, fmt.Sprintf("--kubeconfig=%s", kubeConfig))
}

return kubeContext
return cmds
}
2 changes: 1 addition & 1 deletion pkg/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (drift *Drift) Diff(renderedManifests deviation.DriftedRelease) (deviation.
nameSpace := drift.setNameSpace(renderedManifests, dvn)
drift.log.Debugf("setting namespace to %s", nameSpace)

cmd.SetKubeCmd(nameSpace, arguments...)
cmd.SetKubeCmd(drift.kubeConfig, drift.kubeContext, nameSpace, arguments...)

dft, err := cmd.RunKubeCmd(dvn)
if err != nil {
Expand Down
26 changes: 20 additions & 6 deletions pkg/drift.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import (
"bufio"
"io"
"os"
"strings"
"path/filepath"
"time"

"github.com/nikhilsbhat/helm-drift/pkg/command"
"github.com/nikhilsbhat/helm-drift/pkg/deviation"
"github.com/sirupsen/logrus"
"k8s.io/client-go/util/homedir"
)

const (
Expand Down Expand Up @@ -48,6 +48,8 @@ type Drift struct {
release string
chart string
namespace string
kubeConfig string
kubeContext string
timeSpent float64
log *logrus.Logger
writer *bufio.Writer
Expand Down Expand Up @@ -78,8 +80,6 @@ func (drift *Drift) GetDrift() {

drift.log.Debugf("got all required values to identify drifts from chart/release '%s' proceeding furter to fetch the same", drift.release)

drift.setReleaseNameSpace()

if err := drift.setExternalDiff(); err != nil {
drift.log.Fatalf("%v", err)
}
Expand Down Expand Up @@ -134,8 +134,22 @@ func (drift *Drift) getChartManifests() ([]byte, error) {
return drift.getChartFromTemplate()
}

func (drift *Drift) setReleaseNameSpace() {
drift.namespace = strings.TrimSpace(os.Getenv(command.HelmNamespace))
func (drift *Drift) SetNamespace(namespace string) {
drift.namespace = namespace
if len(drift.namespace) == 0 {
drift.namespace = "default"
}
}

func (drift *Drift) SetKubeConfig(kubeConfig string) {
drift.kubeConfig = kubeConfig
if len(drift.kubeConfig) == 0 {
drift.kubeConfig = filepath.Join(homedir.HomeDir(), ".kube", "config")
}
}

func (drift *Drift) SetKubeContext(kubeContext string) {
drift.kubeContext = kubeContext
}

func (drift *Drift) setExternalDiff() error {
Expand Down
2 changes: 0 additions & 2 deletions pkg/drift_all.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ func (drift *Drift) GetAllDrift() {

drift.log.Debugf("got all required values to identify drifts from chart/release '%s' proceeding furter to fetch the same", drift.release)

drift.setReleaseNameSpace()

if err := drift.setExternalDiff(); err != nil {
drift.log.Fatalf("%v", err)
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/from_release.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/release"
// Import to initialize client auth plugins.
_ "k8s.io/client-go/plugin/pkg/client/auth"
)

// getChartFromRelease should get the manifest from the selected release.
Expand All @@ -16,6 +18,17 @@ func (drift *Drift) getChartFromRelease() ([]byte, error) {
drift.log.Debugf("fetching chart manifest for release '%s' from kube cluster", drift.release)

actionConfig := new(action.Configuration)

kubeContext := drift.kubeContext
if len(kubeContext) != 0 {
settings.KubeContext = kubeContext
}

kubeConfig := drift.kubeConfig
if len(kubeConfig) != 0 {
settings.KubeConfig = kubeConfig
}

if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
drift.log.Error("oops initialising helm client errored with", err)

Expand Down

0 comments on commit af4f3f6

Please sign in to comment.