mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Check authz plugins are valid on daemon startup, add integration tests
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
parent
2fc760496b
commit
2b045027ce
2 changed files with 154 additions and 3 deletions
|
@ -35,6 +35,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/jsonlog"
|
"github.com/docker/docker/pkg/jsonlog"
|
||||||
"github.com/docker/docker/pkg/listeners"
|
"github.com/docker/docker/pkg/listeners"
|
||||||
"github.com/docker/docker/pkg/pidfile"
|
"github.com/docker/docker/pkg/pidfile"
|
||||||
|
"github.com/docker/docker/pkg/plugingetter"
|
||||||
"github.com/docker/docker/pkg/signal"
|
"github.com/docker/docker/pkg/signal"
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
|
@ -287,7 +288,9 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
||||||
cli.d = d
|
cli.d = d
|
||||||
|
|
||||||
// initMiddlewares needs cli.d to be populated. Dont change this init order.
|
// initMiddlewares needs cli.d to be populated. Dont change this init order.
|
||||||
cli.initMiddlewares(api, serverConfig)
|
if err := cli.initMiddlewares(api, serverConfig); err != nil {
|
||||||
|
logrus.Fatalf("Error creating middlewares: %v", err)
|
||||||
|
}
|
||||||
d.SetCluster(c)
|
d.SetCluster(c)
|
||||||
initRouter(api, d, c)
|
initRouter(api, d, c)
|
||||||
|
|
||||||
|
@ -318,7 +321,11 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
||||||
func (cli *DaemonCli) reloadConfig() {
|
func (cli *DaemonCli) reloadConfig() {
|
||||||
reload := func(config *daemon.Config) {
|
reload := func(config *daemon.Config) {
|
||||||
|
|
||||||
// Reload the authorization plugin
|
// Revalidate and reload the authorization plugins
|
||||||
|
if err := validateAuthzPlugins(config.AuthorizationPlugins, cli.d.PluginStore); err != nil {
|
||||||
|
logrus.Fatalf("Error validating authorization plugin: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
cli.authzMiddleware.SetPlugins(config.AuthorizationPlugins)
|
cli.authzMiddleware.SetPlugins(config.AuthorizationPlugins)
|
||||||
|
|
||||||
if err := cli.d.Reload(config); err != nil {
|
if err := cli.d.Reload(config); err != nil {
|
||||||
|
@ -459,7 +466,7 @@ func initRouter(s *apiserver.Server, d *daemon.Daemon, c *cluster.Cluster) {
|
||||||
s.InitRouter(utils.IsDebugEnabled(), routers...)
|
s.InitRouter(utils.IsDebugEnabled(), routers...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config) {
|
func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config) error {
|
||||||
v := cfg.Version
|
v := cfg.Version
|
||||||
|
|
||||||
exp := middleware.NewExperimentalMiddleware(cli.d.HasExperimental())
|
exp := middleware.NewExperimentalMiddleware(cli.d.HasExperimental())
|
||||||
|
@ -476,6 +483,21 @@ func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config
|
||||||
u := middleware.NewUserAgentMiddleware(v)
|
u := middleware.NewUserAgentMiddleware(v)
|
||||||
s.UseMiddleware(u)
|
s.UseMiddleware(u)
|
||||||
|
|
||||||
|
if err := validateAuthzPlugins(cli.Config.AuthorizationPlugins, cli.d.PluginStore); err != nil {
|
||||||
|
return fmt.Errorf("Error validating authorization plugin: %v", err)
|
||||||
|
}
|
||||||
cli.authzMiddleware = authorization.NewMiddleware(cli.Config.AuthorizationPlugins, cli.d.PluginStore)
|
cli.authzMiddleware = authorization.NewMiddleware(cli.Config.AuthorizationPlugins, cli.d.PluginStore)
|
||||||
s.UseMiddleware(cli.authzMiddleware)
|
s.UseMiddleware(cli.authzMiddleware)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validates that the plugins requested with the --authorization-plugin flag are valid AuthzDriver
|
||||||
|
// plugins present on the host and available to the daemon
|
||||||
|
func validateAuthzPlugins(requestedPlugins []string, pg plugingetter.PluginGetter) error {
|
||||||
|
for _, reqPlugin := range requestedPlugins {
|
||||||
|
if _, err := pg.Get(reqPlugin, authorization.AuthZApiImplements, plugingetter.LOOKUP); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
129
integration-cli/docker_cli_authz_plugin_v2_test.go
Normal file
129
integration-cli/docker_cli_authz_plugin_v2_test.go
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/integration/checker"
|
||||||
|
"github.com/go-check/check"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
authzPluginName = "riyaz/authz-no-volume-plugin"
|
||||||
|
authzPluginTag = "latest"
|
||||||
|
authzPluginNameWithTag = authzPluginName + ":" + authzPluginTag
|
||||||
|
authzPluginBadManifestName = "riyaz/authz-plugin-bad-manifest"
|
||||||
|
nonexistentAuthzPluginName = "riyaz/nonexistent-authz-plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
check.Suite(&DockerAuthzV2Suite{
|
||||||
|
ds: &DockerSuite{},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerAuthzV2Suite struct {
|
||||||
|
ds *DockerSuite
|
||||||
|
d *Daemon
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerAuthzV2Suite) SetUpTest(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsLinux, ExperimentalDaemon, Network)
|
||||||
|
s.d = NewDaemon(c)
|
||||||
|
c.Assert(s.d.Start(), check.IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerAuthzV2Suite) TearDownTest(c *check.C) {
|
||||||
|
s.d.Stop()
|
||||||
|
s.ds.TearDownTest(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerAuthzV2Suite) TestAuthZPluginAllowNonVolumeRequest(c *check.C) {
|
||||||
|
// Install authz plugin
|
||||||
|
_, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", authzPluginNameWithTag)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
// start the daemon with the plugin and load busybox, --net=none build fails otherwise
|
||||||
|
// because it needs to pull busybox
|
||||||
|
c.Assert(s.d.Restart("--authorization-plugin="+authzPluginNameWithTag), check.IsNil)
|
||||||
|
c.Assert(s.d.LoadBusybox(), check.IsNil)
|
||||||
|
|
||||||
|
// defer disabling the plugin
|
||||||
|
defer func() {
|
||||||
|
c.Assert(s.d.Restart(), check.IsNil)
|
||||||
|
_, err = s.d.Cmd("plugin", "disable", authzPluginNameWithTag)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
_, err = s.d.Cmd("plugin", "rm", authzPluginNameWithTag)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Ensure docker run command and accompanying docker ps are successful
|
||||||
|
out, err := s.d.Cmd("run", "-d", "busybox", "top")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
id := strings.TrimSpace(out)
|
||||||
|
|
||||||
|
out, err = s.d.Cmd("ps")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
c.Assert(assertContainerList(out, []string{id}), check.Equals, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerAuthzV2Suite) TestAuthZPluginRejectVolumeRequests(c *check.C) {
|
||||||
|
// Install authz plugin
|
||||||
|
_, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", authzPluginNameWithTag)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
// restart the daemon with the plugin
|
||||||
|
c.Assert(s.d.Restart("--authorization-plugin="+authzPluginNameWithTag), check.IsNil)
|
||||||
|
|
||||||
|
// defer disabling the plugin
|
||||||
|
defer func() {
|
||||||
|
c.Assert(s.d.Restart(), check.IsNil)
|
||||||
|
_, err = s.d.Cmd("plugin", "disable", authzPluginNameWithTag)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
_, err = s.d.Cmd("plugin", "rm", authzPluginNameWithTag)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
}()
|
||||||
|
|
||||||
|
out, err := s.d.Cmd("volume", "create")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(out, checker.Contains, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
|
||||||
|
|
||||||
|
out, err = s.d.Cmd("volume", "ls")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(out, checker.Contains, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
|
||||||
|
|
||||||
|
// The plugin will block the command before it can determine the volume does not exist
|
||||||
|
out, err = s.d.Cmd("volume", "rm", "test")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(out, checker.Contains, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
|
||||||
|
|
||||||
|
out, err = s.d.Cmd("volume", "inspect", "test")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(out, checker.Contains, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
|
||||||
|
|
||||||
|
out, err = s.d.Cmd("volume", "prune", "-f")
|
||||||
|
c.Assert(err, check.NotNil)
|
||||||
|
c.Assert(out, checker.Contains, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerAuthzV2Suite) TestAuthZPluginBadManifestFailsDaemonStart(c *check.C) {
|
||||||
|
// Install authz plugin with bad manifest
|
||||||
|
_, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", authzPluginBadManifestName)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
// start the daemon with the plugin, it will error
|
||||||
|
c.Assert(s.d.Restart("--authorization-plugin="+authzPluginBadManifestName), check.NotNil)
|
||||||
|
|
||||||
|
// restarting the daemon without requiring the plugin will succeed
|
||||||
|
c.Assert(s.d.Restart(), check.IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DockerAuthzV2Suite) TestNonexistentAuthZPluginFailsDaemonStart(c *check.C) {
|
||||||
|
// start the daemon with a non-existent authz plugin, it will error
|
||||||
|
c.Assert(s.d.Restart("--authorization-plugin="+nonexistentAuthzPluginName), check.NotNil)
|
||||||
|
|
||||||
|
// restarting the daemon without requiring the plugin will succeed
|
||||||
|
c.Assert(s.d.Restart(), check.IsNil)
|
||||||
|
}
|
Loading…
Reference in a new issue