authz_plugin_v2_test.go 5.7 KB

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