Skip to content

Commit

Permalink
Read the --kube-context flag to set the kubeconfig context
Browse files Browse the repository at this point in the history
Add --kube-context flag

Require --kubeconfig when passing --kube-context

Add --kube-context documentation

Update klient/conf/config.go

Co-authored-by: Harsha Narayana <harsha2k4@gmail.com>

Update klient/conf/config.go

Co-authored-by: Harsha Narayana <harsha2k4@gmail.com>

Fix indentation

Use kubeContext instead of context to avoid clashing
  • Loading branch information
maruina committed Feb 17, 2023
1 parent 35ab1e9 commit f2d2b80
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
6 changes: 6 additions & 0 deletions examples/flags/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ To get additional verbose logs
```shell
./flags.test --assess es --v 2
```

To run a test against a particular Kubeconfig context

```shell
./flags.test --kubeconfig ~/path/to/kubeconfig --context my-context
```
33 changes: 27 additions & 6 deletions klient/conf/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ limitations under the License.
package conf

import (
"errors"
"flag"
"os"
"os/user"
Expand All @@ -33,14 +34,34 @@ var DefaultClusterContext = ""
// New returns Kubernetes configuration value of type *rest.Config.
// filename is kubeconfig file
func New(fileName string) (*rest.Config, error) {
// if filename is not provided assume in-cluster-config
var resolvedKubeConfigFile string
kubeContext := ResolveClusterContext()

// resolve the kubeconfig file
if fileName == "" {
return rest.InClusterConfig()
resolvedKubeConfigFile = ResolveKubeConfigFile()
if fileName != "" {
resolvedKubeConfigFile = fileName
}
}

// if resolvedKubeConfigFile is still empty, assume in-cluster config
if resolvedKubeConfigFile == "" {
if kubeContext == "" {
return rest.InClusterConfig()
}
// if in-cluster can't use the --kubeContext flag
return nil, errors.New("cannot use a cluster context without a valid kubeconfig file")
}

// set the desired context if provided
if kubeContext != "" {
return NewWithContextName(resolvedKubeConfigFile, kubeContext)
}

// create the config object from k8s config path
// create the config object from resolvedKubeConfigFile without a context
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: fileName}, &clientcmd.ConfigOverrides{}).ClientConfig()
&clientcmd.ClientConfigLoadingRules{ExplicitPath: resolvedKubeConfigFile}, &clientcmd.ConfigOverrides{}).ClientConfig()
}

// NewWithContextName returns k8s config value of type *rest.Config
Expand Down Expand Up @@ -110,9 +131,9 @@ func ResolveKubeConfigFile() string {

// ResolveClusterContext returns cluster context name based on --context flag.
func ResolveClusterContext() string {
// If a flag --kube-context is specified use that
// If a flag --context is specified use that
if flag.Parsed() {
f := flag.Lookup("kube-context")
f := flag.Lookup("context")
if f != nil {
return f.Value.String()
}
Expand Down
13 changes: 11 additions & 2 deletions klient/conf/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func setup() {

kubeconfigdir := filepath.Join(home, "test", ".kube")
kubeconfigpath := filepath.Join(kubeconfigdir, "config")
kubeContext := "test-context"

// check if file exists
_, err := os.Stat(kubeconfigpath)
Expand All @@ -52,7 +53,7 @@ func setup() {
}

// generate kube config data
data := genKubeconfig("test-context")
data := genKubeconfig(kubeContext)

err = createFile(kubeconfigpath, data)
if err != nil {
Expand All @@ -64,11 +65,19 @@ func setup() {
log.Info("file created successfully", kubeconfigpath)

flag.StringVar(&kubeconfig, "kubeconfig", "", "Paths to a kubeconfig. Only required if out-of-cluster.")
flag.StringVar(&kubeContext, "context", "", "The name of the kubeconfig context to use. Only required if out-of-cluster.")

// set --kubeconfig flag
err = flag.Set("kubeconfig", kubeconfigpath)
if err != nil {
log.ErrorS(err, "unexpected error while setting flag value")
log.ErrorS(err, "unexpected error while setting kubeconfig flag value")
return
}

// set --context flag
err = flag.Set("context", kubeContext)
if err != nil {
log.ErrorS(err, "unexpected error while setting context flag value")
return
}

Expand Down
13 changes: 13 additions & 0 deletions pkg/envconf/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Config struct {
dryRun bool
failFast bool
disableGracefulTeardown bool
kubeContext string
}

// New creates and initializes an empty environment configuration
Expand Down Expand Up @@ -85,6 +86,7 @@ func NewFromFlags() (*Config, error) {
e.dryRun = envFlags.DryRun()
e.failFast = envFlags.FailFast()
e.disableGracefulTeardown = envFlags.DisableGracefulTeardown()
e.kubeContext = envFlags.KubeContext()

return e, nil
}
Expand Down Expand Up @@ -274,6 +276,17 @@ func (c *Config) DisableGracefulTeardown() bool {
return c.disableGracefulTeardown
}

// WithKubeContext is used to set the kubeconfig context
func (c *Config) WithKubeContext(kubeContext string) *Config {
c.kubeContext = kubeContext
return c
}

// WithKubeContext is used to get the kubeconfig context
func (c *Config) KubeContext() string {
return c.kubeContext
}

func randNS() string {
return RandomName("testns-", 32)
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const (
flagDryRunName = "dry-run"
flagFailFast = "fail-fast"
flagDisableGracefulTeardown = "disable-graceful-teardown"
flagContext = "context"
)

// Supported flag definitions
Expand Down Expand Up @@ -90,6 +91,10 @@ var (
Name: flagDisableGracefulTeardown,
Usage: "Ignore panic recovery while running tests. This will prevent test finish steps from getting executed on panic",
}
contextFlag = flag.Flag{
Name: flagContext,
Usage: "The name of the kubeconfig context to use",
}
)

// EnvFlags surfaces all resolved flag values for the testing framework
Expand All @@ -106,6 +111,7 @@ type EnvFlags struct {
dryRun bool
failFast bool
disableGracefulTeardown bool
kubeContext string
}

// Feature returns value for `-feature` flag
Expand Down Expand Up @@ -180,6 +186,11 @@ func Parse() (*EnvFlags, error) {
return ParseArgs(os.Args[1:])
}

// Context returns an optional kubeconfig context to use
func (f *EnvFlags) KubeContext() string {
return f.kubeContext
}

// ParseArgs parses the specified args from global flag.CommandLine
// and returns a set of environment flag values.
func ParseArgs(args []string) (*EnvFlags, error) {
Expand All @@ -194,6 +205,7 @@ func ParseArgs(args []string) (*EnvFlags, error) {
dryRun bool
failFast bool
disableGracefulTeardown bool
kubeContext string
)

labels := make(LabelsMap)
Expand Down Expand Up @@ -247,6 +259,10 @@ func ParseArgs(args []string) (*EnvFlags, error) {
flag.BoolVar(&disableGracefulTeardown, disableGracefulTeardownFlag.Name, false, disableGracefulTeardownFlag.Usage)
}

if flag.Lookup(contextFlag.Name) == nil {
flag.StringVar(&kubeContext, contextFlag.Name, contextFlag.DefValue, contextFlag.Usage)
}

// Enable klog/v2 flag integration
klog.InitFlags(nil)

Expand Down Expand Up @@ -277,6 +293,7 @@ func ParseArgs(args []string) (*EnvFlags, error) {
dryRun: dryRun,
failFast: failFast,
disableGracefulTeardown: disableGracefulTeardown,
kubeContext: kubeContext,
}, nil
}

Expand Down

0 comments on commit f2d2b80

Please sign in to comment.