k8s.io/apiserver@v0.31.1/plugin/pkg/authorizer/webhook/round_trip_test.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // Package webhook implements the authorizer.Authorizer interface using HTTP webhooks.
    18  package webhook
    19  
    20  import (
    21  	"math/rand"
    22  	"reflect"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/google/go-cmp/cmp"
    27  	fuzz "github.com/google/gofuzz"
    28  
    29  	authorizationv1 "k8s.io/api/authorization/v1"
    30  	authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
    31  )
    32  
    33  func TestRoundTrip(t *testing.T) {
    34  	f := fuzz.New()
    35  	seed := time.Now().UnixNano()
    36  	t.Logf("seed = %v", seed)
    37  	f.RandSource(rand.New(rand.NewSource(seed)))
    38  
    39  	for i := 0; i < 1000; i++ {
    40  		original := &authorizationv1.SubjectAccessReview{}
    41  		f.Fuzz(&original.Spec)
    42  		f.Fuzz(&original.Status)
    43  		converted := &authorizationv1beta1.SubjectAccessReview{
    44  			Spec:   v1SpecToV1beta1Spec(&original.Spec),
    45  			Status: v1StatusToV1beta1Status(original.Status),
    46  		}
    47  		roundtripped := &authorizationv1.SubjectAccessReview{
    48  			Spec:   v1beta1SpecToV1Spec(converted.Spec),
    49  			Status: v1beta1StatusToV1Status(&converted.Status),
    50  		}
    51  		if !reflect.DeepEqual(original, roundtripped) {
    52  			t.Errorf("diff %s", cmp.Diff(original, roundtripped))
    53  		}
    54  	}
    55  }
    56  
    57  // v1StatusToV1beta1Status is only needed to verify round-trip fidelity
    58  func v1StatusToV1beta1Status(in authorizationv1.SubjectAccessReviewStatus) authorizationv1beta1.SubjectAccessReviewStatus {
    59  	return authorizationv1beta1.SubjectAccessReviewStatus{
    60  		Allowed:         in.Allowed,
    61  		Denied:          in.Denied,
    62  		Reason:          in.Reason,
    63  		EvaluationError: in.EvaluationError,
    64  	}
    65  }
    66  
    67  // v1beta1SpecToV1Spec is only needed to verify round-trip fidelity
    68  func v1beta1SpecToV1Spec(in authorizationv1beta1.SubjectAccessReviewSpec) authorizationv1.SubjectAccessReviewSpec {
    69  	return authorizationv1.SubjectAccessReviewSpec{
    70  		ResourceAttributes:    v1beta1ResourceAttributesToV1ResourceAttributes(in.ResourceAttributes),
    71  		NonResourceAttributes: v1beta1NonResourceAttributesToV1NonResourceAttributes(in.NonResourceAttributes),
    72  		User:                  in.User,
    73  		Groups:                in.Groups,
    74  		Extra:                 v1beta1ExtraToV1Extra(in.Extra),
    75  		UID:                   in.UID,
    76  	}
    77  }
    78  
    79  func v1beta1ResourceAttributesToV1ResourceAttributes(in *authorizationv1beta1.ResourceAttributes) *authorizationv1.ResourceAttributes {
    80  	if in == nil {
    81  		return nil
    82  	}
    83  	return &authorizationv1.ResourceAttributes{
    84  		Namespace:     in.Namespace,
    85  		Verb:          in.Verb,
    86  		Group:         in.Group,
    87  		Version:       in.Version,
    88  		Resource:      in.Resource,
    89  		Subresource:   in.Subresource,
    90  		Name:          in.Name,
    91  		FieldSelector: in.FieldSelector,
    92  		LabelSelector: in.LabelSelector,
    93  	}
    94  }
    95  
    96  func v1beta1NonResourceAttributesToV1NonResourceAttributes(in *authorizationv1beta1.NonResourceAttributes) *authorizationv1.NonResourceAttributes {
    97  	if in == nil {
    98  		return nil
    99  	}
   100  	return &authorizationv1.NonResourceAttributes{
   101  		Path: in.Path,
   102  		Verb: in.Verb,
   103  	}
   104  }
   105  
   106  func v1beta1ExtraToV1Extra(in map[string]authorizationv1beta1.ExtraValue) map[string]authorizationv1.ExtraValue {
   107  	if in == nil {
   108  		return nil
   109  	}
   110  	ret := make(map[string]authorizationv1.ExtraValue, len(in))
   111  	for k, v := range in {
   112  		ret[k] = authorizationv1.ExtraValue(v)
   113  	}
   114  	return ret
   115  }