Skip to content

Commit

Permalink
[manila-csi-plugin] pass CreateVolumeRequest.parameters as Volume.vol…
Browse files Browse the repository at this point in the history
…ume_context (#1616) (#1624)

* validator: added Validator.Fields exposing recognized field names

* options: added NodeVolumeContextFields() to expose nodeVolumeCtxValidator.Fields

* CreateVolume: pass all recognized CreateVolumeRequest.parameters fields as Volume.volume_context

Co-authored-by: Róbert Vašek <[email protected]>
  • Loading branch information
lingxiankong and gman0 authored Aug 17, 2021
1 parent 8a51dc7 commit dbe1497
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 5 deletions.
22 changes: 17 additions & 5 deletions pkg/csi/manila/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ func getVolumeCreator(source *csi.VolumeContentSource, shareOpts *options.Contro
return nil, status.Error(codes.InvalidArgument, "invalid volume content source")
}

func filterParametersForVolumeContext(params map[string]string, recognizedFields []string) map[string]string {
volCtx := make(map[string]string)

for _, fieldName := range recognizedFields {
if val, ok := params[fieldName]; ok {
volCtx[fieldName] = val
}
}

return volCtx
}

func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
if err := validateCreateVolumeRequest(req); err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
Expand Down Expand Up @@ -150,17 +162,17 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
accessibleTopology = req.GetAccessibilityRequirements().GetPreferred()
}

volCtx := filterParametersForVolumeContext(params, options.NodeVolumeContextFields())
volCtx["shareID"] = share.ID
volCtx["shareAccessID"] = accessRight.ID

return &csi.CreateVolumeResponse{
Volume: &csi.Volume{
VolumeId: share.ID,
ContentSource: req.GetVolumeContentSource(),
AccessibleTopology: accessibleTopology,
CapacityBytes: int64(sizeInGiB) * bytesInGiB,
VolumeContext: map[string]string{
"shareID": share.ID,
"shareAccessID": accessRight.ID,
"cephfs-mounter": shareOpts.CephfsMounter,
},
VolumeContext: volCtx,
},
}, nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/csi/manila/options/shareoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ func NewNodeVolumeContext(data map[string]string) (*NodeVolumeContext, error) {

return opts, nil
}

func NodeVolumeContextFields() []string {
return nodeVolumeCtxValidator.Fields
}
13 changes: 13 additions & 0 deletions pkg/csi/manila/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type Validator struct {
nameIdxMap nameIndexMap
idxNameMap indexNameMap

// Field names in the struct.
Fields []string

valueExprs *valueExpressions
depsMap dependenciesMap
preclsMap preclusionsMap
Expand All @@ -67,13 +70,23 @@ func New(stringStruct interface{}) *Validator {
t: t,
nameIdxMap: nameIdxMap,
idxNameMap: idxNameMap,
Fields: buildFieldNames(idxNameMap),
valueExprs: buildValueExpressions(t, idxNameMap, nameIdxMap),
depsMap: buildDependenciesMap(t, idxNameMap, nameIdxMap),
preclsMap: buildPreclusionsMap(t, idxNameMap, nameIdxMap),
matchMap: buildMatchRegexMap(t),
}
}

func buildFieldNames(m indexNameMap) []string {
s := make([]string, 0, len(m))
for _, fieldName := range m {
s = append(s, string(fieldName))
}

return s
}

// Populate validates input data and populates the output struct.
func (v *Validator) Populate(data map[string]string, out interface{}) error {
if reflect.TypeOf(out).Elem() != v.t {
Expand Down
31 changes: 31 additions & 0 deletions pkg/csi/manila/validator/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,34 @@ func TestMatches(t *testing.T) {
t.Error(`matches:"true|false" violated, should succeed on matching parameter`)
}
}

func TestFieldNames(t *testing.T) {
type s struct {
A string `name:"a"`
B string `name:"b"`
}

v := New(&s{})

expected := []string{"a", "b"}

findElem := func(x string, xs []string) bool {
for _, e := range xs {
if e == x {
return true
}
}
return false
}

if len(expected) != len(v.Fields) {
t.Errorf("expected number of entries %d (%v), got %d (%v)",
len(expected), expected, len(v.Fields), v.Fields)
}

for i := range v.Fields {
if !findElem(v.Fields[i], expected) {
t.Error("found unexpected field", v.Fields[i], "; expected fields", expected, "actual fields", v.Fields)
}
}
}

0 comments on commit dbe1497

Please sign in to comment.