Skip to content

Commit 7e1aa64

Browse files
committed
[manila-csi-plugin] support muilple share rules
Signed-off-by: moonek <[email protected]>
1 parent d3f9104 commit 7e1aa64

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
@@ -193,18 +193,24 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
193193

194194
ad := getShareAdapter(shareOpts.Protocol)
195195

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

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

205+
var accessRightIDs []string
206+
for _, ar := range accessRights {
207+
accessRightIDs = append(accessRightIDs, ar.ID)
208+
}
209+
shareAccessIDs := strings.Join(accessRightIDs, ",")
210+
205211
volCtx := filterParametersForVolumeContext(params, options.NodeVolumeContextFields())
206212
volCtx = util.SetMapIfNotEmpty(volCtx, "shareID", share.ID)
207-
volCtx = util.SetMapIfNotEmpty(volCtx, "shareAccessID", accessRight.ID)
213+
volCtx = util.SetMapIfNotEmpty(volCtx, "shareAccessIDs", shareAccessIDs)
208214
volCtx = util.SetMapIfNotEmpty(volCtx, "groupID", share.ShareGroupID)
209215
volCtx = util.SetMapIfNotEmpty(volCtx, "affinity", shareOpts.Affinity)
210216
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
@@ -18,6 +18,7 @@ package shareadapters
1818

1919
import (
2020
"fmt"
21+
"strings"
2122
"time"
2223

2324
"github.com/gophercloud/gophercloud/v2"
@@ -31,82 +32,81 @@ type Cephfs struct{}
3132

3233
var _ ShareAdapter = &Cephfs{}
3334

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

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

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

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

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

112112
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
@@ -32,7 +32,7 @@ type NFS struct{}
3232

3333
var _ ShareAdapter = &NFS{}
3434

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

3838
rights, err := args.ManilaClient.GetAccessRights(args.Share.ID)
@@ -42,22 +42,43 @@ func (NFS) GetOrGrantAccess(args *GrantAccessArgs) (*shares.AccessRight, error)
4242
}
4343
}
4444

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

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

6384
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
@@ -44,7 +44,7 @@ type ShareAdapter interface {
4444
// GetOrGrantAccess first tries to retrieve an access right for args.Share.
4545
// An access right is created for the share in case it doesn't exist yet.
4646
// Returns an existing or new access right for args.Share.
47-
GetOrGrantAccess(args *GrantAccessArgs) (accessRight *shares.AccessRight, err error)
47+
GetOrGrantAccesses(args *GrantAccessArgs) (accessRights []shares.AccessRight, err error)
4848

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

0 commit comments

Comments
 (0)