Skip to content

Commit 6abeef5

Browse files
committed
Add experimental javascript hooks
1 parent 3ec4a00 commit 6abeef5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+29474
-1
lines changed

cmd/mock-driver/main.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package main
1818
import (
1919
"flag"
2020
"fmt"
21+
"io/ioutil"
2122
"net"
2223
"os"
2324
"os/signal"
@@ -26,17 +27,20 @@ import (
2627

2728
"github.com/kubernetes-csi/csi-test/v3/driver"
2829
"github.com/kubernetes-csi/csi-test/v3/mock/service"
30+
"gopkg.in/yaml.v2"
2931
)
3032

3133
func main() {
3234
var config service.Config
35+
var hooksFile string = ""
3336
flag.BoolVar(&config.DisableAttach, "disable-attach", false, "Disables RPC_PUBLISH_UNPUBLISH_VOLUME capability.")
3437
flag.StringVar(&config.DriverName, "name", service.Name, "CSI driver name.")
3538
flag.Int64Var(&config.AttachLimit, "attach-limit", 2, "number of attachable volumes on a node")
3639
flag.BoolVar(&config.NodeExpansionRequired, "node-expand-required", false, "Enables NodeServiceCapability_RPC_EXPAND_VOLUME capacity.")
3740
flag.BoolVar(&config.DisableControllerExpansion, "disable-controller-expansion", false, "Disables ControllerServiceCapability_RPC_EXPAND_VOLUME capability.")
3841
flag.BoolVar(&config.DisableOnlineExpansion, "disable-online-expansion", false, "Disables online volume expansion capability.")
3942
flag.BoolVar(&config.PermissiveTargetPath, "permissive-target-path", false, "Allows the CO to create PublishVolumeRequest.TargetPath, which violates the CSI spec.")
43+
flag.StringVar(&hooksFile, "hooks-file", "", "JSON file with hook scripts.")
4044
flag.Parse()
4145

4246
endpoint := os.Getenv("CSI_ENDPOINT")
@@ -46,6 +50,15 @@ func main() {
4650
controllerEndpoint = endpoint
4751
}
4852

53+
if hooksFile != "" {
54+
execHooks, err := parseHooksFile(hooksFile)
55+
if err == nil {
56+
config.ExecHooks = execHooks
57+
} else {
58+
fmt.Printf("Failed to load hooks file %s: %v", hooksFile, err)
59+
}
60+
}
61+
4962
// Create mock driver
5063
s := service.New(config)
5164

@@ -198,3 +211,20 @@ func listen(endpoint string) (net.Listener, func(), error) {
198211
l, err := net.Listen(proto, addr)
199212
return l, cleanup, err
200213
}
214+
215+
func parseHooksFile(file string) (*service.Hooks, error) {
216+
var hooks service.Hooks
217+
218+
fr, err := os.Open(file)
219+
if err != nil {
220+
return nil, err
221+
}
222+
defer fr.Close()
223+
bytes, _ := ioutil.ReadAll(fr)
224+
err = yaml.UnmarshalStrict([]byte(bytes), &hooks)
225+
if err != nil {
226+
return nil, err
227+
}
228+
fmt.Printf("Hooks file %s loaded\n", file)
229+
return &hooks, err
230+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ require (
1010
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
1111
github.com/onsi/ginkgo v1.10.3
1212
github.com/onsi/gomega v1.7.1
13+
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff
1314
github.com/sirupsen/logrus v1.4.2
1415
golang.org/x/net v0.0.0-20191112182307-2180aed22343
1516
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 // indirect
1617
golang.org/x/text v0.3.2 // indirect
1718
google.golang.org/genproto v0.0.0-20191114150713-6bbd007550de // indirect
1819
google.golang.org/grpc v1.25.1
20+
gopkg.in/sourcemap.v1 v1.0.5 // indirect
1921
gopkg.in/yaml.v2 v2.2.5
2022
)

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
3434
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3535
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3636
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
37+
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA=
38+
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
3739
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
3840
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
3941
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -86,6 +88,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
8688
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
8789
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
8890
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
91+
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
92+
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
8993
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
9094
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
9195
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

mock/service/controller.go

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ func (s *service) CreateVolume(
3131
if req.VolumeCapabilities == nil {
3232
return nil, status.Error(codes.InvalidArgument, "Volume Capabilities cannot be empty")
3333
}
34-
34+
if hookVal, hookMsg := s.execHook("CreateVolumeStart"); hookVal != codes.OK {
35+
return nil, status.Errorf(hookVal, hookMsg)
36+
}
3537
// Check to see if the volume already exists.
3638
if i, v := s.findVolByName(ctx, req.Name); i >= 0 {
3739
// Requested volume name already exists, need to check if the existing volume's
@@ -96,6 +98,10 @@ func (s *service) CreateVolume(
9698
TargetPath: "",
9799
}
98100

101+
if hookVal, hookMsg := s.execHook("CreateVolumeEnd"); hookVal != codes.OK {
102+
return nil, status.Errorf(hookVal, hookMsg)
103+
}
104+
99105
return &csi.CreateVolumeResponse{Volume: &v}, nil
100106
}
101107

@@ -112,6 +118,10 @@ func (s *service) DeleteVolume(
112118
return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty")
113119
}
114120

121+
if hookVal, hookMsg := s.execHook("DeleteVolumeStart"); hookVal != codes.OK {
122+
return nil, status.Errorf(hookVal, hookMsg)
123+
}
124+
115125
// If the volume does not exist then return an idempotent response.
116126
i, _ := s.findVolNoLock("id", req.VolumeId)
117127
if i < 0 {
@@ -125,6 +135,10 @@ func (s *service) DeleteVolume(
125135
s.vols[len(s.vols)-1] = csi.Volume{}
126136
s.vols = s.vols[:len(s.vols)-1]
127137
log.WithField("volumeID", req.VolumeId).Debug("mock delete volume")
138+
139+
if hookVal, hookMsg := s.execHook("DeleteVolumeEnd"); hookVal != codes.OK {
140+
return nil, status.Errorf(hookVal, hookMsg)
141+
}
128142
return &csi.DeleteVolumeResponse{}, nil
129143
}
130144

@@ -151,6 +165,10 @@ func (s *service) ControllerPublishVolume(
151165
return nil, status.Errorf(codes.NotFound, "Not matching Node ID %s to Mock Node ID %s", req.NodeId, s.nodeID)
152166
}
153167

168+
if hookVal, hookMsg := s.execHook("ControllerPublishVolumeStart"); hookVal != codes.OK {
169+
return nil, status.Errorf(hookVal, hookMsg)
170+
}
171+
154172
s.volsRWL.Lock()
155173
defer s.volsRWL.Unlock()
156174

@@ -209,6 +227,10 @@ func (s *service) ControllerPublishVolume(
209227
v.VolumeContext[ReadOnlyKey] = roVal
210228
s.vols[i] = v
211229

230+
if hookVal, hookMsg := s.execHook("ControllerPublishVolumeEnd"); hookVal != codes.OK {
231+
return nil, status.Errorf(hookVal, hookMsg)
232+
}
233+
212234
return &csi.ControllerPublishVolumeResponse{
213235
PublishContext: map[string]string{
214236
"device": device,
@@ -239,6 +261,10 @@ func (s *service) ControllerUnpublishVolume(
239261
return nil, status.Errorf(codes.NotFound, "Node ID %s does not match to expected Node ID %s", req.NodeId, s.nodeID)
240262
}
241263

264+
if hookVal, hookMsg := s.execHook("ControllerUnpublishVolumeStart"); hookVal != codes.OK {
265+
return nil, status.Errorf(hookVal, hookMsg)
266+
}
267+
242268
s.volsRWL.Lock()
243269
defer s.volsRWL.Unlock()
244270

@@ -262,6 +288,10 @@ func (s *service) ControllerUnpublishVolume(
262288
delete(v.VolumeContext, ReadOnlyKey)
263289
s.vols[i] = v
264290

291+
if hookVal, hookMsg := s.execHook("ControllerUnpublishVolumeEnd"); hookVal != codes.OK {
292+
return nil, status.Errorf(hookVal, hookMsg)
293+
}
294+
265295
return &csi.ControllerUnpublishVolumeResponse{}, nil
266296
}
267297

@@ -281,6 +311,10 @@ func (s *service) ValidateVolumeCapabilities(
281311
return nil, status.Error(codes.NotFound, req.VolumeId)
282312
}
283313

314+
if hookVal, hookMsg := s.execHook("ValidateVolumeCapabilities"); hookVal != codes.OK {
315+
return nil, status.Errorf(hookVal, hookMsg)
316+
}
317+
284318
return &csi.ValidateVolumeCapabilitiesResponse{
285319
Confirmed: &csi.ValidateVolumeCapabilitiesResponse_Confirmed{
286320
VolumeContext: req.GetVolumeContext(),
@@ -295,6 +329,10 @@ func (s *service) ListVolumes(
295329
req *csi.ListVolumesRequest) (
296330
*csi.ListVolumesResponse, error) {
297331

332+
if hookVal, hookMsg := s.execHook("ListVolumesStart"); hookVal != codes.OK {
333+
return nil, status.Errorf(hookVal, hookMsg)
334+
}
335+
298336
// Copy the mock volumes into a new slice in order to avoid
299337
// locking the service's volume slice for the duration of the
300338
// ListVolumes RPC.
@@ -359,6 +397,10 @@ func (s *service) ListVolumes(
359397
nextToken = fmt.Sprintf("%d", n)
360398
}
361399

400+
if hookVal, hookMsg := s.execHook("ListVolumesEnd"); hookVal != codes.OK {
401+
return nil, status.Errorf(hookVal, hookMsg)
402+
}
403+
362404
return &csi.ListVolumesResponse{
363405
Entries: entries,
364406
NextToken: nextToken,
@@ -370,6 +412,10 @@ func (s *service) GetCapacity(
370412
req *csi.GetCapacityRequest) (
371413
*csi.GetCapacityResponse, error) {
372414

415+
if hookVal, hookMsg := s.execHook("GetCapacity"); hookVal != codes.OK {
416+
return nil, status.Errorf(hookVal, hookMsg)
417+
}
418+
373419
return &csi.GetCapacityResponse{
374420
AvailableCapacity: MaxStorageCapacity,
375421
}, nil
@@ -380,6 +426,10 @@ func (s *service) ControllerGetCapabilities(
380426
req *csi.ControllerGetCapabilitiesRequest) (
381427
*csi.ControllerGetCapabilitiesResponse, error) {
382428

429+
if hookVal, hookMsg := s.execHook("ControllerGetCapabilitiesStart"); hookVal != codes.OK {
430+
return nil, status.Errorf(hookVal, hookMsg)
431+
}
432+
383433
caps := []*csi.ControllerServiceCapability{
384434
{
385435
Type: &csi.ControllerServiceCapability_Rpc{
@@ -452,6 +502,10 @@ func (s *service) ControllerGetCapabilities(
452502
})
453503
}
454504

505+
if hookVal, hookMsg := s.execHook("ControllerGetCapabilitiesEnd"); hookVal != codes.OK {
506+
return nil, status.Errorf(hookVal, hookMsg)
507+
}
508+
455509
return &csi.ControllerGetCapabilitiesResponse{
456510
Capabilities: caps,
457511
}, nil
@@ -467,6 +521,10 @@ func (s *service) CreateSnapshot(ctx context.Context,
467521
return nil, status.Error(codes.InvalidArgument, "Snapshot SourceVolumeId cannot be empty")
468522
}
469523

524+
if hookVal, hookMsg := s.execHook("CreateSnapshotStart"); hookVal != codes.OK {
525+
return nil, status.Errorf(hookVal, hookMsg)
526+
}
527+
470528
// Check to see if the snapshot already exists.
471529
if i, v := s.snapshots.FindSnapshot("name", req.GetName()); i >= 0 {
472530
// Requested snapshot name already exists
@@ -481,6 +539,10 @@ func (s *service) CreateSnapshot(ctx context.Context,
481539
snapshot := s.newSnapshot(req.GetName(), req.GetSourceVolumeId(), req.GetParameters())
482540
s.snapshots.Add(snapshot)
483541

542+
if hookVal, hookMsg := s.execHook("CreateSnapshotEnd"); hookVal != codes.OK {
543+
return nil, status.Errorf(hookVal, hookMsg)
544+
}
545+
484546
return &csi.CreateSnapshotResponse{Snapshot: &snapshot.SnapshotCSI}, nil
485547
}
486548

@@ -492,6 +554,10 @@ func (s *service) DeleteSnapshot(ctx context.Context,
492554
return nil, status.Error(codes.InvalidArgument, "Snapshot ID cannot be empty")
493555
}
494556

557+
if hookVal, hookMsg := s.execHook("DeleteSnapshotStart"); hookVal != codes.OK {
558+
return nil, status.Errorf(hookVal, hookMsg)
559+
}
560+
495561
// If the snapshot does not exist then return an idempotent response.
496562
i, _ := s.snapshots.FindSnapshot("id", req.SnapshotId)
497563
if i < 0 {
@@ -503,12 +569,21 @@ func (s *service) DeleteSnapshot(ctx context.Context,
503569
// themselves have fields that are.
504570
s.snapshots.Delete(i)
505571
log.WithField("SnapshotId", req.SnapshotId).Debug("mock delete snapshot")
572+
573+
if hookVal, hookMsg := s.execHook("DeleteSnapshotEnd"); hookVal != codes.OK {
574+
return nil, status.Errorf(hookVal, hookMsg)
575+
}
576+
506577
return &csi.DeleteSnapshotResponse{}, nil
507578
}
508579

509580
func (s *service) ListSnapshots(ctx context.Context,
510581
req *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) {
511582

583+
if hookVal, hookMsg := s.execHook("ListSnapshots"); hookVal != codes.OK {
584+
return nil, status.Errorf(hookVal, hookMsg)
585+
}
586+
512587
// case 1: SnapshotId is not empty, return snapshots that match the snapshot id.
513588
if len(req.GetSnapshotId()) != 0 {
514589
return getSnapshotById(s, req)
@@ -534,6 +609,10 @@ func (s *service) ControllerExpandVolume(
534609
return nil, status.Error(codes.InvalidArgument, "Request capacity cannot be empty")
535610
}
536611

612+
if hookVal, hookMsg := s.execHook("ControllerExpandVolumeStart"); hookVal != codes.OK {
613+
return nil, status.Errorf(hookVal, hookMsg)
614+
}
615+
537616
s.volsRWL.Lock()
538617
defer s.volsRWL.Unlock()
539618

@@ -567,6 +646,10 @@ func (s *service) ControllerExpandVolume(
567646
v.CapacityBytes = requestBytes
568647
s.vols[i] = v
569648

649+
if hookVal, hookMsg := s.execHook("ControllerExpandVolumeEnd"); hookVal != codes.OK {
650+
return nil, status.Errorf(hookVal, hookMsg)
651+
}
652+
570653
return resp, nil
571654
}
572655

0 commit comments

Comments
 (0)