Skip to content

Commit e800fa1

Browse files
committed
feat(planpreview): add configurable plan preview handling
1 parent 91c6112 commit e800fa1

8 files changed

Lines changed: 298 additions & 0 deletions

File tree

pkg/app/piped/cmd/piped/piped.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,10 @@ func (p *piped) run(ctx context.Context, input cli.Input) (runErr error) {
535535
decrypter,
536536
appManifestsCache,
537537
cfg,
538+
planpreview.WithWorkerNum(cfg.PlanPreview.WorkerNum),
539+
planpreview.WithCommandQueueBufferSize(cfg.PlanPreview.CommandQueueBufferSize),
540+
planpreview.WithCommandCheckInterval(cfg.PlanPreview.CommandCheckInterval.Duration()),
541+
planpreview.WithCommandHandleTimeout(cfg.PlanPreview.CommandHandleTimeout.Duration()),
538542
planpreview.WithLogger(input.Logger),
539543
)
540544
group.Go(func() error {

pkg/app/pipedv1/cmd/piped/piped.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@ func (p *piped) run(ctx context.Context, input cli.Input) (runErr error) {
500500
decrypter,
501501
cfg,
502502
pluginRegistry,
503+
planpreview.WithWorkerNum(cfg.PlanPreview.WorkerNum),
504+
planpreview.WithCommandQueueBufferSize(cfg.PlanPreview.CommandQueueBufferSize),
505+
planpreview.WithCommandCheckInterval(cfg.PlanPreview.CommandCheckInterval.Duration()),
506+
planpreview.WithCommandHandleTimeout(cfg.PlanPreview.CommandHandleTimeout.Duration()),
503507
planpreview.WithLogger(input.Logger),
504508
)
505509
group.Go(func() error {

pkg/config/piped.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ type PipedSpec struct {
7979
SecretManagement *SecretManagement `json:"secretManagement,omitempty"`
8080
// Optional settings for event watcher.
8181
EventWatcher PipedEventWatcher `json:"eventWatcher"`
82+
// Optional settings for plan-preview command handling.
83+
PlanPreview PipedPlanPreview `json:"planPreview"`
8284
// List of labels to filter all applications this piped will handle.
8385
AppSelector map[string]string `json:"appSelector,omitempty"`
8486
}
@@ -141,6 +143,9 @@ func (s *PipedSpec) Validate() error {
141143
if err := s.EventWatcher.Validate(); err != nil {
142144
return err
143145
}
146+
if err := s.PlanPreview.Validate(); err != nil {
147+
return err
148+
}
144149
for _, n := range s.Notifications.Receivers {
145150
if n.Slack != nil {
146151
if err := n.Slack.Validate(); err != nil {
@@ -1211,3 +1216,30 @@ type PipedEventWatcherGitRepo struct {
12111216
// This is prioritized if both includes and this one are given.
12121217
Excludes []string `json:"excludes,omitempty"`
12131218
}
1219+
1220+
type PipedPlanPreview struct {
1221+
// Number of workers to handle plan-preview commands.
1222+
WorkerNum int `json:"workerNum,omitempty"`
1223+
// Channel buffer size used for plan-preview commands.
1224+
CommandQueueBufferSize int `json:"commandQueueBufferSize,omitempty"`
1225+
// Interval to fetch plan-preview commands.
1226+
CommandCheckInterval Duration `json:"commandCheckInterval,omitempty"`
1227+
// Timeout to handle each plan-preview command.
1228+
CommandHandleTimeout Duration `json:"commandHandleTimeout,omitempty"`
1229+
}
1230+
1231+
func (p *PipedPlanPreview) Validate() error {
1232+
if p.WorkerNum < 0 {
1233+
return errors.New("planPreview.workerNum must be greater than or equal to 0")
1234+
}
1235+
if p.CommandQueueBufferSize < 0 {
1236+
return errors.New("planPreview.commandQueueBufferSize must be greater than or equal to 0")
1237+
}
1238+
if p.CommandCheckInterval < 0 {
1239+
return errors.New("planPreview.commandCheckInterval must be greater than or equal to 0")
1240+
}
1241+
if p.CommandHandleTimeout < 0 {
1242+
return errors.New("planPreview.commandHandleTimeout must be greater than or equal to 0")
1243+
}
1244+
return nil
1245+
}

pkg/config/piped_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,12 @@ func TestPipedConfig(t *testing.T) {
361361
},
362362
},
363363
},
364+
PlanPreview: PipedPlanPreview{
365+
WorkerNum: 5,
366+
CommandQueueBufferSize: 20,
367+
CommandCheckInterval: Duration(5 * time.Second),
368+
CommandHandleTimeout: Duration(10 * time.Minute),
369+
},
364370
},
365371
expectedError: nil,
366372
},
@@ -378,6 +384,95 @@ func TestPipedConfig(t *testing.T) {
378384
}
379385
}
380386

387+
func TestPipedPlanPreviewValidate(t *testing.T) {
388+
testcases := []struct {
389+
name string
390+
planPreview PipedPlanPreview
391+
wantErr bool
392+
wantPipedPlanPreview PipedPlanPreview
393+
}{
394+
{
395+
name: "negative workerNum",
396+
wantErr: true,
397+
planPreview: PipedPlanPreview{
398+
WorkerNum: -1,
399+
},
400+
wantPipedPlanPreview: PipedPlanPreview{
401+
WorkerNum: -1,
402+
},
403+
},
404+
{
405+
name: "negative commandQueueBufferSize",
406+
wantErr: true,
407+
planPreview: PipedPlanPreview{
408+
CommandQueueBufferSize: -1,
409+
},
410+
wantPipedPlanPreview: PipedPlanPreview{
411+
CommandQueueBufferSize: -1,
412+
},
413+
},
414+
{
415+
name: "negative commandCheckInterval",
416+
wantErr: true,
417+
planPreview: PipedPlanPreview{
418+
CommandCheckInterval: Duration(-time.Second),
419+
},
420+
wantPipedPlanPreview: PipedPlanPreview{
421+
CommandCheckInterval: Duration(-time.Second),
422+
},
423+
},
424+
{
425+
name: "negative commandHandleTimeout",
426+
wantErr: true,
427+
planPreview: PipedPlanPreview{
428+
CommandHandleTimeout: Duration(-time.Minute),
429+
},
430+
wantPipedPlanPreview: PipedPlanPreview{
431+
CommandHandleTimeout: Duration(-time.Minute),
432+
},
433+
},
434+
{
435+
name: "all zero",
436+
wantErr: false,
437+
planPreview: PipedPlanPreview{
438+
WorkerNum: 0,
439+
CommandQueueBufferSize: 0,
440+
CommandCheckInterval: Duration(0),
441+
CommandHandleTimeout: Duration(0),
442+
},
443+
wantPipedPlanPreview: PipedPlanPreview{
444+
WorkerNum: 0,
445+
CommandQueueBufferSize: 0,
446+
CommandCheckInterval: Duration(0),
447+
CommandHandleTimeout: Duration(0),
448+
},
449+
},
450+
{
451+
name: "valid values",
452+
wantErr: false,
453+
planPreview: PipedPlanPreview{
454+
WorkerNum: 5,
455+
CommandQueueBufferSize: 20,
456+
CommandCheckInterval: Duration(5 * time.Second),
457+
CommandHandleTimeout: Duration(10 * time.Minute),
458+
},
459+
wantPipedPlanPreview: PipedPlanPreview{
460+
WorkerNum: 5,
461+
CommandQueueBufferSize: 20,
462+
CommandCheckInterval: Duration(5 * time.Second),
463+
CommandHandleTimeout: Duration(10 * time.Minute),
464+
},
465+
},
466+
}
467+
for _, tc := range testcases {
468+
t.Run(tc.name, func(t *testing.T) {
469+
err := tc.planPreview.Validate()
470+
assert.Equal(t, tc.wantErr, err != nil)
471+
assert.Equal(t, tc.wantPipedPlanPreview, tc.planPreview)
472+
})
473+
}
474+
}
475+
381476
func TestPipedEventWatcherValidate(t *testing.T) {
382477
testcases := []struct {
383478
name string
@@ -1137,6 +1232,12 @@ func TestPipedSpecClone(t *testing.T) {
11371232
},
11381233
},
11391234
},
1235+
PlanPreview: PipedPlanPreview{
1236+
WorkerNum: 5,
1237+
CommandQueueBufferSize: 20,
1238+
CommandCheckInterval: Duration(5 * time.Second),
1239+
CommandHandleTimeout: Duration(10 * time.Minute),
1240+
},
11401241
},
11411242
expectedSpec: &PipedSpec{
11421243
ProjectID: "test-project",
@@ -1335,6 +1436,12 @@ func TestPipedSpecClone(t *testing.T) {
13351436
},
13361437
},
13371438
},
1439+
PlanPreview: PipedPlanPreview{
1440+
WorkerNum: 5,
1441+
CommandQueueBufferSize: 20,
1442+
CommandCheckInterval: Duration(5 * time.Second),
1443+
CommandHandleTimeout: Duration(10 * time.Minute),
1444+
},
13381445
},
13391446
expectedError: nil,
13401447
},

pkg/config/testdata/piped/piped-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,9 @@ spec:
243243
includes:
244244
- event-watcher-dev.yaml
245245
- event-watcher-stg.yaml
246+
247+
planPreview:
248+
workerNum: 5
249+
commandQueueBufferSize: 20
250+
commandCheckInterval: 5s
251+
commandHandleTimeout: 10m

pkg/configv1/piped.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ type PipedSpec struct {
6464
SecretManagement *SecretManagement `json:"secretManagement,omitempty"`
6565
// Optional settings for event watcher.
6666
EventWatcher PipedEventWatcher `json:"eventWatcher"`
67+
// Optional settings for plan-preview command handling.
68+
PlanPreview PipedPlanPreview `json:"planPreview"`
6769
// List of labels to filter all applications this piped will handle.
6870
AppSelector map[string]string `json:"appSelector,omitempty"`
6971
}
@@ -113,6 +115,9 @@ func (s *PipedSpec) Validate() error {
113115
if err := s.EventWatcher.Validate(); err != nil {
114116
return err
115117
}
118+
if err := s.PlanPreview.Validate(); err != nil {
119+
return err
120+
}
116121
for _, n := range s.Notifications.Receivers {
117122
if n.Slack != nil {
118123
if err := n.Slack.Validate(); err != nil {
@@ -632,6 +637,33 @@ type PipedEventWatcherGitRepo struct {
632637
Excludes []string `json:"excludes,omitempty"`
633638
}
634639

640+
type PipedPlanPreview struct {
641+
// Number of workers to handle plan-preview commands.
642+
WorkerNum int `json:"workerNum,omitempty"`
643+
// Channel buffer size used for plan-preview commands.
644+
CommandQueueBufferSize int `json:"commandQueueBufferSize,omitempty"`
645+
// Interval to fetch plan-preview commands.
646+
CommandCheckInterval Duration `json:"commandCheckInterval,omitempty"`
647+
// Timeout to handle each plan-preview command.
648+
CommandHandleTimeout Duration `json:"commandHandleTimeout,omitempty"`
649+
}
650+
651+
func (p *PipedPlanPreview) Validate() error {
652+
if p.WorkerNum < 0 {
653+
return errors.New("planPreview.workerNum must be greater than or equal to 0")
654+
}
655+
if p.CommandQueueBufferSize < 0 {
656+
return errors.New("planPreview.commandQueueBufferSize must be greater than or equal to 0")
657+
}
658+
if p.CommandCheckInterval < 0 {
659+
return errors.New("planPreview.commandCheckInterval must be greater than or equal to 0")
660+
}
661+
if p.CommandHandleTimeout < 0 {
662+
return errors.New("planPreview.commandHandleTimeout must be greater than or equal to 0")
663+
}
664+
return nil
665+
}
666+
635667
// PipedPlugin defines the plugin configuration for the piped.
636668
type PipedPlugin struct {
637669
// The name of the plugin.

0 commit comments

Comments
 (0)