github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/integration/plugin/authz/authz_plugin_v2_test.go (about) 1 // +build !windows 2 3 package authz // import "github.com/demonoid81/moby/integration/plugin/authz" 4 5 import ( 6 "context" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "strings" 11 "testing" 12 13 "github.com/demonoid81/moby/api/types" 14 "github.com/demonoid81/moby/api/types/filters" 15 volumetypes "github.com/demonoid81/moby/api/types/volume" 16 "github.com/demonoid81/moby/client" 17 "github.com/demonoid81/moby/integration/internal/container" 18 "github.com/demonoid81/moby/integration/internal/requirement" 19 "gotest.tools/v3/assert" 20 "gotest.tools/v3/skip" 21 ) 22 23 var ( 24 authzPluginName = "riyaz/authz-no-volume-plugin" 25 authzPluginTag = "latest" 26 authzPluginNameWithTag = authzPluginName + ":" + authzPluginTag 27 authzPluginBadManifestName = "riyaz/authz-plugin-bad-manifest" 28 nonexistentAuthzPluginName = "riyaz/nonexistent-authz-plugin" 29 ) 30 31 func setupTestV2(t *testing.T) func() { 32 skip.If(t, testEnv.DaemonInfo.OSType == "windows") 33 skip.If(t, !requirement.HasHubConnectivity(t)) 34 35 teardown := setupTest(t) 36 37 d.Start(t) 38 39 return teardown 40 } 41 42 func TestAuthZPluginV2AllowNonVolumeRequest(t *testing.T) { 43 skip.If(t, os.Getenv("DOCKER_ENGINE_GOARCH") != "amd64") 44 defer setupTestV2(t)() 45 46 c := d.NewClientT(t) 47 ctx := context.Background() 48 49 // Install authz plugin 50 err := pluginInstallGrantAllPermissions(c, authzPluginNameWithTag) 51 assert.NilError(t, err) 52 // start the daemon with the plugin and load busybox, --net=none build fails otherwise 53 // because it needs to pull busybox 54 d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) 55 d.LoadBusybox(t) 56 57 // Ensure docker run command and accompanying docker ps are successful 58 cID := container.Run(ctx, t, c) 59 60 _, err = c.ContainerInspect(ctx, cID) 61 assert.NilError(t, err) 62 } 63 64 func TestAuthZPluginV2Disable(t *testing.T) { 65 skip.If(t, os.Getenv("DOCKER_ENGINE_GOARCH") != "amd64") 66 defer setupTestV2(t)() 67 68 c := d.NewClientT(t) 69 70 // Install authz plugin 71 err := pluginInstallGrantAllPermissions(c, authzPluginNameWithTag) 72 assert.NilError(t, err) 73 74 d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) 75 d.LoadBusybox(t) 76 77 _, err = c.VolumeCreate(context.Background(), volumetypes.VolumeCreateBody{Driver: "local"}) 78 assert.Assert(t, err != nil) 79 assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) 80 81 // disable the plugin 82 err = c.PluginDisable(context.Background(), authzPluginNameWithTag, types.PluginDisableOptions{}) 83 assert.NilError(t, err) 84 85 // now test to see if the docker api works. 86 _, err = c.VolumeCreate(context.Background(), volumetypes.VolumeCreateBody{Driver: "local"}) 87 assert.NilError(t, err) 88 } 89 90 func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) { 91 skip.If(t, os.Getenv("DOCKER_ENGINE_GOARCH") != "amd64") 92 defer setupTestV2(t)() 93 94 c := d.NewClientT(t) 95 96 // Install authz plugin 97 err := pluginInstallGrantAllPermissions(c, authzPluginNameWithTag) 98 assert.NilError(t, err) 99 100 // restart the daemon with the plugin 101 d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) 102 103 _, err = c.VolumeCreate(context.Background(), volumetypes.VolumeCreateBody{Driver: "local"}) 104 assert.Assert(t, err != nil) 105 assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) 106 107 _, err = c.VolumeList(context.Background(), filters.Args{}) 108 assert.Assert(t, err != nil) 109 assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) 110 111 // The plugin will block the command before it can determine the volume does not exist 112 err = c.VolumeRemove(context.Background(), "test", false) 113 assert.Assert(t, err != nil) 114 assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) 115 116 _, err = c.VolumeInspect(context.Background(), "test") 117 assert.Assert(t, err != nil) 118 assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) 119 120 _, err = c.VolumesPrune(context.Background(), filters.Args{}) 121 assert.Assert(t, err != nil) 122 assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) 123 } 124 125 func TestAuthZPluginV2BadManifestFailsDaemonStart(t *testing.T) { 126 skip.If(t, os.Getenv("DOCKER_ENGINE_GOARCH") != "amd64") 127 defer setupTestV2(t)() 128 129 c := d.NewClientT(t) 130 131 // Install authz plugin with bad manifest 132 err := pluginInstallGrantAllPermissions(c, authzPluginBadManifestName) 133 assert.NilError(t, err) 134 135 // start the daemon with the plugin, it will error 136 err = d.RestartWithError("--authorization-plugin=" + authzPluginBadManifestName) 137 assert.Assert(t, err != nil) 138 139 // restarting the daemon without requiring the plugin will succeed 140 d.Start(t) 141 } 142 143 func TestAuthZPluginV2NonexistentFailsDaemonStart(t *testing.T) { 144 defer setupTestV2(t)() 145 146 // start the daemon with a non-existent authz plugin, it will error 147 err := d.RestartWithError("--authorization-plugin=" + nonexistentAuthzPluginName) 148 assert.Assert(t, err != nil) 149 150 // restarting the daemon without requiring the plugin will succeed 151 d.Start(t) 152 } 153 154 func pluginInstallGrantAllPermissions(client client.APIClient, name string) error { 155 ctx := context.Background() 156 options := types.PluginInstallOptions{ 157 RemoteRef: name, 158 AcceptAllPermissions: true, 159 } 160 responseReader, err := client.PluginInstall(ctx, "", options) 161 if err != nil { 162 return err 163 } 164 defer responseReader.Close() 165 // we have to read the response out here because the client API 166 // actually starts a goroutine which we can only be sure has 167 // completed when we get EOF from reading responseBody 168 _, err = ioutil.ReadAll(responseReader) 169 return err 170 }