Skip to content

Commit 8b8c9aa

Browse files
Madhu-1mergify[bot]
authored andcommitted
controller: get the fence client upon registration
when a csiaddons is registered, List the NFC CR's matching the provisioner name and send a request to get the client address from the csi driver and update the status with the client details. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
1 parent 9b09847 commit 8b8c9aa

File tree

1 file changed

+121
-1
lines changed

1 file changed

+121
-1
lines changed

internal/controller/csiaddons/csiaddonsnode_controller.go

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package controller
1818

1919
import (
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.
159279
func (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

Comments
 (0)