@@ -18,6 +18,7 @@ package controller
1818
1919import (
2020 "context"
21+ "encoding/json"
2122 "errors"
2223 "fmt"
2324 "net/url"
@@ -26,6 +27,7 @@ import (
2627
2728 csiaddonsv1alpha1 "github.com/csi-addons/kubernetes-csi-addons/api/csiaddons/v1alpha1"
2829 "github.com/csi-addons/kubernetes-csi-addons/internal/connection"
30+ "github.com/csi-addons/kubernetes-csi-addons/internal/proto"
2931 "github.com/csi-addons/kubernetes-csi-addons/internal/util"
3032 "github.com/csi-addons/spec/lib/go/identity"
3133
@@ -138,6 +140,13 @@ func (r *CSIAddonsNodeReconciler) Reconcile(ctx context.Context, req ctrl.Reques
138140 return ctrl.Result {}, err
139141 }
140142
143+ nfsc , err := r .getNetworkFenceClientStatus (ctx , & logger , newConn , csiAddonsNode )
144+ if err != nil {
145+ return ctrl.Result {}, err
146+ }
147+
148+ csiAddonsNode .Status .NetworkFenceClientStatus = nfsc
149+
141150 logger .Info ("Successfully connected to sidecar" )
142151 r .ConnPool .Put (key , newConn )
143152 logger .Info ("Added connection to connection pool" , "Key" , key )
@@ -155,11 +164,122 @@ func (r *CSIAddonsNodeReconciler) Reconcile(ctx context.Context, req ctrl.Reques
155164 return ctrl.Result {}, nil
156165}
157166
167+ // getNetworkFenceClassesForDriver gets the networkfenceclasses for the driver.
168+ func (r * CSIAddonsNodeReconciler ) getNetworkFenceClassesForDriver (ctx context.Context , logger * logr.Logger ,
169+ instance * csiaddonsv1alpha1.CSIAddonsNode ) ([]csiaddonsv1alpha1.NetworkFenceClass , error ) {
170+ // get the networkfenceclasses from the annotation
171+ nfclasses := make ([]csiaddonsv1alpha1.NetworkFenceClass , 0 )
172+ classesJSON , ok := instance .GetAnnotations ()[networkFenceClassAnnotationKey ]
173+ if ! ok {
174+ logger .Info ("No networkfenceclasses found in annotation" )
175+ return nfclasses , nil
176+ }
177+
178+ var classes []string
179+
180+ // Unmarshal the existing JSON into a slice of strings.
181+ if err := json .Unmarshal ([]byte (classesJSON ), & classes ); err != nil {
182+ logger .Error (err , "Failed to unmarshal existing networkFenceClasses annotation" , "name" , instance .Name )
183+ return nfclasses , err
184+ }
185+
186+ for _ , class := range classes {
187+ logger .Info ("Found networkfenceclass " , "name" , class )
188+ nfc := csiaddonsv1alpha1.NetworkFenceClass {}
189+ err := r .Client .Get (ctx , client.ObjectKey {Name : class }, & nfc )
190+ if err != nil {
191+ logger .Error (err , "Failed to get networkfenceclass" , "name" , class )
192+ return nil , err
193+ }
194+ nfclasses = append (nfclasses , nfc )
195+ }
196+
197+ return nfclasses , nil
198+ }
199+
200+ func (r * CSIAddonsNodeReconciler ) getNetworkFenceClientStatus (ctx context.Context , logger * logr.Logger , conn * connection.Connection , csiAddonsNode * csiaddonsv1alpha1.CSIAddonsNode ) ([]csiaddonsv1alpha1.NetworkFenceClientStatus , error ) {
201+
202+ nfclasses , err := r .getNetworkFenceClassesForDriver (ctx , logger , csiAddonsNode )
203+ if err != nil {
204+ logger .Error (err , "Failed to get network fence classes" )
205+ return nil , err
206+ }
207+
208+ var nfsc []csiaddonsv1alpha1.NetworkFenceClientStatus
209+
210+ for _ , nfc := range nfclasses {
211+ clients , err := getFenceClientDetails (ctx , conn , logger , nfc )
212+ if err != nil {
213+ logger .Error (err , "Failed to get clients to fence" , "networkFenceClass" , nfc .Name )
214+ return nil , err
215+ }
216+
217+ // If no clients are found, skip this network fence class
218+ if clients == nil {
219+ continue
220+ }
221+
222+ // process the client details for this network fence class
223+ clientDetails := r .getClientDetails (clients )
224+ nfsc = append (nfsc , csiaddonsv1alpha1.NetworkFenceClientStatus {
225+ NetworkFenceClassName : nfc .Name ,
226+ ClientDetails : clientDetails ,
227+ })
228+ }
229+
230+ return nfsc , nil
231+ }
232+
233+ // getClientDetails processes the client details to create the necessary status
234+ func (r * CSIAddonsNodeReconciler ) getClientDetails (clients * proto.FenceClientsResponse ) []csiaddonsv1alpha1.ClientDetail {
235+ var clientDetails []csiaddonsv1alpha1.ClientDetail
236+ for _ , client := range clients .Clients {
237+ clientDetails = append (clientDetails , csiaddonsv1alpha1.ClientDetail {
238+ Id : client .Id ,
239+ Cidrs : client .Cidrs ,
240+ })
241+ }
242+ return clientDetails
243+ }
244+
245+ // getFenceClientDetails gets the list of clients to fence from the driver.
246+ func getFenceClientDetails (ctx context.Context , conn * connection.Connection , logger * logr.Logger , nfc csiaddonsv1alpha1.NetworkFenceClass ) (* proto.FenceClientsResponse , error ) {
247+
248+ param := nfc .Spec .Parameters
249+ secretName := param [prefixedNetworkFenceSecretNameKey ]
250+ secretNamespace := param [prefixedNetworkFenceSecretNamespaceKey ]
251+ // Remove secret from the parameters
252+ delete (param , prefixedNetworkFenceSecretNameKey )
253+ delete (param , prefixedNetworkFenceSecretNamespaceKey )
254+
255+ // check if the driver contains the GET_CLIENTS_TO_FENCE capability
256+ // if it does, we need to get the list of clients to fence
257+ for _ , cap := range conn .Capabilities {
258+ if cap .GetNetworkFence () != nil &&
259+ cap .GetNetworkFence ().GetType () == identity .Capability_NetworkFence_GET_CLIENTS_TO_FENCE {
260+ logger .Info ("Driver support GET_CLIENTS_TO_FENCE capability" )
261+ client := proto .NewNetworkFenceClient (conn .Client )
262+ req := & proto.FenceClientsRequest {
263+ Parameters : nfc .Spec .Parameters ,
264+ SecretName : secretName ,
265+ SecretNamespace : secretNamespace ,
266+ }
267+ clients , err := client .GetFenceClients (ctx , req )
268+ if err != nil {
269+ logger .Error (err , "Failed to get clients to fence" )
270+ return nil , err
271+ }
272+ return clients , nil
273+ }
274+ }
275+ return nil , nil
276+ }
277+
158278// SetupWithManager sets up the controller with the Manager.
159279func (r * CSIAddonsNodeReconciler ) SetupWithManager (mgr ctrl.Manager , ctrlOptions controller.Options ) error {
160280 return ctrl .NewControllerManagedBy (mgr ).
161281 For (& csiaddonsv1alpha1.CSIAddonsNode {}).
162- WithEventFilter (predicate.GenerationChangedPredicate {}).
282+ WithEventFilter (predicate .Or (predicate. GenerationChangedPredicate {}, predicate. AnnotationChangedPredicate {}) ).
163283 WithOptions (ctrlOptions ).
164284 Complete (r )
165285}
0 commit comments