Skip to content

Commit

Permalink
User-configurable request timeouts (#970)
Browse files Browse the repository at this point in the history
Add an option to allow the user to specify the KUDO client's request
timeout.  The hardcoded default of 3 seconds causes problems for users
whose connectivity to a target service involves relatively significant amounts
of latency.

Mirror the behaviour of `kubectl` by setting this to 0.
  • Loading branch information
yankcrime authored and gerred committed Oct 24, 2019
1 parent e6ca394 commit dbbb207
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 13 deletions.
2 changes: 1 addition & 1 deletion pkg/kudoctl/cmd/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func Run(args []string, settings *env.Settings) error {
return err
}

kc, err := kudo.NewClient(settings.Namespace, settings.KubeConfig)
kc, err := env.GetClient(settings)
if err != nil {
return errors.Wrap(err, "creating kudo client")
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/kudoctl/cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Options struct {
Parameters map[string]string
PackageVersion string
SkipInstance bool
RequestTimeout int64
}

// DefaultOptions initializes the install command options to its defaults
Expand Down Expand Up @@ -102,7 +103,7 @@ func installOperator(operatorArgument string, options *Options, fs afero.Fs, set
}
clog.V(4).Printf("repository used %s", repository)

kc, err := kudo.NewClient(settings.Namespace, settings.KubeConfig)
kc, err := env.GetClient(settings)
clog.V(3).Printf("acquiring kudo client")
if err != nil {
clog.V(3).Printf("failed to acquire client")
Expand Down
3 changes: 1 addition & 2 deletions pkg/kudoctl/cmd/plan/plan_history.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"github.com/kudobuilder/kudo/pkg/kudoctl/env"
"github.com/kudobuilder/kudo/pkg/kudoctl/util/kudo"
"github.com/spf13/cobra"
"github.com/xlab/treeprint"
)
Expand Down Expand Up @@ -36,7 +35,7 @@ func RunHistory(cmd *cobra.Command, options *Options, settings *env.Settings) er
func planHistory(options *Options, settings *env.Settings) error {
namespace := settings.Namespace

kc, err := kudo.NewClient(settings.Namespace, settings.KubeConfig)
kc, err := env.GetClient(settings)
if err != nil {
fmt.Printf("Unable to create kudo client to talk to kubernetes API server %v", err)
return err
Expand Down
2 changes: 1 addition & 1 deletion pkg/kudoctl/cmd/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type uninstallOptions struct {
type uninstallCmd struct{}

func (cmd *uninstallCmd) run(options uninstallOptions, settings *env.Settings) error {
kc, err := kudo.NewClient(settings.Namespace, settings.KubeConfig)
kc, err := env.GetClient(settings)
clog.V(3).Printf("acquiring kudo client")
if err != nil {
clog.V(3).Printf("failed to acquire kudo client: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/kudoctl/cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func runUpdate(args []string, options *updateOptions, settings *env.Settings) er
}
instanceToUpdate := options.InstanceName

kc, err := kudo.NewClient(settings.Namespace, settings.KubeConfig)
kc, err := env.GetClient(settings)
if err != nil {
return errors.Wrap(err, "creating kudo client")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kudoctl/cmd/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func runUpgrade(args []string, options *options, fs afero.Fs, settings *env.Sett
}
packageToUpgrade := args[0]

kc, err := kudo.NewClient(settings.Namespace, settings.KubeConfig)
kc, err := env.GetClient(settings)
if err != nil {
return errors.Wrap(err, "creating kudo client")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"path/filepath"

"github.com/kudobuilder/kudo/pkg/kudoctl/kudohome"
"github.com/kudobuilder/kudo/pkg/kudoctl/util/kudo"

"github.com/spf13/pflag"
"k8s.io/client-go/util/homedir"
Expand All @@ -21,11 +22,14 @@ type Settings struct {
Home kudohome.Home
// Namespace used when working with Kubernetes
Namespace string
// RequestTimeout is the timeout value (in seconds) when making API calls via the KUDO client
RequestTimeout int64
}

// DefaultSettings initializes the settings to its defaults
var DefaultSettings = &Settings{
Namespace: "default",
Namespace: "default",
RequestTimeout: 0,
}

// envMap maps flag names to envvars
Expand All @@ -39,6 +43,7 @@ func (s *Settings) AddFlags(fs *pflag.FlagSet) {
fs.StringVar((*string)(&s.Home), "home", DefaultKudoHome, "location of your KUDO config.")
fs.StringVar(&s.KubeConfig, "kubeconfig", os.Getenv("HOME")+"/.kube/config", "Path to your Kubernetes configuration file.")
fs.StringVarP(&s.Namespace, "namespace", "n", "default", "Target namespace for the object.")
fs.Int64Var(&s.RequestTimeout, "request-timeout", 0, "Request timeout value, in seconds. Defaults to 0 (unlimited)")
}

// Init sets values from the environment.
Expand All @@ -62,3 +67,8 @@ func setFlagFromEnv(name, envar string, fs *pflag.FlagSet) {
}
}
}

// GetClient is a helper function that takes the Settings struct and returns a new KUDO Client
func GetClient(s *Settings) (*kudo.Client, error) {
return kudo.NewClient(s.Namespace, s.KubeConfig, s.RequestTimeout)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ func TestEnvSettings(t *testing.T) {
envars map[string]string

// expected values
home, kconfig string
home, kconfig string
requesttimeout int64
}{
{
name: "defaults",
Expand Down Expand Up @@ -47,6 +48,13 @@ func TestEnvSettings(t *testing.T) {
home: "/foo",
kconfig: "/bar",
},
{
name: "with request timeout set",
args: []string{"--request-timeout", "5"},
home: DefaultKudoHome,
kconfig: os.Getenv("HOME") + "/.kube/config",
requesttimeout: 5,
},
}

allEnvvars := map[string]string{
Expand Down Expand Up @@ -77,7 +85,9 @@ func TestEnvSettings(t *testing.T) {
if settings.KubeConfig != tt.kconfig {
t.Errorf("expected kubeconfig %q, got %q", tt.kconfig, settings.KubeConfig)
}

if settings.RequestTimeout != tt.requesttimeout {
t.Errorf("expected request-timeout %d, got %d", tt.requesttimeout, settings.RequestTimeout)
}
resetEnv(tt.envars)
})
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/kudoctl/util/kudo/kudo.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Client struct {
}

// NewClient creates new KUDO Client
func NewClient(namespace, kubeConfigPath string) (*Client, error) {
func NewClient(namespace, kubeConfigPath string, requestTimeout int64) (*Client, error) {

// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath)
Expand All @@ -39,7 +39,7 @@ func NewClient(namespace, kubeConfigPath string) (*Client, error) {
}

// set default configs
config.Timeout = time.Second * 3
config.Timeout = time.Duration(requestTimeout) * time.Second

// create the clientset
kudoClientset, err := versioned.NewForConfig(config)
Expand Down
2 changes: 1 addition & 1 deletion pkg/kudoctl/util/kudo/kudo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestNewK2oClient(t *testing.T) {

for _, tt := range tests {
// Just interested in errors
_, err := NewClient("default", "")
_, err := NewClient("default", "", 0)
if err.Error() != tt.err {
t.Errorf("non existing test:\nexpected: %v\n got: %v", tt.err, err.Error())
}
Expand Down

0 comments on commit dbbb207

Please sign in to comment.