@@ -81,73 +81,72 @@ func (h *WebhookHandler) Handle(ctx context.Context, req admission.Request) admi
81
81
},
82
82
}
83
83
84
- // Collect all checks in parallel.
85
- checkerWG := & sync.WaitGroup {}
86
- resultCh := make (chan CheckResult )
87
- for _ , checker := range h .checkers {
88
- checkerWG .Add (1 )
89
-
90
- go func (ctx context.Context , checker Checker , resultCh chan CheckResult ) {
91
- // Initialize the checker.
92
- checks := checker .Init (ctx , h .client , cluster )
93
-
94
- // Run its checks in parallel.
95
- checksWG := & sync.WaitGroup {}
96
- for _ , check := range checks {
97
- checksWG .Add (1 )
98
- go func (ctx context.Context , check Check , resultCh chan CheckResult ) {
99
- result := check (ctx )
100
- resultCh <- result
101
- checksWG .Done ()
102
- }(ctx , check , resultCh )
103
- }
104
- checksWG .Wait ()
105
-
106
- checkerWG .Done ()
107
- }(ctx , checker , resultCh )
108
- }
84
+ results := run (ctx , h .client , cluster , h .checkers )
109
85
110
- // Close the channel when all checkers are done.
111
- go func (wg * sync.WaitGroup , resultCh chan CheckResult ) {
112
- wg .Wait ()
113
- close (resultCh )
114
- }(checkerWG , resultCh )
115
-
116
- // Collect all check results from the channel.
86
+ // Summarize the results.
117
87
internalError := false
118
- for result := range resultCh {
88
+ for _ , result := range results {
119
89
if result .Error {
120
90
internalError = true
121
91
}
122
-
123
92
if ! result .Allowed {
124
93
resp .Allowed = false
125
94
}
126
-
127
95
for _ , cause := range result .Causes {
128
96
resp .Result .Details .Causes = append (resp .Result .Details .Causes , metav1.StatusCause {
129
97
Type : metav1 .CauseType (fmt .Sprintf ("FailedPreflight%s" , result .Name )),
130
98
Message : cause .Message ,
131
99
Field : cause .Field ,
132
100
})
133
101
}
134
-
135
102
resp .Warnings = append (resp .Warnings , result .Warnings ... )
136
103
}
137
104
138
- if len (resp .Result .Details .Causes ) == 0 {
139
- return resp
140
- }
141
-
142
- // Because we have some causes, we construct the response message and code.
143
- resp .Result .Message = "preflight checks failed"
144
- resp .Result .Code = http .StatusForbidden
145
- resp .Result .Reason = metav1 .StatusReasonForbidden
146
- if internalError {
105
+ switch {
106
+ case internalError :
147
107
// Internal errors take precedence over check failures.
108
+ resp .Result .Message = "preflight checks failed due to an internal error"
148
109
resp .Result .Code = http .StatusInternalServerError
149
110
resp .Result .Reason = metav1 .StatusReasonInternalError
111
+ case ! resp .Allowed :
112
+ // Because the response is not allowed, preflights must have failed.
113
+ resp .Result .Message = "preflight checks failed"
114
+ resp .Result .Code = http .StatusUnprocessableEntity
115
+ resp .Result .Reason = metav1 .StatusReasonInvalid
150
116
}
151
117
152
118
return resp
153
119
}
120
+
121
+ func run (ctx context.Context , client ctrlclient.Client , cluster * clusterv1.Cluster , checkers []Checker ) []CheckResult {
122
+ resultsOrderedByCheckerAndCheck := make ([][]CheckResult , len (checkers ))
123
+
124
+ checkersWG := sync.WaitGroup {}
125
+ for i , checker := range checkers {
126
+ checkersWG .Add (1 )
127
+ go func (ctx context.Context , client ctrlclient.Client , cluster * clusterv1.Cluster , checker Checker , i int ) {
128
+ checks := checker .Init (ctx , client , cluster )
129
+ resultsOrderedByCheck := make ([]CheckResult , len (checks ))
130
+
131
+ checksWG := sync.WaitGroup {}
132
+ for j , check := range checks {
133
+ checksWG .Add (1 )
134
+ go func (ctx context.Context , check Check , j int ) {
135
+ result := check (ctx )
136
+ resultsOrderedByCheck [j ] = result
137
+ checksWG .Done ()
138
+ }(ctx , check , j )
139
+ }
140
+ checksWG .Wait ()
141
+ resultsOrderedByCheckerAndCheck [i ] = resultsOrderedByCheck
142
+ checkersWG .Done ()
143
+ }(ctx , client , cluster , checker , i )
144
+ }
145
+ checkersWG .Wait ()
146
+
147
+ results := []CheckResult {}
148
+ for _ , resultsByCheck := range resultsOrderedByCheckerAndCheck {
149
+ results = append (results , resultsByCheck ... )
150
+ }
151
+ return results
152
+ }
0 commit comments