Skip to content

Commit 0a5f9d4

Browse files
authored
Allow for disabling any disruption kind (#903)
1 parent 8e0d322 commit 0a5f9d4

File tree

7 files changed

+52
-0
lines changed

7 files changed

+52
-0
lines changed

api/v1beta1/disruption_webhook.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"encoding/json"
1111
"errors"
1212
"fmt"
13+
"reflect"
14+
"slices"
1315
"strings"
1416
"time"
1517

@@ -47,6 +49,7 @@ var (
4749
defaultClusterThreshold float64
4850
allowNodeLevel bool
4951
allowNodeFailure bool
52+
disabledDisruptions []string
5053
handlerEnabled bool
5154
maxDuration time.Duration
5255
defaultDuration time.Duration
@@ -80,6 +83,7 @@ func (r *Disruption) SetupWebhookWithManager(setupWebhookConfig utils.SetupWebho
8083
deleteOnly = setupWebhookConfig.DeleteOnlyFlag
8184
allowNodeFailure = setupWebhookConfig.AllowNodeFailure
8285
allowNodeLevel = setupWebhookConfig.AllowNodeLevel
86+
disabledDisruptions = setupWebhookConfig.DisabledDisruptions
8387
enableSafemode = setupWebhookConfig.EnableSafemodeFlag
8488
defaultNamespaceThreshold = float64(setupWebhookConfig.NamespaceThresholdFlag) / 100.0
8589
defaultClusterThreshold = float64(setupWebhookConfig.ClusterThresholdFlag) / 100.0
@@ -232,6 +236,10 @@ func (r *Disruption) ValidateCreate() (admission.Warnings, error) {
232236
return nil, multierror.Prefix(multiErr, "ddmark: ")
233237
}
234238

239+
if err = checkForDisabledDisruptions(r); err != nil {
240+
return nil, err
241+
}
242+
235243
// handle initial safety nets
236244
if enableSafemode {
237245
if responses, err := r.initialSafetyNets(); err != nil {
@@ -663,3 +671,18 @@ func safetyNetAttemptsNodeRootDiskFailure(r *Disruption) bool {
663671

664672
return false
665673
}
674+
675+
// checkForDisabledDisruptions returns an error if `r` specifies any of the disruption kinds in setupWebhookConfig.DisabledDisruptions
676+
func checkForDisabledDisruptions(r *Disruption) error {
677+
for _, disKind := range chaostypes.DisruptionKindNames {
678+
if subspec := r.Spec.DisruptionKindPicker(disKind); reflect.ValueOf(subspec).IsNil() {
679+
continue
680+
}
681+
682+
if slices.Contains(disabledDisruptions, string(disKind)) {
683+
return fmt.Errorf("disruption kind %s is currently disabled", disKind)
684+
}
685+
}
686+
687+
return nil
688+
}

api/v1beta1/disruption_webhook_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ var _ = Describe("Disruption Webhook", func() {
285285
k8sClient = nil
286286
newDisruption = nil
287287
permittedUserGroups = map[string]struct{}{}
288+
disabledDisruptions = []string{}
288289
})
289290

290291
When("disruption has delete-only mode enable", func() {
@@ -532,6 +533,18 @@ var _ = Describe("Disruption Webhook", func() {
532533
Expect(ddmarkMock.AssertNumberOfCalls(GinkgoT(), "ValidateStructMultierror", 1)).To(BeTrue())
533534
})
534535
})
536+
537+
When("controller has network-disruptions disabled", func() {
538+
It("should return an error which denies the creation of a new disruption", func() {
539+
ddmarkMock.EXPECT().ValidateStructMultierror(mock.Anything, mock.Anything).Return(&multierror.Error{}).Once()
540+
disabledDisruptions = []string{"network-disruption"}
541+
542+
_, err := newDisruption.ValidateCreate()
543+
544+
Expect(err).Should(HaveOccurred())
545+
Expect(err.Error()).Should(HavePrefix("disruption kind network-disruption is currently disabled"))
546+
})
547+
})
535548
})
536549

537550
Describe("expectations with node disruptions", func() {

chart/templates/configmap.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ data:
7575
disruptionCronEnabled: {{ .Values.controller.disruptionCronEnabled }}
7676
disruptionRolloutEnabled: {{ .Values.controller.disruptionRolloutEnabled }}
7777
disruptionDeletionTimeout: {{ .Values.controller.disruptionDeletionTimeout }}
78+
disabledDisruptions:
79+
{{- range $index, $kind := .Values.controller.disabledDisruptions }}
80+
{{ $kind }}
81+
{{- end }}
7882
injector:
7983
image: {{ template "chaos-controller.format-image" deepCopy .Values.global.chaos.defaultImage | merge .Values.global.oci | merge .Values.injector.image }}
8084
imagePullSecrets: {{ .Values.injector.image.pullSecrets }}

chart/values.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ controller:
8989
disruptionRolloutEnabled: false
9090
disruptionDeletionTimeout: 15m # The duration after which a disruption will be marked as "stuck on removal" if its removal process exceeds this duration.
9191
aggregateToClusterRole: false # If this is true two aggregated cluster roles are created for viewing and editing (https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles)
92+
# disabledDisruptions: # List of disruption kinds to disable at admission
93+
# - dns-disruption
94+
# - node-failure
9295
injector:
9396
image:
9497
repo: chaos-injector

config/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type controllerConfig struct {
4444
DisruptionCronEnabled bool `json:"disruptionCronEnabled"`
4545
DisruptionRolloutEnabled bool `json:"disruptionRolloutEnabled"`
4646
DisruptionDeletionTimeout time.Duration `json:"disruptionDeletionTimeout"`
47+
DisabledDisruptions []string `json:"disabledDisruptions"`
4748
}
4849

4950
type controllerWebhookConfig struct {
@@ -370,6 +371,12 @@ func New(logger *zap.SugaredLogger, osArgs []string) (config, error) {
370371
return cfg, err
371372
}
372373

374+
mainFS.StringSliceVar(&cfg.Controller.DisabledDisruptions, "disabled-disruptions", []string{}, "List of Disruption Kinds to disable. These should match their kind names from types.go: e.g., `dns-disruption`, `container-failure`, etc. ")
375+
376+
if err := viper.BindPFlag("controller.disabledDisruptions", mainFS.Lookup("disabled-disruptions")); err != nil {
377+
return cfg, err
378+
}
379+
373380
mainFS.StringVar(&cfg.Controller.SafeMode.Environment, "safemode-environment", "", "Specify the 'location' this controller is run in. All disruptions must have an annotation of chaos.datadoghq.com/environment configured with this location to be allowed to create")
374381

375382
if err := viper.BindPFlag("controller.safeMode.environment", mainFS.Lookup("safemode-environment")); err != nil {

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ func main() {
340340
EnableSafemodeFlag: cfg.Controller.SafeMode.Enable,
341341
AllowNodeFailure: cfg.Controller.SafeMode.AllowNodeFailure,
342342
AllowNodeLevel: cfg.Controller.SafeMode.AllowNodeLevel,
343+
DisabledDisruptions: cfg.Controller.DisabledDisruptions,
343344
DeleteOnlyFlag: cfg.Controller.DeleteOnly,
344345
HandlerEnabledFlag: cfg.Handler.Enabled,
345346
DefaultDurationFlag: cfg.Controller.DefaultDuration,

utils/utils.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type SetupWebhookWithManagerConfig struct {
5050
EnableSafemodeFlag bool
5151
AllowNodeLevel bool
5252
AllowNodeFailure bool
53+
DisabledDisruptions []string
5354
DeleteOnlyFlag bool
5455
HandlerEnabledFlag bool
5556
DefaultDurationFlag time.Duration

0 commit comments

Comments
 (0)