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