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