diff --git a/.traefik.yml b/.traefik.yml index 6f9bd34..f3de044 100644 --- a/.traefik.yml +++ b/.traefik.yml @@ -11,11 +11,12 @@ testData: names: whoami,nginx # Comma separated names of containers/services/deployments etc. sessionDuration: 1m # The session duration after which containers/services/deployments instances are shutdown # You can only use one strategy at a time - # To do so, only declare `dynamic` or `blockin` + # To do so, only declare `dynamic` or `blocking` # Dynamic strategy, provides the waiting webui dynamic: displayName: My Title # (Optional) Defaults to the middleware name + showDetails: true # (Optional) Set to true or false to show details specifcally for this middleware, unset to use Sablier server defaults theme: hacker-terminal # (Optional) The theme to use refreshFrequency: 5s # (Optional) The loading page refresh frequency diff --git a/app/http/pages/render.go b/app/http/pages/render.go index 0bc7074..df98e6e 100644 --- a/app/http/pages/render.go +++ b/app/http/pages/render.go @@ -25,6 +25,7 @@ type RenderOptionsInstanceState struct { type RenderOptions struct { DisplayName string + ShowDetails bool InstanceStates []RenderOptionsInstanceState SessionDuration time.Duration RefreshFrequency time.Duration @@ -61,9 +62,15 @@ func Render(options RenderOptions, writer io.Writer) error { return err } + instanceStates := []RenderOptionsInstanceState{} + + if options.ShowDetails { + instanceStates = options.InstanceStates + } + return tpl.Execute(writer, TemplateValues{ DisplayName: options.DisplayName, - InstanceStates: options.InstanceStates, + InstanceStates: instanceStates, SessionDuration: humanizeDuration(options.SessionDuration), RefreshFrequency: fmt.Sprintf("%d", int64(options.RefreshFrequency.Seconds())), Version: options.Version, diff --git a/app/http/pages/render_test.go b/app/http/pages/render_test.go index cbc7308..9a42306 100644 --- a/app/http/pages/render_test.go +++ b/app/http/pages/render_test.go @@ -242,6 +242,38 @@ func TestRenderContent(t *testing.T) { }, wantContent: "", }, + { + name: "details is rendered", + args: args{ + options: RenderOptions{ + DisplayName: "Test", + ShowDetails: true, + InstanceStates: instanceStates, + Theme: "ghost", + SessionDuration: 10 * time.Minute, + RefreshFrequency: 10 * time.Second, + CustomThemes: nil, + Version: "v0.0.0", + }, + }, + wantContent: "started (4/4)", + }, + { + name: "details is not rendered", + args: args{ + options: RenderOptions{ + DisplayName: "Test", + ShowDetails: false, + InstanceStates: instanceStates, + Theme: "ghost", + SessionDuration: 10 * time.Minute, + RefreshFrequency: 10 * time.Second, + CustomThemes: nil, + Version: "v0.0.0", + }, + }, + wantContent: "
", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/app/http/routes/models/dynamic_request.go b/app/http/routes/models/dynamic_request.go index e3eaf9d..bac9992 100644 --- a/app/http/routes/models/dynamic_request.go +++ b/app/http/routes/models/dynamic_request.go @@ -6,6 +6,7 @@ import ( type DynamicRequest struct { Names []string `form:"names" binding:"required"` + ShowDetails bool `form:"show_details"` DisplayName string `form:"display_name"` Theme string `form:"theme"` SessionDuration time.Duration `form:"session_duration" binding:"required"` diff --git a/app/http/routes/strategies.go b/app/http/routes/strategies.go index a3cecd4..a8eacd0 100644 --- a/app/http/routes/strategies.go +++ b/app/http/routes/strategies.go @@ -49,6 +49,7 @@ func NewServeStrategy(sessionsManager sessions.Manager, conf config.Strategy) *S func (s *ServeStrategy) ServeDynamic(c *gin.Context) { request := models.DynamicRequest{ Theme: s.StrategyConfig.Dynamic.DefaultTheme, + ShowDetails: s.StrategyConfig.Dynamic.ShowDetailsByDefault, RefreshFrequency: s.StrategyConfig.Dynamic.DefaultRefreshFrequency, } @@ -67,6 +68,7 @@ func (s *ServeStrategy) ServeDynamic(c *gin.Context) { renderOptions := pages.RenderOptions{ DisplayName: request.DisplayName, + ShowDetails: request.ShowDetails, SessionDuration: request.SessionDuration, Theme: request.Theme, CustomThemes: s.customThemesFS, diff --git a/cmd/root.go b/cmd/root.go index 410cdc3..f962987 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -66,6 +66,8 @@ It provides an integrations with multiple reverse proxies and different loading viper.BindPFlag("strategy.dynamic.custom-themes-path", startCmd.Flags().Lookup("strategy.dynamic.custom-themes-path")) startCmd.Flags().StringVar(&conf.Strategy.Dynamic.DefaultTheme, "strategy.dynamic.default-theme", "hacker-terminal", "Default theme used for dynamic strategy") viper.BindPFlag("strategy.dynamic.default-theme", startCmd.Flags().Lookup("strategy.dynamic.default-theme")) + startCmd.Flags().BoolVar(&conf.Strategy.Dynamic.ShowDetailsByDefault, "strategy.dynamic.show-details-by-default", true, "Show the loading instances details by default") + viper.BindPFlag("strategy.dynamic.show-details-by-default", startCmd.Flags().Lookup("strategy.dynamic.show-details-by-default")) startCmd.Flags().DurationVar(&conf.Strategy.Dynamic.DefaultRefreshFrequency, "strategy.dynamic.default-refresh-frequency", 5*time.Second, "Default refresh frequency in the HTML page for dynamic strategy") viper.BindPFlag("strategy.dynamic.default-refresh-frequency", startCmd.Flags().Lookup("strategy.dynamic.default-refresh-frequency")) startCmd.Flags().DurationVar(&conf.Strategy.Blocking.DefaultTimeout, "strategy.blocking.default-timeout", 1*time.Minute, "Default timeout used for blocking strategy") diff --git a/cmd/root_test.go b/cmd/root_test.go index 3da106e..79763ec 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -106,6 +106,8 @@ func TestPrecedence(t *testing.T) { "--sessions.expiration-interval", "3h", "--logging.level", "info", "--strategy.dynamic.custom-themes-path", "/tmp/cli/themes", + // Must use `=` see https://github.com/spf13/cobra/issues/613 + "--strategy.dynamic.show-details-by-default=false", "--strategy.dynamic.default-theme", "cli", "--strategy.dynamic.default-refresh-frequency", "3h", "--strategy.blocking.default-timeout", "3h", diff --git a/cmd/testdata/config.env b/cmd/testdata/config.env index 22669ed..05468ba 100644 --- a/cmd/testdata/config.env +++ b/cmd/testdata/config.env @@ -6,6 +6,7 @@ SESSIONS_DEFAULT_DURATION=2h SESSIONS_EXPIRATION_INTERVAL=2h LOGGING_LEVEL=debug STRATEGY_DYNAMIC_CUSTOM_THEMES_PATH=/tmp/envvar/themes +STRATEGY_SHOW_DETAILS_BY_DEFAULT=false STRATEGY_DYNAMIC_DEFAULT_THEME=envvar STRATEGY_DYNAMIC_DEFAULT_REFRESH_FREQUENCY=2h STRATEGY_BLOCKING_DEFAULT_TIMEOUT=2h \ No newline at end of file diff --git a/cmd/testdata/config.yml b/cmd/testdata/config.yml index c20a875..683ae90 100644 --- a/cmd/testdata/config.yml +++ b/cmd/testdata/config.yml @@ -13,6 +13,7 @@ logging: strategy: dynamic: custom-themes-path: /tmp/configfile/themes + show-details-by-default: false default-theme: configfile default-refresh-frequency: 1h blocking: diff --git a/cmd/testdata/config_cli_wanted.json b/cmd/testdata/config_cli_wanted.json index dd95feb..9827aa5 100644 --- a/cmd/testdata/config_cli_wanted.json +++ b/cmd/testdata/config_cli_wanted.json @@ -19,6 +19,7 @@ "Strategy": { "Dynamic": { "CustomThemesPath": "/tmp/cli/themes", + "ShowDetailsByDefault": false, "DefaultTheme": "cli", "DefaultRefreshFrequency": 10800000000000 }, diff --git a/cmd/testdata/config_env_wanted.json b/cmd/testdata/config_env_wanted.json index 985ec95..12c031e 100644 --- a/cmd/testdata/config_env_wanted.json +++ b/cmd/testdata/config_env_wanted.json @@ -19,6 +19,7 @@ "Strategy": { "Dynamic": { "CustomThemesPath": "/tmp/envvar/themes", + "ShowDetailsByDefault": false, "DefaultTheme": "envvar", "DefaultRefreshFrequency": 7200000000000 }, diff --git a/cmd/testdata/config_yaml_wanted.json b/cmd/testdata/config_yaml_wanted.json index 4a7a0cc..cec2578 100644 --- a/cmd/testdata/config_yaml_wanted.json +++ b/cmd/testdata/config_yaml_wanted.json @@ -19,6 +19,7 @@ "Strategy": { "Dynamic": { "CustomThemesPath": "/tmp/configfile/themes", + "ShowDetailsByDefault": false, "DefaultTheme": "configfile", "DefaultRefreshFrequency": 3600000000000 }, diff --git a/config/strategy.go b/config/strategy.go index be24915..32391d3 100644 --- a/config/strategy.go +++ b/config/strategy.go @@ -4,6 +4,7 @@ import "time" type DynamicStrategy struct { CustomThemesPath string `mapstructure:"CUSTOM_THEMES_PATH" yaml:"customThemesPath"` + ShowDetailsByDefault bool `mapstructure:"SHOW_DETAILS_BY_DEFAULT" yaml:"showDetailsByDefault"` DefaultTheme string `mapstructure:"DEFAULT_THEME" yaml:"defaultTheme" default:"hacker-terminal"` DefaultRefreshFrequency time.Duration `mapstructure:"DEFAULT_REFRESH_FREQUENCY" yaml:"defaultRefreshFrequency" default:"5s"` } @@ -27,6 +28,7 @@ func NewStrategyConfig() Strategy { func newDynamicStrategy() DynamicStrategy { return DynamicStrategy{ DefaultTheme: "hacker-terminal", + ShowDetailsByDefault: true, DefaultRefreshFrequency: 5 * time.Second, } } diff --git a/plugins/traefik/config.go b/plugins/traefik/config.go index 12e58e8..c43cae0 100644 --- a/plugins/traefik/config.go +++ b/plugins/traefik/config.go @@ -3,12 +3,14 @@ package traefik import ( "fmt" "net/http" + "strconv" "strings" "time" ) type DynamicConfiguration struct { DisplayName string `yaml:"displayname"` + ShowDetails *bool `yaml:"showDetails"` Theme string `yaml:"theme"` RefreshFrequency string `yaml:"refreshFrequency"` } @@ -110,6 +112,10 @@ func (c *Config) buildDynamicRequest(middlewareName string) (*http.Request, erro q.Add("refresh_frequency", c.Dynamic.RefreshFrequency) } + if c.Dynamic.ShowDetails != nil { + q.Add("show_details", strconv.FormatBool(*c.Dynamic.ShowDetails)) + } + request.URL.RawQuery = q.Encode() return request, nil diff --git a/plugins/traefik/config_test.go b/plugins/traefik/config_test.go index 3fe80d2..9e306a9 100644 --- a/plugins/traefik/config_test.go +++ b/plugins/traefik/config_test.go @@ -9,6 +9,9 @@ import ( "github.com/acouvreur/sablier/plugins/traefik" ) +var fals bool = false +var tru bool = true + func TestConfig_BuildRequest(t *testing.T) { type fields struct { SablierURL string @@ -98,6 +101,48 @@ func TestConfig_BuildRequest(t *testing.T) { want: nil, wantErr: true, }, + { + name: "dynamic session with show details to true", + fields: fields{ + SablierURL: "http://sablier:10000", + Names: "nginx , apache", + SessionDuration: "1m", + Dynamic: &traefik.DynamicConfiguration{ + ShowDetails: &tru, + RefreshFrequency: "1m", + }, + }, + want: createRequest("GET", "http://sablier:10000/api/strategies/dynamic?display_name=sablier-middleware&names=nginx&names=apache&refresh_frequency=1m&session_duration=1m&show_details=true", nil), + wantErr: false, + }, + { + name: "dynamic session with show details to false", + fields: fields{ + SablierURL: "http://sablier:10000", + Names: "nginx , apache", + SessionDuration: "1m", + Dynamic: &traefik.DynamicConfiguration{ + ShowDetails: &fals, + RefreshFrequency: "1m", + }, + }, + want: createRequest("GET", "http://sablier:10000/api/strategies/dynamic?display_name=sablier-middleware&names=nginx&names=apache&refresh_frequency=1m&session_duration=1m&show_details=false", nil), + wantErr: false, + }, + { + name: "dynamic session without show details set", + fields: fields{ + SablierURL: "http://sablier:10000", + Names: "nginx , apache", + SessionDuration: "1m", + Dynamic: &traefik.DynamicConfiguration{ + ShowDetails: nil, + RefreshFrequency: "1m", + }, + }, + want: createRequest("GET", "http://sablier:10000/api/strategies/dynamic?display_name=sablier-middleware&names=nginx&names=apache&refresh_frequency=1m&session_duration=1m", nil), + wantErr: false, + }, { name: "blocking session with default values", fields: fields{