Skip to content

Commit e100d6b

Browse files
mooneksilvacarloss
authored andcommitted
[manila-csi-plugin] support muilple share rules
Signed-off-by: moonek <[email protected]>
1 parent b55fbc4 commit e100d6b

File tree

4 files changed

+101
-74
lines changed

4 files changed

+101
-74
lines changed

pkg/csi/manila/controllerserver.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,18 +194,24 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
194194

195195
ad := getShareAdapter(shareOpts.Protocol)
196196

197-
accessRight, err := ad.GetOrGrantAccess(ctx, &shareadapters.GrantAccessArgs{Share: share, ManilaClient: manilaClient, Options: shareOpts})
197+
accessRights, err := ad.GetOrGrantAccesses(ctx, &shareadapters.GrantAccessArgs{Share: share, ManilaClient: manilaClient, Options: shareOpts})
198198
if err != nil {
199199
if wait.Interrupted(err) {
200-
return nil, status.Errorf(codes.DeadlineExceeded, "deadline exceeded while waiting for access rule %s for volume %s to become available", accessRight.ID, share.Name)
200+
return nil, status.Errorf(codes.DeadlineExceeded, "deadline exceeded while waiting for access rules for volume %s to become available", share.Name)
201201
}
202202

203203
return nil, status.Errorf(codes.Internal, "failed to grant access to volume %s: %v", share.Name, err)
204204
}
205205

206+
var accessRightIDs []string
207+
for _, ar := range accessRights {
208+
accessRightIDs = append(accessRightIDs, ar.ID)
209+
}
210+
shareAccessIDs := strings.Join(accessRightIDs, ",")
211+
206212
volCtx := filterParametersForVolumeContext(params, options.NodeVolumeContextFields())
207213
volCtx = util.SetMapIfNotEmpty(volCtx, "shareID", share.ID)
208-
volCtx = util.SetMapIfNotEmpty(volCtx, "shareAccessID", accessRight.ID)
214+
volCtx = util.SetMapIfNotEmpty(volCtx, "shareAccessIDs", shareAccessIDs)
209215
volCtx = util.SetMapIfNotEmpty(volCtx, "groupID", share.ShareGroupID)
210216
volCtx = util.SetMapIfNotEmpty(volCtx, "affinity", shareOpts.Affinity)
211217
volCtx = util.SetMapIfNotEmpty(volCtx, "antiAffinity", shareOpts.AntiAffinity)

pkg/csi/manila/shareadapters/cephfs.go

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package shareadapters
1919
import (
2020
"context"
2121
"fmt"
22+
"strings"
2223
"time"
2324

2425
"github.com/gophercloud/gophercloud/v2"
@@ -32,82 +33,81 @@ type Cephfs struct{}
3233

3334
var _ ShareAdapter = &Cephfs{}
3435

35-
func (Cephfs) GetOrGrantAccess(ctx context.Context, args *GrantAccessArgs) (accessRight *shares.AccessRight, err error) {
36+
func (Cephfs) GetOrGrantAccesses(ctx context.Context, args *GrantAccessArgs) ([]shares.AccessRight, error) {
3637
// First, check if the access right exists or needs to be created
3738

38-
var rights []shares.AccessRight
39-
40-
accessTo := args.Options.CephfsClientID
41-
if accessTo == "" {
42-
accessTo = args.Share.Name
43-
}
44-
45-
rights, err = args.ManilaClient.GetAccessRights(ctx, args.Share.ID)
39+
rights, err := args.ManilaClient.GetAccessRights(ctx, args.Share.ID)
4640
if err != nil {
4741
if _, ok := err.(gophercloud.ErrResourceNotFound); !ok {
4842
return nil, fmt.Errorf("failed to list access rights: %v", err)
4943
}
50-
} else {
51-
// Try to find the access right
44+
}
45+
46+
accessToList := []string{args.Share.Name}
47+
if args.Options.CephfsClientID != "" {
48+
accessToList = strings.Split(args.Options.CephfsClientID, ",")
49+
}
5250

51+
created := false
52+
for _, at := range accessToList {
53+
// Try to find the access right
54+
found := false
5355
for _, r := range rights {
54-
if r.AccessTo == accessTo && r.AccessType == "cephx" && r.AccessLevel == "rw" {
56+
if r.AccessTo == at && r.AccessType == "cephx" && r.AccessLevel == "rw" {
5557
klog.V(4).Infof("cephx access right for share %s already exists", args.Share.Name)
56-
57-
accessRight = &r
58+
found = true
5859
break
5960
}
6061
}
61-
}
6262

63-
if accessRight == nil {
6463
// Not found, create it
65-
66-
accessRight, err = args.ManilaClient.GrantAccess(ctx, args.Share.ID, shares.GrantAccessOpts{
67-
AccessType: "cephx",
68-
AccessLevel: "rw",
69-
AccessTo: accessTo,
70-
})
71-
72-
if err != nil {
73-
return
64+
if !found {
65+
result, err := args.ManilaClient.GrantAccess(ctx, args.Share.ID, shares.GrantAccessOpts{
66+
AccessType: "cephx",
67+
AccessLevel: "rw",
68+
AccessTo: at,
69+
})
70+
if err != nil {
71+
return nil, fmt.Errorf("failed to grant access right: %v", err)
72+
}
73+
if result.AccessKey == "" {
74+
// Wait till a ceph key is assigned to the access right
75+
backoff := wait.Backoff{
76+
Duration: time.Second * 5,
77+
Factor: 1.2,
78+
Steps: 10,
79+
}
80+
wait.ExponentialBackoff(backoff, func() (bool, error) {
81+
rights, err := args.ManilaClient.GetAccessRights(ctx, args.Share.ID)
82+
if err != nil {
83+
return false, fmt.Errorf("error get access rights for share %s: %v", args.Share.ID, err)
84+
}
85+
if len(rights) == 0 {
86+
return false, fmt.Errorf("cannot find the access right we've just created")
87+
}
88+
for _, r := range rights {
89+
if r.AccessTo == at && r.AccessKey != "" {
90+
return true, nil
91+
}
92+
}
93+
klog.V(4).Infof("Access key for %s is not set yet, retrying...", at)
94+
return false, nil
95+
})
96+
}
97+
created = true
7498
}
7599
}
76100

77-
if accessRight.AccessKey != "" {
78-
// The access right is ready
79-
return
80-
}
81-
82-
// Wait till a ceph key is assigned to the access right
83-
84-
backoff := wait.Backoff{
85-
Duration: time.Second * 5,
86-
Factor: 1.2,
87-
Steps: 10,
88-
}
89-
90-
return accessRight, wait.ExponentialBackoff(backoff, func() (bool, error) {
91-
rights, err := args.ManilaClient.GetAccessRights(ctx, args.Share.ID)
101+
// Search again because access rights have changed
102+
if created {
103+
rights, err = args.ManilaClient.GetAccessRights(ctx, args.Share.ID)
92104
if err != nil {
93-
return false, err
94-
}
95-
96-
var accessRight *shares.AccessRight
97-
98-
for i := range rights {
99-
if rights[i].AccessTo == accessTo {
100-
accessRight = &rights[i]
101-
break
105+
if _, ok := err.(gophercloud.ErrResourceNotFound); !ok {
106+
return nil, fmt.Errorf("failed to list access rights: %v", err)
102107
}
103108
}
104-
105-
if accessRight == nil {
106-
return false, fmt.Errorf("cannot find the access right we've just created")
107-
}
108-
109-
return accessRight.AccessKey != "", nil
110-
})
109+
}
110+
return rights, nil
111111
}
112112

113113
func (Cephfs) BuildVolumeContext(args *VolumeContextArgs) (volumeContext map[string]string, err error) {

pkg/csi/manila/shareadapters/nfs.go

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type NFS struct{}
3333

3434
var _ ShareAdapter = &NFS{}
3535

36-
func (NFS) GetOrGrantAccess(ctx context.Context, args *GrantAccessArgs) (*shares.AccessRight, error) {
36+
func (NFS) GetOrGrantAccesses(ctx context.Context, args *GrantAccessArgs) ([]shares.AccessRight, error) {
3737
// First, check if the access right exists or needs to be created
3838

3939
rights, err := args.ManilaClient.GetAccessRights(ctx, args.Share.ID)
@@ -43,22 +43,43 @@ func (NFS) GetOrGrantAccess(ctx context.Context, args *GrantAccessArgs) (*shares
4343
}
4444
}
4545

46-
// Try to find the access right
47-
48-
for _, r := range rights {
49-
if r.AccessTo == args.Options.NFSShareClient && r.AccessType == "ip" && r.AccessLevel == "rw" {
50-
klog.V(4).Infof("IP access right for share %s already exists", args.Share.Name)
51-
return &r, nil
46+
accessToList := strings.Split(args.Options.NFSShareClient, ",")
47+
48+
created := false
49+
for _, at := range accessToList {
50+
// Try to find the access right
51+
found := false
52+
for _, r := range rights {
53+
if r.AccessTo == at && r.AccessType == "ip" && r.AccessLevel == "rw" {
54+
klog.V(4).Infof("IP access right %s for share %s already exists", at, args.Share.Name)
55+
found = true
56+
break
57+
}
58+
}
59+
// Not found, create it
60+
if !found {
61+
_, err = args.ManilaClient.GrantAccess(ctx, args.Share.ID, shares.GrantAccessOpts{
62+
AccessType: "ip",
63+
AccessLevel: "rw",
64+
AccessTo: at,
65+
})
66+
if err != nil {
67+
return nil, fmt.Errorf("failed to grant access right: %v", err)
68+
}
69+
created = true
5270
}
5371
}
5472

55-
// Not found, create it
56-
57-
return args.ManilaClient.GrantAccess(ctx, args.Share.ID, shares.GrantAccessOpts{
58-
AccessType: "ip",
59-
AccessLevel: "rw",
60-
AccessTo: args.Options.NFSShareClient,
61-
})
73+
// Search again because access rights have changed
74+
if created {
75+
rights, err = args.ManilaClient.GetAccessRights(ctx, args.Share.ID)
76+
if err != nil {
77+
if _, ok := err.(gophercloud.ErrResourceNotFound); !ok {
78+
return nil, fmt.Errorf("failed to list access rights: %v", err)
79+
}
80+
}
81+
}
82+
return rights, nil
6283
}
6384

6485
func (NFS) BuildVolumeContext(args *VolumeContextArgs) (volumeContext map[string]string, err error) {

pkg/csi/manila/shareadapters/shareadapter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type ShareAdapter interface {
4646
// GetOrGrantAccess first tries to retrieve an access right for args.Share.
4747
// An access right is created for the share in case it doesn't exist yet.
4848
// Returns an existing or new access right for args.Share.
49-
GetOrGrantAccess(ctx context.Context, args *GrantAccessArgs) (accessRight *shares.AccessRight, err error)
49+
GetOrGrantAccesses(ctx context.Context, args *GrantAccessArgs) (accessRights []shares.AccessRight, err error)
5050

5151
// BuildVolumeContext builds a volume context map that's passed to NodeStageVolumeRequest and NodePublishVolumeRequest
5252
BuildVolumeContext(args *VolumeContextArgs) (volumeContext map[string]string, err error)

0 commit comments

Comments
 (0)