Skip to content

Commit

Permalink
feat: kubeconfig path flag (#329)
Browse files Browse the repository at this point in the history
* feat: kubeconfig path flag

* fix: GetConfig comment

---------

Co-authored-by: Andy Suderman <andy@fairwinds.com>
  • Loading branch information
bbensky and sudermanjr authored Oct 1, 2024
1 parent ac6e833 commit f4ac782
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 24 deletions.
27 changes: 17 additions & 10 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ func init() {
klog.Exitf("Failed to bind context flag: %v", err)
}

rootCmd.PersistentFlags().String("kubeconfig", "", "A path to a kubeconfig file.")
err = viper.BindPFlag("kubeconfig", rootCmd.PersistentFlags().Lookup("kubeconfig"))
if err != nil {
klog.Exitf("Failed to bind kubeconfig flag: %v", err)
}

rootCmd.PersistentFlags().Bool("wide", false, "Output chart name and namespace")
err = viper.BindPFlag("wide", rootCmd.PersistentFlags().Lookup("wide"))
if err != nil {
Expand Down Expand Up @@ -252,14 +258,15 @@ var findCmd = &cobra.Command{
klog.V(5).Infof("All Keys: %v", viper.AllKeys())

kubeContext := viper.GetString("context")
kubeConfigPath := viper.GetString("kubeconfig")

format := viper.GetString("format")
if !(format == output.TableFormat || format == output.JSONFormat) {
klog.Exitf("--format flag value is not valid. Run `nova find --help` to see flag options")
}

if viper.GetBool("helm") && viper.GetBool("containers") {
output, err := handleHelmAndContainers(kubeContext)
output, err := handleHelmAndContainers(kubeContext, kubeConfigPath)
if err != nil {
klog.Exit(err)
}
Expand All @@ -276,15 +283,15 @@ var findCmd = &cobra.Command{
}

if viper.GetBool("containers") {
output, err := handleContainers(kubeContext)
output, err := handleContainers(kubeContext, kubeConfigPath)
if err != nil {
klog.Exit(err)
}
output.Print(format)
return
}

output, err := handleHelm(kubeContext)
output, err := handleHelm(kubeContext, kubeConfigPath)
if err != nil {
klog.Exit(err)
}
Expand Down Expand Up @@ -321,7 +328,7 @@ func Execute(VERSION, COMMIT string) {
}
}

func handleContainers(kubeContext string) (*output.ContainersOutput, error) {
func handleContainers(kubeContext, kubeConfigPath string) (*output.ContainersOutput, error) {
// Set up a context we can use to cancel all operations to external container registries if we need to
timeout := time.Duration(viper.GetUint16("timeout")) * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
Expand All @@ -339,7 +346,7 @@ func handleContainers(kubeContext string) (*output.ContainersOutput, error) {
case <-ctx.Done():
}
}()
iClient := containers.NewClient(kubeContext)
iClient := containers.NewClient(kubeContext, kubeConfigPath)
namespace := viper.GetString("namespace")
if viper.IsSet("namespace") {
klog.V(3).Infof("Scanning namespace %v", namespace)
Expand All @@ -356,8 +363,8 @@ func handleContainers(kubeContext string) (*output.ContainersOutput, error) {
return output.NewContainersOutput(containers.Images, containers.ErrImages, showNonSemver, showErrored, includeAll), nil
}

func handleHelm(kubeContext string) (*output.Output, error) {
h := nova_helm.NewHelm(kubeContext)
func handleHelm(kubeContext, kubeConfigPath string) (*output.Output, error) {
h := nova_helm.NewHelm(kubeContext, kubeConfigPath)
if viper.IsSet("desired-versions") {
klog.V(3).Infof("desired-versions is set - attempting to load them")
klog.V(8).Infof("raw desired-versions: %v", viper.Get("desired-versions"))
Expand Down Expand Up @@ -412,12 +419,12 @@ func handleHelm(kubeContext string) (*output.Output, error) {
return &out, nil
}

func handleHelmAndContainers(kubeContext string) (*output.HelmAndContainersOutput, error) {
helmOutput, err := handleHelm(kubeContext)
func handleHelmAndContainers(kubeContext, kubeConfigPath string) (*output.HelmAndContainersOutput, error) {
helmOutput, err := handleHelm(kubeContext, kubeConfigPath)
if err != nil {
return nil, err
}
containersOutput, err := handleContainers(kubeContext)
containersOutput, err := handleContainers(kubeContext, kubeConfigPath)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/containers/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ type Tag struct {
}

// NewClient is a constructor to create a new Client
func NewClient(kubeContext string) *Client {
func NewClient(kubeContext, kubeConfigPath string) *Client {
return &Client{
Kube: kube.GetConfigInstance(kubeContext),
Kube: kube.GetConfigInstance(kubeContext, kubeConfigPath),
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/helm/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ type DesiredVersion struct {
}

// NewHelm returns a basic helm struct with the version of helm requested
func NewHelm(kubeContext string) *Helm {
func NewHelm(kubeContext, kubeConfigPath string) *Helm {
return &Helm{
Kube: kube.GetConfigInstance(kubeContext),
Kube: kube.GetConfigInstance(kubeContext, kubeConfigPath),
}
}

Expand Down
40 changes: 30 additions & 10 deletions pkg/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package kube

import (
"flag"
"sync"

"k8s.io/apimachinery/pkg/api/meta"
Expand Down Expand Up @@ -45,19 +46,38 @@ var (
)

// GetConfigInstance returns a Kubernetes interface based on the current configuration
func GetConfigInstance(context string) *Connection {
func GetConfigInstance(context, kubeConfigPath string) *Connection {
once.Do(func() {
kubeClient = &Connection{
Client: getKubeClient(context),
DynamicClient: getDynamicKubeClient(context),
RESTMapper: getRESTMapper(context),
Client: getKubeClient(context, kubeConfigPath),
DynamicClient: getDynamicKubeClient(context, kubeConfigPath),
RESTMapper: getRESTMapper(context, kubeConfigPath),
}
})
return kubeClient
}

func getKubeClient(context string) kubernetes.Interface {
kubeConf, err := config.GetConfigWithContext(context)
// GetConfig returns a *rest.Config based on the current configuration
func GetConfig(context, kubeConfigPath string) (*rest.Config, error) {

if context != "" {
klog.V(3).Infof("using kube context: %s", context)
}

fs := flag.NewFlagSet("fs", flag.ContinueOnError)
fs.String("kubeconfig", kubeConfigPath, "")
config.RegisterFlags(fs)

kubeConfig, err := config.GetConfigWithContext(context)
if err != nil {
return nil, err
}

return kubeConfig, nil
}

func getKubeClient(context, kubeConfigPath string) kubernetes.Interface {
kubeConf, err := GetConfig(context, kubeConfigPath)
if err != nil {
klog.Fatalf("error getting config with context %s: %v", context, err)
}
Expand All @@ -69,8 +89,8 @@ func getKubeClient(context string) kubernetes.Interface {
return clientset
}

func getDynamicKubeClient(context string) dynamic.Interface {
kubeConf, err := config.GetConfigWithContext(context)
func getDynamicKubeClient(context, kubeConfigPath string) dynamic.Interface {
kubeConf, err := GetConfig(context, kubeConfigPath)
if err != nil {
klog.Fatalf("error getting config with context %s: %v", context, err)
}
Expand All @@ -81,8 +101,8 @@ func getDynamicKubeClient(context string) dynamic.Interface {
return dynamicClient
}

func getRESTMapper(context string) meta.RESTMapper {
kubeConf, err := config.GetConfigWithContext(context)
func getRESTMapper(context, kubeConfigPath string) meta.RESTMapper {
kubeConf, err := GetConfig(context, kubeConfigPath)
if err != nil {
klog.Fatalf("error getting config with context %s: %v", context, err)
}
Expand Down

0 comments on commit f4ac782

Please sign in to comment.