Skip to content

Commit

Permalink
connection: track Namespace of driver Pods to locate Leases
Browse files Browse the repository at this point in the history
The CSIAddonsNode objects are located in the Namespace where CSI-drivers
are running. Use this Namespace in the Connection struct, so that the
Lease for a group of CSI-Addons ControllerServers can be found.

Updates: csi-addons#422
Signed-off-by: Niels de Vos <[email protected]>
  • Loading branch information
nixpanic authored and mergify[bot] committed Dec 15, 2023
1 parent b15ae1a commit f5192a6
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ help: ## Display this help.

.PHONY: manifests
manifests: controller-gen kustomize ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="{./apis/...,./cmd/...,./controllers/...,./sidecar/...}" output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="{./apis/...,./cmd/...,./controllers/...,./internal/...,./sidecar/...}" output:crd:artifacts:config=config/crd/bases
cd config/manager && $(KUSTOMIZE) edit set image controller=${CONTROLLER_IMG} rbac-proxy=${RBAC_PROXY_IMG}
$(KUSTOMIZE) build config/crd > deploy/controller/crds.yaml
$(KUSTOMIZE) build config/rbac > deploy/controller/rbac.yaml
Expand Down
8 changes: 8 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ rules:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
Expand Down
2 changes: 1 addition & 1 deletion controllers/csiaddons/csiaddonsnode_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func (r *CSIAddonsNodeReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}

logger.Info("Connecting to sidecar")
newConn, err := connection.NewConnection(ctx, endPoint, nodeID, driverName, csiAddonsNode.Name)
newConn, err := connection.NewConnection(ctx, endPoint, nodeID, driverName, csiAddonsNode.Namespace, csiAddonsNode.Name)
if err != nil {
logger.Error(err, "Failed to establish connection with sidecar")

Expand Down
8 changes: 8 additions & 0 deletions deploy/controller/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ rules:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
Expand Down
4 changes: 3 additions & 1 deletion internal/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
type Connection struct {
Client *grpc.ClientConn
Capabilities []*identity.Capability
Namespace string
Name string
NodeID string
DriverName string
Expand All @@ -38,7 +39,7 @@ type Connection struct {

// NewConnection establishes connection with sidecar, fetches capability and returns Connection object
// filled with required information.
func NewConnection(ctx context.Context, endpoint, nodeID, driverName, podName string) (*Connection, error) {
func NewConnection(ctx context.Context, endpoint, nodeID, driverName, namespace, podName string) (*Connection, error) {
opts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithIdleTimeout(time.Duration(0)),
Expand All @@ -50,6 +51,7 @@ func NewConnection(ctx context.Context, endpoint, nodeID, driverName, podName st

conn := &Connection{
Client: cc,
Namespace: namespace,
Name: podName,
NodeID: nodeID,
DriverName: driverName,
Expand Down
34 changes: 33 additions & 1 deletion internal/connection/connection_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"github.com/csi-addons/kubernetes-csi-addons/internal/util"
)

//+kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;list;watch

// ConnectionPool consists of map of Connection objects and
// methods Put, Get & Delete which operates with required rw locks
// to ensure consistency.
Expand Down Expand Up @@ -103,13 +105,43 @@ func (cp *ConnectionPool) GetByNodeID(driverName, nodeID string) map[string]*Con
return result
}

// getNamespaceByDriverName loops through the connections in the pool and
// returns the Namespace of the first connection that matches the driverName.
func (cp *ConnectionPool) getNamespaceByDriverName(driverName string) (string, error) {
cp.rwlock.RLock()
defer cp.rwlock.RUnlock()

for _, conn := range cp.pool {
if conn.DriverName != driverName {
continue
}

return conn.Namespace, nil
}

// should be impossible to get here, all Connections have a Namespace
return "", fmt.Errorf("failed to find the namespace where driver %q is running", driverName)
}

// GetLeaderByDriver finds the holder of the lease for the driver, and returns
// the connection to that particular CSI-Addons sidecar.
func (cp *ConnectionPool) GetLeaderByDriver(ctx context.Context, reconciler client.Client, driverName string) (*Connection, error) {
// detect the Namespace where the driver is deployed
ns, err := cp.getNamespaceByDriverName(driverName)
if err != nil {
return nil, err
}

// get the Lease for the driver
leaseName := util.NormalizeLeaseName(driverName) + "-csi-addons"
var lease coordination.Lease
err := reconciler.Get(ctx, client.ObjectKey{Name: leaseName}, &lease)
err = reconciler.Get(
ctx,
client.ObjectKey{
Namespace: ns,
Name: leaseName,
},
&lease)
if err != nil {
return nil, fmt.Errorf("no leader found for driver %q: %w", driverName, err)
} else if lease.Spec.HolderIdentity == nil || *lease.Spec.HolderIdentity == "" {
Expand Down

0 comments on commit f5192a6

Please sign in to comment.