-
Notifications
You must be signed in to change notification settings - Fork 256
Add support for configurable Plan Preview behavior in piped #6646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -79,6 +79,8 @@ type PipedSpec struct { | |
| SecretManagement *SecretManagement `json:"secretManagement,omitempty"` | ||
| // Optional settings for event watcher. | ||
| EventWatcher PipedEventWatcher `json:"eventWatcher"` | ||
| // Optional settings for plan-preview command handling. | ||
| PlanPreview PipedPlanPreview `json:"planPreview"` | ||
| // List of labels to filter all applications this piped will handle. | ||
| AppSelector map[string]string `json:"appSelector,omitempty"` | ||
| } | ||
|
|
@@ -141,6 +143,9 @@ func (s *PipedSpec) Validate() error { | |
| if err := s.EventWatcher.Validate(); err != nil { | ||
| return err | ||
| } | ||
| if err := s.PlanPreview.Validate(); err != nil { | ||
| return err | ||
| } | ||
| for _, n := range s.Notifications.Receivers { | ||
| if n.Slack != nil { | ||
| if err := n.Slack.Validate(); err != nil { | ||
|
|
@@ -1211,3 +1216,30 @@ type PipedEventWatcherGitRepo struct { | |
| // This is prioritized if both includes and this one are given. | ||
| Excludes []string `json:"excludes,omitempty"` | ||
| } | ||
|
|
||
| type PipedPlanPreview struct { | ||
| // WorkerNum is the number of worker goroutines processing plan-preview commands. | ||
| WorkerNum int `json:"workerNum,omitempty"` | ||
| // CommandQueueBufferSize is the buffer size of the internal command channel. | ||
| CommandQueueBufferSize int `json:"commandQueueBufferSize,omitempty"` | ||
| // CommandCheckInterval is how often to poll for new plan-preview commands. | ||
| CommandCheckInterval Duration `json:"commandCheckInterval,omitempty"` | ||
| // CommandHandleTimeout is the default timeout for building each plan-preview result when the command does not specify one. | ||
| CommandHandleTimeout Duration `json:"commandHandleTimeout,omitempty"` | ||
| } | ||
|
|
||
| func (p *PipedPlanPreview) Validate() error { | ||
| if p.WorkerNum < 0 { | ||
| return errors.New("planPreview.workerNum must be greater than or equal to 0") | ||
| } | ||
| if p.CommandQueueBufferSize < 0 { | ||
| return errors.New("planPreview.commandQueueBufferSize must be greater than or equal to 0") | ||
| } | ||
| if p.CommandCheckInterval < 0 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
commandTicker := time.NewTicker(h.options.commandCheckInterval)This will cause panic if
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right, We handle this the same way as above in if cfg.PlanPreview.CommandCheckInterval > 0 {
ppOpts = append(ppOpts, planpreview.WithCommandCheckInterval(cfg.PlanPreview.CommandCheckInterval.Duration()))
} |
||
| return errors.New("planPreview.commandCheckInterval must be greater than or equal to 0") | ||
| } | ||
| if p.CommandHandleTimeout < 0 { | ||
| return errors.New("planPreview.commandHandleTimeout must be greater than or equal to 0") | ||
| } | ||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,6 +64,8 @@ type PipedSpec struct { | |
| SecretManagement *SecretManagement `json:"secretManagement,omitempty"` | ||
| // Optional settings for event watcher. | ||
| EventWatcher PipedEventWatcher `json:"eventWatcher"` | ||
| // Optional settings for plan-preview command handling. | ||
| PlanPreview PipedPlanPreview `json:"planPreview"` | ||
| // List of labels to filter all applications this piped will handle. | ||
| AppSelector map[string]string `json:"appSelector,omitempty"` | ||
| } | ||
|
|
@@ -113,6 +115,9 @@ func (s *PipedSpec) Validate() error { | |
| if err := s.EventWatcher.Validate(); err != nil { | ||
| return err | ||
| } | ||
| if err := s.PlanPreview.Validate(); err != nil { | ||
| return err | ||
| } | ||
| for _, n := range s.Notifications.Receivers { | ||
| if n.Slack != nil { | ||
| if err := n.Slack.Validate(); err != nil { | ||
|
|
@@ -632,6 +637,33 @@ type PipedEventWatcherGitRepo struct { | |
| Excludes []string `json:"excludes,omitempty"` | ||
| } | ||
|
|
||
| type PipedPlanPreview struct { | ||
| // WorkerNum is the number of worker goroutines processing plan-preview commands. | ||
| WorkerNum int `json:"workerNum,omitempty"` | ||
| // CommandQueueBufferSize is the buffer size of the internal command channel. | ||
| CommandQueueBufferSize int `json:"commandQueueBufferSize,omitempty"` | ||
| // CommandCheckInterval is how often to poll for new plan-preview commands. | ||
| CommandCheckInterval Duration `json:"commandCheckInterval,omitempty"` | ||
| // CommandHandleTimeout is the default timeout for building each plan-preview result when the command does not specify one. | ||
| CommandHandleTimeout Duration `json:"commandHandleTimeout,omitempty"` | ||
| } | ||
|
|
||
| func (p *PipedPlanPreview) Validate() error { | ||
| if p.WorkerNum < 0 { | ||
| return errors.New("planPreview.workerNum must be greater than or equal to 0") | ||
| } | ||
| if p.CommandQueueBufferSize < 0 { | ||
| return errors.New("planPreview.commandQueueBufferSize must be greater than or equal to 0") | ||
| } | ||
| if p.CommandCheckInterval < 0 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same reason with v0, commandCheckInterval = 0 would cause panic |
||
| return errors.New("planPreview.commandCheckInterval must be greater than or equal to 0") | ||
| } | ||
| if p.CommandHandleTimeout < 0 { | ||
| return errors.New("planPreview.commandHandleTimeout must be greater than or equal to 0") | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // PipedPlugin defines the plugin configuration for the piped. | ||
| type PipedPlugin struct { | ||
| // The name of the plugin. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You allow WorkerNum = 0, I scare that commands can be block by this allowance, please verify the behavior to find the right condition for validating
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I checked the handler behavior here in
piped/planpreview/handler.go:From the handler logic,
workerNum = 0would result in no workers being started, so commands wouldn’t be processed if it reached there as is.In the current flow, we guard this at the callsite (
> 0check inpiped.go), so a zero value isn’t passed toWithWorkerNumand the handler falls back to its default worker count.I’m happy to enforce
> 0inValidate()as well if you think that’s preferable, though it may also affect cases where the field is omitted and defaults are expected.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure the right thing to do here, but isn't that we are using defensive programming in a lot of place, I don't think this is a good idea
maybe just concentrate on validating config at one place, what do you think ?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I think that would be cleaner. I’ve moved the
> 0checks into theWith*option functions in the handler, so the “0 = keep default” logic is handled in one place now.Validate()is just handling invalid cases (like negatives). Since with plainint/Duration, omitted and0both decode the same after YAML parsing, we can’t really reject0there without breaking configs where users just omit theplanPreviewblock.Let me know your thoughts on this.