/
nfs.go
109 lines (91 loc) · 2.84 KB
/
nfs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package controller
import (
"context"
"encoding/json"
"fmt"
"path"
"google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
"github.com/dravanet/truenas-csi/pkg/config"
TruenasOapi "github.com/dravanet/truenas-csi/pkg/truenas"
"github.com/dravanet/truenas-csi/pkg/volumecontext"
)
func (cs *server) createNFSVolume(ctx context.Context, cl *TruenasOapi.Client, nfs *config.NFS, reqName string, dataset string) (
volumeContext *volumecontext.VolumeContext,
err error) {
paths := []string{path.Join("/mnt", dataset)}
share, err := cs.getNFSShareByComment(ctx, cl, reqName)
if err != nil {
return
}
if share == nil {
enabled := true
maprootuser := "root"
maprootgroup := "wheel"
if _, err = handleNasResponse(cl.PostSharingNfs(ctx, TruenasOapi.PostSharingNfsJSONRequestBody{
Enabled: &enabled,
Paths: &paths,
Comment: &reqName,
Hosts: &nfs.AllowedHosts,
Networks: &nfs.AllowedNetworks,
MaprootUser: &maprootuser,
MaprootGroup: &maprootgroup,
})); err != nil {
return
}
} else {
if len(share.Paths) != 1 {
return nil, fmt.Errorf("share %q uses more paths", reqName)
}
if share.Paths[0] != paths[0] {
return nil, fmt.Errorf("share %q uses dataset %q (expected: %q)", reqName, share.Paths[0], paths[0])
}
}
volumeContext = &volumecontext.VolumeContext{
Nfs: &volumecontext.NFS{
Address: fmt.Sprintf("%s:%s", nfs.Server, paths[0]),
},
}
return
}
func (cs *server) deleteNFSVolume(ctx context.Context, cl *TruenasOapi.Client, di *datasetInfo) error {
// Lookup nfs share
share, err := cs.getNFSShareByComment(ctx, cl, di.Comments)
if err != nil {
return err
}
if share != nil {
// Delete nfs share
if _, err = handleNasResponse(cl.DeleteSharingNfsIdId(ctx, *share.ID)); err != nil {
return err
}
}
return nil
}
type nfsShare struct {
ID *int `json:"id"`
Comment *string `json:"comment"`
Paths []string `json:"paths"`
}
func (cs *server) getNFSShareByComment(ctx context.Context, cl *TruenasOapi.Client, comment string) (share *nfsShare, err error) {
var nfsshareresp []byte
if nfsshareresp, err = handleNasResponse(cl.GetSharingNfs(ctx, &TruenasOapi.GetSharingNfsParams{}, truenasOapiFilter("comment", comment))); err != nil {
return
}
var shares []nfsShare
if err = json.Unmarshal(nfsshareresp, &shares); err != nil {
return nil, status.Error(codes.Unavailable, "Error parsing NAS response")
}
if len(shares) > 1 {
return nil, status.Errorf(codes.Unavailable, "Unexpected data returned from NAS, multiple items have same comment: %+v", shares)
}
if len(shares) == 1 {
if shares[0].Comment == nil || *shares[0].Comment != comment {
return nil, status.Errorf(codes.Unavailable, "Unexpected data returned from NAS, seems like filtering does not work: %+v", shares)
}
}
if len(shares) == 1 {
share = &shares[0]
}
return
}