...

Source file src/github.com/linkerd/linkerd2/pkg/k8s/authz_test.go

Documentation: github.com/linkerd/linkerd2/pkg/k8s

     1  package k8s
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/go-test/deep"
    10  )
    11  
    12  func TestResourceAuthz(t *testing.T) {
    13  	tests := []struct {
    14  		k8sConfigs []string
    15  		err        error
    16  	}{
    17  		{
    18  			// TODO: determine the objects that will affect ResourceAuthz
    19  			[]string{`
    20  kind: ClusterRole
    21  apiVersion: rbac.authorization.k8s.io/v1
    22  metadata:
    23    name: cr-test
    24  rules:
    25  - apiGroups: ["apps"]
    26    resources: ["deployments"]
    27    verbs: ["list"]`,
    28  				`
    29  kind: ClusterRoleBinding
    30  apiVersion: rbac.authorization.k8s.io/v1
    31  metadata:
    32    name: crb-test
    33  roleRef:
    34    apiGroup: rbac.authorization.k8s.io
    35    kind: ClusterRole
    36    name: cr-test
    37  subjects:
    38  - kind: Group
    39    name: system:unauthenticated
    40    apiGroup: rbac.authorization.k8s.io`,
    41  			},
    42  			errors.New("not authorized to access deployments.apps"),
    43  		},
    44  	}
    45  
    46  	ctx := context.Background()
    47  	for i, test := range tests {
    48  		test := test // pin
    49  		t.Run(fmt.Sprintf("%d: returns expected authorization", i), func(t *testing.T) {
    50  			k8sClient, err := NewFakeAPI(test.k8sConfigs...)
    51  			if err != nil {
    52  				t.Fatalf("Unexpected error: %s", err)
    53  			}
    54  			err = ResourceAuthz(ctx, k8sClient, "", "list", "apps", "v1", "deployments", "")
    55  			if err != nil || test.err != nil {
    56  				if (err == nil && test.err != nil) ||
    57  					(err != nil && test.err == nil) ||
    58  					(err.Error() != test.err.Error()) {
    59  					t.Fatalf("Unexpected error (Expected: %s, Got: %s)", test.err, err)
    60  				}
    61  			}
    62  		})
    63  	}
    64  }
    65  
    66  func TestServiceProfilesAccess(t *testing.T) {
    67  	fakeResources := []string{`
    68  kind: APIResourceList
    69  apiVersion: v1
    70  groupVersion: linkerd.io/v1alpha2
    71  resources:
    72  - name: serviceprofiles
    73    singularName: serviceprofile
    74    namespaced: true
    75    kind: ServiceProfile
    76    verbs:
    77    - delete
    78    - deletecollection
    79    - get
    80    - list
    81    - patch
    82    - create
    83    - update
    84    - watch
    85    shortNames:
    86    - sp`}
    87  
    88  	api, err := NewFakeAPI(fakeResources...)
    89  	if err != nil {
    90  		t.Fatalf("NewFakeAPI error: %s", err)
    91  	}
    92  
    93  	err = ServiceProfilesAccess(context.Background(), api)
    94  	// RBAC SSAR request failed, but the Discovery lookup succeeded
    95  	if diff := deep.Equal(err, errors.New("not authorized to access serviceprofiles.linkerd.io")); diff != nil {
    96  		t.Errorf("%+v", diff)
    97  	}
    98  }
    99  
   100  func TestServersAccess(t *testing.T) {
   101  	testCases := []struct {
   102  		name          string
   103  		resources     []string
   104  		expectedError error
   105  	}{
   106  		{
   107  			name: "supports version but not authorized",
   108  			resources: []string{
   109  				`
   110  apiVersion: apiextensions.k8s.io/v1
   111  kind: CustomResourceDefinition
   112  metadata:
   113    name: servers.policy.linkerd.io
   114  spec:
   115    conversion:
   116      strategy: None
   117    group: policy.linkerd.io
   118    names:
   119      kind: Server
   120      listKind: ServerList
   121      plural: servers
   122      shortNames:
   123      - srv
   124      singular: server
   125    scope: Namespaced
   126  `, `
   127  kind: APIResourceList
   128  apiVersion: v1beta1
   129  groupVersion: policy.linkerd.io/v1beta2
   130  resources:
   131  - name: servers
   132    singularName: server
   133    namespaced: true
   134    kind: Server
   135    verbs:
   136    - delete
   137    - deletecollection
   138    - get
   139    - list
   140    - patch
   141    - create
   142    - update
   143    - watch
   144    shortNames:
   145    - srv
   146  `},
   147  			expectedError: errors.New("not authorized to access servers.policy.linkerd.io"),
   148  		},
   149  		{
   150  			name: "does not support version",
   151  			resources: []string{
   152  				`
   153  apiVersion: apiextensions.k8s.io/v1
   154  kind: CustomResourceDefinition
   155  metadata:
   156    name: servers.policy.linkerd.io
   157  spec:
   158    conversion:
   159      strategy: None
   160    group: policy.linkerd.io
   161    names:
   162      kind: Server
   163      listKind: ServerList
   164      plural: servers
   165      shortNames:
   166      - srv
   167      singular: server
   168    scope: Namespaced
   169  `, `
   170  kind: APIResourceList
   171  apiVersion: v1beta1
   172  groupVersion: policy.linkerd.io/v1beta1
   173  resources:
   174  - name: servers
   175    singularName: server
   176    namespaced: true
   177    kind: Server
   178    verbs:
   179    - delete
   180    - deletecollection
   181    - get
   182    - list
   183    - patch
   184    - create
   185    - update
   186    - watch
   187    shortNames:
   188    - srv
   189  `},
   190  			expectedError: errors.New(`the server could not find the requested resource, GroupVersion "policy.linkerd.io/v1beta2" not found`),
   191  		},
   192  	}
   193  
   194  	for _, tc := range testCases {
   195  		tc := tc // pin
   196  		t.Run(tc.name, func(t *testing.T) {
   197  			api, err := NewFakeAPI(tc.resources...)
   198  			if err != nil {
   199  				t.Errorf("unexpected error: %s", err)
   200  			}
   201  
   202  			err = ServersAccess(context.Background(), api.Interface)
   203  			if err == nil {
   204  				t.Fatal("Expected error, but got success")
   205  			}
   206  			if err.Error() != tc.expectedError.Error() {
   207  				t.Fatalf("Unexpected error (Expected: %s, Got: %s)", tc.expectedError, err)
   208  			}
   209  		})
   210  	}
   211  }
   212  

View as plain text