Skip to content

Commit

Permalink
Allow backend timeout to be configurable
Browse files Browse the repository at this point in the history
Update config commands to allow getting/setting timeout
Update basic config tests to show read/write success
Update command tests to show getting/setting timeout
Update changelog

Signed-off-by: naemono <[email protected]>
  • Loading branch information
naemono committed Mar 20, 2020
1 parent 21a71bb commit a4583f1
Show file tree
Hide file tree
Showing 17 changed files with 264 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic
Versioning](http://semver.org/spec/v2.0.0.html).

## Unreleased
- Added ability to make the Resty HTTP Timeout configurable.

### Added
- Added `flapping` field to check history, along with `is_flapping_start` and
Expand Down
2 changes: 1 addition & 1 deletion cli/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func New(config config.Config) *RestClient {
client := &RestClient{resty: restyInst, config: config}

// set http client timeout
restyInst.SetTimeout(15 * time.Second)
restyInst.SetTimeout(config.Timeout())

// Standardize redirect policy
restyInst.SetRedirectPolicy(resty.FlexibleRedirectPolicy(10))
Expand Down
12 changes: 12 additions & 0 deletions cli/client/config/basic/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"time"

"github.com/sensu/sensu-go/cli/commands/helpers"
"github.com/sensu/sensu-go/types"
Expand Down Expand Up @@ -34,6 +35,7 @@ type Cluster struct {
TrustedCAFile string `json:"trusted-ca-file"`
InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify"`
*types.Tokens
Timeout time.Duration `json:"timeout"`
}

// Profile contains the active configuration
Expand Down Expand Up @@ -110,6 +112,16 @@ func (c *Config) flags(flags *pflag.FlagSet) {
if value, err := flags.GetString("trusted-ca-file"); err == nil && value != "" {
c.Cluster.TrustedCAFile = value
}

if value, err := flags.GetString("timeout"); err == nil && value != "" {
duration, err := time.ParseDuration(value)
if err == nil {
c.Cluster.Timeout = duration
} else {
// Default to timeout of 15 seconds
c.Cluster.Timeout = 15 * time.Second
}
}
}

func (c *Config) open(path string) error {
Expand Down
10 changes: 10 additions & 0 deletions cli/client/config/basic/reader.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package basic

import (
"time"

"github.com/sensu/sensu-go/cli/client/config"
"github.com/sensu/sensu-go/types"
)
Expand Down Expand Up @@ -31,6 +33,14 @@ func (c *Config) Namespace() string {
return c.Profile.Namespace
}

// Timeout returns the configured timeout
func (c *Config) Timeout() time.Duration {
if c.Cluster.Timeout == 0*time.Second {
return config.DefaultTimeout
}
return c.Cluster.Timeout
}

// Tokens returns the active cluster JWT
func (c *Config) Tokens() *types.Tokens {
return c.Cluster.Tokens
Expand Down
11 changes: 11 additions & 0 deletions cli/client/config/basic/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package basic

import (
"testing"
"time"

"github.com/sensu/sensu-go/cli/client/config"
"github.com/sensu/sensu-go/types"
Expand Down Expand Up @@ -33,6 +34,16 @@ func TestNamespaceDefault(t *testing.T) {
assert.Equal(t, config.DefaultNamespace, conf.Namespace())
}

func TestTimeout(t *testing.T) {
conf := &Config{Cluster: Cluster{Timeout: 30 * time.Second}}
assert.Equal(t, conf.Cluster.Timeout, conf.Timeout())
}

func TestTimeoutDefault(t *testing.T) {
conf := &Config{}
assert.Equal(t, config.DefaultTimeout, conf.Timeout())
}

func TestTokens(t *testing.T) {
tokens := &types.Tokens{Access: "foobar"}
conf := &Config{Cluster: Cluster{Tokens: tokens}}
Expand Down
8 changes: 8 additions & 0 deletions cli/client/config/basic/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"time"

"github.com/sensu/sensu-go/types"
)
Expand Down Expand Up @@ -37,6 +38,13 @@ func (c *Config) SaveNamespace(namespace string) error {
return write(c.Profile, filepath.Join(c.path, profileFilename))
}

// SaveTimeout saves the user's timeout to a configuration file
func (c *Config) SaveTimeout(timeout time.Duration) error {
c.Cluster.Timeout = timeout

return write(c.Cluster, filepath.Join(c.path, clusterFilename))
}

// SaveTokens saves the JWT into a configuration file
func (c *Config) SaveTokens(tokens *types.Tokens) error {
// Update the configuration loaded in memory
Expand Down
16 changes: 16 additions & 0 deletions cli/client/config/basic/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"testing"
"time"

"github.com/sensu/sensu-go/types"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -75,6 +76,21 @@ func TestSaveNamespace(t *testing.T) {
assert.Equal(t, namespace, config.Namespace())
}

func TestSaveTimeout(t *testing.T) {
dir, cleanup := tmpDir(t)
defer cleanup()

// Set flags
flags := pflag.NewFlagSet("config-dir", pflag.ContinueOnError)
flags.String("config-dir", dir, "")

config := Load(flags)

timeout := 30 * time.Second
require.NoError(t, config.SaveTimeout(timeout))
assert.Equal(t, timeout, config.Timeout())
}

func TestSaveTokens(t *testing.T) {
dir, cleanup := tmpDir(t)
defer cleanup()
Expand Down
7 changes: 7 additions & 0 deletions cli/client/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package config

import (
"time"

"github.com/sensu/sensu-go/types"
)

Expand All @@ -11,6 +13,9 @@ const (
// DefaultFormat is the default format output for printers.
DefaultFormat = FormatTabular

// DefaultTimeout is the default timeout
DefaultTimeout = 15 * time.Second

// FormatTabular indicates tabular format for printers.
FormatTabular = "tabular"

Expand Down Expand Up @@ -38,6 +43,7 @@ type Read interface {
InsecureSkipTLSVerify() bool
Namespace() string
Tokens() *types.Tokens
Timeout() time.Duration
TrustedCAFile() string
}

Expand All @@ -49,4 +55,5 @@ type Write interface {
SaveNamespace(string) error
SaveTokens(*types.Tokens) error
SaveTrustedCAFile(string) error
SaveTimeout(time.Duration) error
}
14 changes: 14 additions & 0 deletions cli/client/config/inmemory/inmemory.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package inmemory

import (
"time"

"github.com/sensu/sensu-go/cli/client/config"
"github.com/sensu/sensu-go/types"
)
Expand All @@ -10,6 +12,7 @@ type Config struct {
url string
format string
namespace string
timeout time.Duration
tokens *types.Tokens
}

Expand Down Expand Up @@ -39,6 +42,11 @@ func (c *Config) Namespace() string {
return c.namespace
}

// Timeout describes the timeout for communicating with the backend
func (c *Config) Timeout() time.Duration {
return c.timeout
}

// Tokens describes the authorization tokens used to make requests
func (c *Config) Tokens() *types.Tokens {
return c.tokens
Expand All @@ -62,6 +70,12 @@ func (c *Config) SaveNamespace(val string) error {
return nil
}

// SaveTimeout updates the current timeout value
func (c *Config) SaveTimeout(val time.Duration) error {
c.timeout = val
return nil
}

// SaveTokens updates the current value
func (c *Config) SaveTokens(val *types.Tokens) error {
c.tokens = val
Expand Down
16 changes: 16 additions & 0 deletions cli/client/config/mock.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package config

import (
"time"

corev2 "github.com/sensu/sensu-go/api/core/v2"

"github.com/stretchr/testify/mock"
Expand Down Expand Up @@ -38,6 +40,14 @@ func (m *MockConfig) Namespace() string {
return args.String(0)
}

// Timeout mocks the timeout config
func (m *MockConfig) Timeout() time.Duration {
args := m.Called()
timeoutString := args.String(0)
d, _ := time.ParseDuration(timeoutString)
return d
}

// TrustedCAFile mocks the trusted CA file config
func (m *MockConfig) TrustedCAFile() string {
args := m.Called()
Expand Down Expand Up @@ -68,6 +78,12 @@ func (m *MockConfig) SaveNamespace(namespace string) error {
return args.Error(0)
}

// SaveTimeout mocks saving the timeout
func (m *MockConfig) SaveTimeout(timeout time.Duration) error {
args := m.Called(timeout)
return args.Error(0)
}

// SaveTokens mocks saving the tokens
func (m *MockConfig) SaveTokens(tokens *corev2.Tokens) error {
args := m.Called(tokens)
Expand Down
16 changes: 16 additions & 0 deletions cli/client/testing/mock_config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package testing

import (
"time"

"github.com/sensu/sensu-go/types"
"github.com/stretchr/testify/mock"
)
Expand Down Expand Up @@ -43,6 +45,14 @@ func (m *MockConfig) TrustedCAFile() string {
return args.String(0)
}

// Timeout mocks the timeout config
func (m *MockConfig) Timeout() time.Duration {
args := m.Called()
timeoutString := args.String(0)
d, _ := time.ParseDuration(timeoutString)
return d
}

// SaveAPIUrl mocks saving the API URL
func (m *MockConfig) SaveAPIUrl(url string) error {
args := m.Called(url)
Expand All @@ -67,6 +77,12 @@ func (m *MockConfig) SaveNamespace(namespace string) error {
return args.Error(0)
}

// SaveTimeout mocks saving the timeout
func (m *MockConfig) SaveTimeout(timeout time.Duration) error {
args := m.Called(timeout)
return args.Error(0)
}

// SaveTokens mocks saving the tokens
func (m *MockConfig) SaveTokens(tokens *types.Tokens) error {
args := m.Called(tokens)
Expand Down
1 change: 1 addition & 0 deletions cli/commands/config/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func HelpCommand(cli *cli.SensuCli) *cobra.Command {
cmd.AddCommand(
SetFormatCommand(cli),
SetNamespaceCommand(cli),
SetTimeoutCommand(cli),
ViewCommand(cli),
)

Expand Down
52 changes: 52 additions & 0 deletions cli/commands/config/set_timeout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package config

import (
"errors"
"fmt"
"time"

"github.com/sensu/sensu-go/cli"
"github.com/sensu/sensu-go/cli/commands/hooks"
"github.com/spf13/cobra"
)

// SetTimeoutCommand given argument changes timeout for active profile
func SetTimeoutCommand(cli *cli.SensuCli) *cobra.Command {
return &cobra.Command{
Use: "set-timeout [TIMEOUT]",
Short: "Set timeout for active profile in duration format (ex: 15s)",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
_ = cmd.Help()
return errors.New("invalid argument(s) received")
}

newTimeout := args[0]
newTimeoutDuration, err := time.ParseDuration(newTimeout)
if err != nil {
fmt.Fprintf(
cmd.OutOrStderr(),
"Unable to parse new timeout with error: %s\n",
err,
)
return err
}
if err := cli.Config.SaveTimeout(newTimeoutDuration); err != nil {
fmt.Fprintf(
cmd.OutOrStderr(),
"Unable to write new configuration file with error: %s\n",
err,
)
}

fmt.Fprintln(cmd.OutOrStdout(), "Updated")
return nil
},
Annotations: map[string]string{
// We want to be able to run this command regardless of whether the CLI
// has been configured.
hooks.ConfigurationRequirement: hooks.ConfigurationNotRequired,
},
}
}
Loading

0 comments on commit a4583f1

Please sign in to comment.