@@ -12,8 +12,6 @@ import (
1212 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1313 ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
1414 "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
15-
16- "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/utils"
1715)
1816
1917type CheckResult struct {
@@ -28,23 +26,19 @@ type Check = func(ctx context.Context) CheckResult
2826
2927type Checker interface {
3028 Checks (ctx context.Context , client ctrlclient.Client , cluster * clusterv1.Cluster ) ([]Check , error )
31- Provider () string
3229}
3330
3431type WebhookHandler struct {
35- client ctrlclient.Client
36- decoder admission.Decoder
37- checkersByProvider map [ string ]Checker
32+ client ctrlclient.Client
33+ decoder admission.Decoder
34+ checkers [ ]Checker
3835}
3936
4037func New (client ctrlclient.Client , decoder admission.Decoder , checkers ... Checker ) * WebhookHandler {
4138 h := & WebhookHandler {
42- client : client ,
43- decoder : decoder ,
44- checkersByProvider : make (map [string ]Checker , len (checkers )),
45- }
46- for _ , checker := range checkers {
47- h .checkersByProvider [checker .Provider ()] = checker
39+ client : client ,
40+ decoder : decoder ,
41+ checkers : checkers ,
4842 }
4943 return h
5044}
@@ -65,12 +59,6 @@ func (h *WebhookHandler) Handle(ctx context.Context, req admission.Request) admi
6559 return admission .Allowed ("" )
6660 }
6761
68- // Checks run only for the known infrastructure providers.
69- checker , ok := h .checkersByProvider [utils .GetProvider (cluster )]
70- if ! ok {
71- return admission .Allowed ("" )
72- }
73-
7462 resp := admission.Response {
7563 AdmissionResponse : admissionv1.AdmissionResponse {
7664 Allowed : true ,
@@ -80,26 +68,43 @@ func (h *WebhookHandler) Handle(ctx context.Context, req admission.Request) admi
8068 },
8169 }
8270
83- checks , err := checker .Checks (ctx , h .client , cluster )
84- if err != nil {
85- resp .Allowed = false
86- resp .Result .Code = http .StatusInternalServerError
87- resp .Result .Message = "failed to initialize preflight checks"
88- resp .Result .Details .Causes = append (resp .Result .Details .Causes , metav1.StatusCause {
89- Type : metav1 .CauseTypeInternal ,
90- Message : err .Error (),
91- Field : "" , // This concerns the whole cluster.
92- })
93- return resp
71+ // Initialize checkers in parallel.
72+ type ChecksResult struct {
73+ checks []Check
74+ err error
9475 }
76+ checksResultCh := make (chan ChecksResult , len (h .checkers ))
9577
96- if len (checks ) == 0 {
97- return admission .Allowed ("" )
78+ wg := & sync.WaitGroup {}
79+ for _ , checker := range h .checkers {
80+ wg .Add (1 )
81+ result := ChecksResult {}
82+ result .checks , result .err = checker .Checks (ctx , h .client , cluster )
83+ checksResultCh <- result
84+ wg .Done ()
9885 }
86+ wg .Wait ()
87+ close (checksResultCh )
9988
100- // Run all checks and collect results.
89+ // Collect all checks.
90+ checks := make ([]Check , 0 )
91+ for checksResult := range checksResultCh {
92+ if checksResult .err != nil {
93+ resp .Allowed = false
94+ resp .Result .Code = http .StatusInternalServerError
95+ resp .Result .Message = "failed to initialize preflight checks"
96+ resp .Result .Details .Causes = append (resp .Result .Details .Causes , metav1.StatusCause {
97+ Type : metav1 .CauseTypeInternal ,
98+ Message : checksResult .err .Error (),
99+ Field : "" , // This concerns the whole cluster.
100+ })
101+ continue
102+ }
103+ checks = append (checks , checksResult .checks ... )
104+ }
105+
106+ // Run all checks in parallel.
101107 resultCh := make (chan CheckResult , len (checks ))
102- wg := & sync.WaitGroup {}
103108 for _ , check := range checks {
104109 wg .Add (1 )
105110 go func (ctx context.Context , check Check ) {
@@ -111,6 +116,7 @@ func (h *WebhookHandler) Handle(ctx context.Context, req admission.Request) admi
111116 wg .Wait ()
112117 close (resultCh )
113118
119+ // Collect check results.
114120 for result := range resultCh {
115121 if result .Error {
116122 resp .Allowed = false
0 commit comments