authz_plugin_v2_test.go 5.4 KB

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