Просмотр исходного кода

Merge pull request #27804 from anusha-ragunathan/blacklist-authz

Blacklist authz plugins that failed.
Anusha Ragunathan 8 лет назад
Родитель
Сommit
406c19f096
3 измененных файлов с 32 добавлено и 3 удалено
  1. 12 2
      pkg/authorization/authz.go
  2. 11 0
      pkg/authorization/middleware.go
  3. 9 1
      pkg/authorization/plugin.go

+ 12 - 2
pkg/authorization/authz.go

@@ -52,6 +52,8 @@ type Ctx struct {
 }
 
 // AuthZRequest authorized the request to the docker daemon using authZ plugins
+// Side effect: If the authz plugin is invalid, then update ctx.plugins, so that
+// the caller(middleware) can update its list and stop retrying with invalid plugins.
 func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
 	var body []byte
 	if sendBody(ctx.requestURI, r.Header) && r.ContentLength > 0 && r.ContentLength < maxBodySize {
@@ -76,11 +78,14 @@ func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
 		RequestHeaders:  headers(r.Header),
 	}
 
-	for _, plugin := range ctx.plugins {
+	for i, plugin := range ctx.plugins {
 		logrus.Debugf("AuthZ request using plugin %s", plugin.Name())
 
 		authRes, err := plugin.AuthZRequest(ctx.authReq)
 		if err != nil {
+			if err == ErrInvalidPlugin {
+				ctx.plugins = append(ctx.plugins[:i], ctx.plugins[i+1:]...)
+			}
 			return fmt.Errorf("plugin %s failed with error: %s", plugin.Name(), err)
 		}
 
@@ -93,6 +98,8 @@ func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
 }
 
 // AuthZResponse authorized and manipulates the response from docker daemon using authZ plugins
+// Side effect: If the authz plugin is invalid, then update ctx.plugins, so that
+// the caller(middleware) can update its list and stop retrying with invalid plugins.
 func (ctx *Ctx) AuthZResponse(rm ResponseModifier, r *http.Request) error {
 	ctx.authReq.ResponseStatusCode = rm.StatusCode()
 	ctx.authReq.ResponseHeaders = headers(rm.Header())
@@ -101,11 +108,14 @@ func (ctx *Ctx) AuthZResponse(rm ResponseModifier, r *http.Request) error {
 		ctx.authReq.ResponseBody = rm.RawBody()
 	}
 
-	for _, plugin := range ctx.plugins {
+	for i, plugin := range ctx.plugins {
 		logrus.Debugf("AuthZ response using plugin %s", plugin.Name())
 
 		authRes, err := plugin.AuthZResponse(ctx.authReq)
 		if err != nil {
+			if err == ErrInvalidPlugin {
+				ctx.plugins = append(ctx.plugins[:i], ctx.plugins[i+1:]...)
+			}
 			return fmt.Errorf("plugin %s failed with error: %s", plugin.Name(), err)
 		}
 

+ 11 - 0
pkg/authorization/middleware.go

@@ -2,6 +2,7 @@ package authorization
 
 import (
 	"net/http"
+	"strings"
 	"sync"
 
 	"github.com/Sirupsen/logrus"
@@ -59,6 +60,11 @@ func (m *Middleware) WrapHandler(handler func(ctx context.Context, w http.Respon
 
 		if err := authCtx.AuthZRequest(w, r); err != nil {
 			logrus.Errorf("AuthZRequest for %s %s returned error: %s", r.Method, r.RequestURI, err)
+			if strings.Contains(err.Error(), ErrInvalidPlugin.Error()) {
+				m.mu.Lock()
+				m.plugins = authCtx.plugins
+				m.mu.Unlock()
+			}
 			return err
 		}
 
@@ -72,6 +78,11 @@ func (m *Middleware) WrapHandler(handler func(ctx context.Context, w http.Respon
 
 		if err := authCtx.AuthZResponse(rw, r); errD == nil && err != nil {
 			logrus.Errorf("AuthZResponse for %s %s returned error: %s", r.Method, r.RequestURI, err)
+			if strings.Contains(err.Error(), ErrInvalidPlugin.Error()) {
+				m.mu.Lock()
+				m.plugins = authCtx.plugins
+				m.mu.Unlock()
+			}
 			return err
 		}
 

+ 9 - 1
pkg/authorization/plugin.go

@@ -1,12 +1,20 @@
 package authorization
 
 import (
+	"errors"
 	"sync"
 
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugins"
 )
 
+var (
+	// ErrInvalidPlugin indicates that the plugin cannot be used. This is
+	// because the plugin was not found or does not implement necessary
+	// functionality
+	ErrInvalidPlugin = errors.New("invalid plugin")
+)
+
 // Plugin allows third party plugins to authorize requests and responses
 // in the context of docker API
 type Plugin interface {
@@ -102,7 +110,7 @@ func (a *authorizationPlugin) initPlugin() error {
 				plugin, e = plugins.Get(a.name, AuthZApiImplements)
 			}
 			if e != nil {
-				err = e
+				err = ErrInvalidPlugin
 				return
 			}
 			a.plugin = plugin.Client()