Plumb failure policy from config to webhook construction
This commit is contained in:
		@@ -118,11 +118,21 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, nil, err
 | 
									return nil, nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								var decisionOnError authorizer.Decision
 | 
				
			||||||
 | 
								switch configuredAuthorizer.Webhook.FailurePolicy {
 | 
				
			||||||
 | 
								case authzconfig.FailurePolicyNoOpinion:
 | 
				
			||||||
 | 
									decisionOnError = authorizer.DecisionNoOpinion
 | 
				
			||||||
 | 
								case authzconfig.FailurePolicyDeny:
 | 
				
			||||||
 | 
									decisionOnError = authorizer.DecisionDeny
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									return nil, nil, fmt.Errorf("unknown failurePolicy %q", configuredAuthorizer.Webhook.FailurePolicy)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			webhookAuthorizer, err := webhook.New(clientConfig,
 | 
								webhookAuthorizer, err := webhook.New(clientConfig,
 | 
				
			||||||
				configuredAuthorizer.Webhook.SubjectAccessReviewVersion,
 | 
									configuredAuthorizer.Webhook.SubjectAccessReviewVersion,
 | 
				
			||||||
				configuredAuthorizer.Webhook.AuthorizedTTL.Duration,
 | 
									configuredAuthorizer.Webhook.AuthorizedTTL.Duration,
 | 
				
			||||||
				configuredAuthorizer.Webhook.UnauthorizedTTL.Duration,
 | 
									configuredAuthorizer.Webhook.UnauthorizedTTL.Duration,
 | 
				
			||||||
				*config.WebhookRetryBackoff,
 | 
									*config.WebhookRetryBackoff,
 | 
				
			||||||
 | 
									decisionOnError,
 | 
				
			||||||
				configuredAuthorizer.Webhook.MatchConditions,
 | 
									configuredAuthorizer.Webhook.MatchConditions,
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,6 +54,7 @@ func (c DelegatingAuthorizerConfig) New() (authorizer.Authorizer, error) {
 | 
				
			|||||||
		c.AllowCacheTTL,
 | 
							c.AllowCacheTTL,
 | 
				
			||||||
		c.DenyCacheTTL,
 | 
							c.DenyCacheTTL,
 | 
				
			||||||
		*c.WebhookRetryBackoff,
 | 
							*c.WebhookRetryBackoff,
 | 
				
			||||||
 | 
							authorizer.DecisionNoOpinion,
 | 
				
			||||||
		webhook.AuthorizerMetrics{
 | 
							webhook.AuthorizerMetrics{
 | 
				
			||||||
			RecordRequestTotal:   RecordRequestTotal,
 | 
								RecordRequestTotal:   RecordRequestTotal,
 | 
				
			||||||
			RecordRequestLatency: RecordRequestLatency,
 | 
								RecordRequestLatency: RecordRequestLatency,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,8 +75,8 @@ type WebhookAuthorizer struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewFromInterface creates a WebhookAuthorizer using the given subjectAccessReview client
 | 
					// NewFromInterface creates a WebhookAuthorizer using the given subjectAccessReview client
 | 
				
			||||||
func NewFromInterface(subjectAccessReview authorizationv1client.AuthorizationV1Interface, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) {
 | 
					func NewFromInterface(subjectAccessReview authorizationv1client.AuthorizationV1Interface, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, decisionOnError authorizer.Decision, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) {
 | 
				
			||||||
	return newWithBackoff(&subjectAccessReviewV1Client{subjectAccessReview.RESTClient()}, authorizedTTL, unauthorizedTTL, retryBackoff, nil, metrics)
 | 
						return newWithBackoff(&subjectAccessReviewV1Client{subjectAccessReview.RESTClient()}, authorizedTTL, unauthorizedTTL, retryBackoff, decisionOnError, nil, metrics)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// New creates a new WebhookAuthorizer from the provided kubeconfig file.
 | 
					// New creates a new WebhookAuthorizer from the provided kubeconfig file.
 | 
				
			||||||
@@ -98,19 +98,19 @@ func NewFromInterface(subjectAccessReview authorizationv1client.AuthorizationV1I
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// For additional HTTP configuration, refer to the kubeconfig documentation
 | 
					// For additional HTTP configuration, refer to the kubeconfig documentation
 | 
				
			||||||
// https://kubernetes.io/docs/user-guide/kubeconfig-file/.
 | 
					// https://kubernetes.io/docs/user-guide/kubeconfig-file/.
 | 
				
			||||||
func New(config *rest.Config, version string, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, matchConditions []apiserver.WebhookMatchCondition) (*WebhookAuthorizer, error) {
 | 
					func New(config *rest.Config, version string, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, decisionOnError authorizer.Decision, matchConditions []apiserver.WebhookMatchCondition) (*WebhookAuthorizer, error) {
 | 
				
			||||||
	subjectAccessReview, err := subjectAccessReviewInterfaceFromConfig(config, version, retryBackoff)
 | 
						subjectAccessReview, err := subjectAccessReviewInterfaceFromConfig(config, version, retryBackoff)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return newWithBackoff(subjectAccessReview, authorizedTTL, unauthorizedTTL, retryBackoff, matchConditions, AuthorizerMetrics{
 | 
						return newWithBackoff(subjectAccessReview, authorizedTTL, unauthorizedTTL, retryBackoff, decisionOnError, matchConditions, AuthorizerMetrics{
 | 
				
			||||||
		RecordRequestTotal:   noopMetrics{}.RecordRequestTotal,
 | 
							RecordRequestTotal:   noopMetrics{}.RecordRequestTotal,
 | 
				
			||||||
		RecordRequestLatency: noopMetrics{}.RecordRequestLatency,
 | 
							RecordRequestLatency: noopMetrics{}.RecordRequestLatency,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newWithBackoff allows tests to skip the sleep.
 | 
					// newWithBackoff allows tests to skip the sleep.
 | 
				
			||||||
func newWithBackoff(subjectAccessReview subjectAccessReviewer, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, matchConditions []apiserver.WebhookMatchCondition, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) {
 | 
					func newWithBackoff(subjectAccessReview subjectAccessReviewer, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, decisionOnError authorizer.Decision, matchConditions []apiserver.WebhookMatchCondition, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) {
 | 
				
			||||||
	// compile all expressions once in validation and save the results to be used for eval later
 | 
						// compile all expressions once in validation and save the results to be used for eval later
 | 
				
			||||||
	cm, fieldErr := apiservervalidation.ValidateAndCompileMatchConditions(matchConditions)
 | 
						cm, fieldErr := apiservervalidation.ValidateAndCompileMatchConditions(matchConditions)
 | 
				
			||||||
	if err := fieldErr.ToAggregate(); err != nil {
 | 
						if err := fieldErr.ToAggregate(); err != nil {
 | 
				
			||||||
@@ -122,7 +122,7 @@ func newWithBackoff(subjectAccessReview subjectAccessReviewer, authorizedTTL, un
 | 
				
			|||||||
		authorizedTTL:       authorizedTTL,
 | 
							authorizedTTL:       authorizedTTL,
 | 
				
			||||||
		unauthorizedTTL:     unauthorizedTTL,
 | 
							unauthorizedTTL:     unauthorizedTTL,
 | 
				
			||||||
		retryBackoff:        retryBackoff,
 | 
							retryBackoff:        retryBackoff,
 | 
				
			||||||
		decisionOnError:     authorizer.DecisionNoOpinion,
 | 
							decisionOnError:     decisionOnError,
 | 
				
			||||||
		metrics:             metrics,
 | 
							metrics:             metrics,
 | 
				
			||||||
		celMatcher:          cm,
 | 
							celMatcher:          cm,
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ import (
 | 
				
			|||||||
	utiltesting "k8s.io/client-go/util/testing"
 | 
						utiltesting "k8s.io/client-go/util/testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/google/go-cmp/cmp"
 | 
						"github.com/google/go-cmp/cmp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	authorizationv1 "k8s.io/api/authorization/v1"
 | 
						authorizationv1 "k8s.io/api/authorization/v1"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
@@ -209,7 +210,7 @@ current-context: default
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return fmt.Errorf("error building sar client: %v", err)
 | 
									return fmt.Errorf("error building sar client: %v", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, err = newWithBackoff(sarClient, 0, 0, testRetryBackoff, []apiserver.WebhookMatchCondition{}, noopAuthorizerMetrics())
 | 
								_, err = newWithBackoff(sarClient, 0, 0, testRetryBackoff, authorizer.DecisionNoOpinion, []apiserver.WebhookMatchCondition{}, noopAuthorizerMetrics())
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
		if err != nil && !tt.wantErr {
 | 
							if err != nil && !tt.wantErr {
 | 
				
			||||||
@@ -352,7 +353,7 @@ func newV1Authorizer(callbackURL string, clientCert, clientKey, ca []byte, cache
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("error building sar client: %v", err)
 | 
							return nil, fmt.Errorf("error building sar client: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return newWithBackoff(sarClient, cacheTime, cacheTime, testRetryBackoff, expressions, metrics)
 | 
						return newWithBackoff(sarClient, cacheTime, cacheTime, testRetryBackoff, authorizer.DecisionNoOpinion, expressions, metrics)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestV1TLSConfig(t *testing.T) {
 | 
					func TestV1TLSConfig(t *testing.T) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,6 +35,7 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/google/go-cmp/cmp"
 | 
						"github.com/google/go-cmp/cmp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
 | 
						authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	authzconfig "k8s.io/apiserver/pkg/apis/apiserver"
 | 
						authzconfig "k8s.io/apiserver/pkg/apis/apiserver"
 | 
				
			||||||
@@ -196,7 +197,7 @@ current-context: default
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return fmt.Errorf("error building sar client: %v", err)
 | 
									return fmt.Errorf("error building sar client: %v", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, err = newWithBackoff(sarClient, 0, 0, testRetryBackoff, []authzconfig.WebhookMatchCondition{}, noopAuthorizerMetrics())
 | 
								_, err = newWithBackoff(sarClient, 0, 0, testRetryBackoff, authorizer.DecisionNoOpinion, []authzconfig.WebhookMatchCondition{}, noopAuthorizerMetrics())
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
		if err != nil && !tt.wantErr {
 | 
							if err != nil && !tt.wantErr {
 | 
				
			||||||
@@ -339,7 +340,7 @@ func newV1beta1Authorizer(callbackURL string, clientCert, clientKey, ca []byte,
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("error building sar client: %v", err)
 | 
							return nil, fmt.Errorf("error building sar client: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return newWithBackoff(sarClient, cacheTime, cacheTime, testRetryBackoff, []authzconfig.WebhookMatchCondition{}, noopAuthorizerMetrics())
 | 
						return newWithBackoff(sarClient, cacheTime, cacheTime, testRetryBackoff, authorizer.DecisionNoOpinion, []authzconfig.WebhookMatchCondition{}, noopAuthorizerMetrics())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestV1beta1TLSConfig(t *testing.T) {
 | 
					func TestV1beta1TLSConfig(t *testing.T) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user