...

Source file src/github.com/redhat-developer/odo/pkg/configAutomount/kubernetes_test.go

Documentation: github.com/redhat-developer/odo/pkg/configAutomount

     1  package configAutomount
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/golang/mock/gomock"
     7  	"github.com/google/go-cmp/cmp"
     8  	"github.com/redhat-developer/odo/pkg/kclient"
     9  	corev1 "k8s.io/api/core/v1"
    10  	"k8s.io/utils/pointer"
    11  )
    12  
    13  func TestKubernetesClient_GetAutomountingVolumes(t *testing.T) {
    14  
    15  	defaultPVC1 := corev1.PersistentVolumeClaim{}
    16  	defaultPVC1.SetName("defaultPVC1")
    17  	defaultPVC1.SetLabels(map[string]string{
    18  		labelMountName: labelMountValue,
    19  	})
    20  
    21  	defaultPVC2 := corev1.PersistentVolumeClaim{}
    22  	defaultPVC2.SetName("defaultPVC2")
    23  	defaultPVC2.SetLabels(map[string]string{
    24  		labelMountName: labelMountValue,
    25  	})
    26  
    27  	pvcMountPath := corev1.PersistentVolumeClaim{}
    28  	pvcMountPath.SetName("pvcMountPath")
    29  	pvcMountPath.SetLabels(map[string]string{
    30  		labelMountName: labelMountValue,
    31  	})
    32  	pvcMountPath.SetAnnotations(map[string]string{
    33  		annotationMountPathName: "/specific/pvc/mount/path",
    34  	})
    35  
    36  	roPVC := corev1.PersistentVolumeClaim{}
    37  	roPVC.SetName("roPVC")
    38  	roPVC.SetLabels(map[string]string{
    39  		labelMountName: labelMountValue,
    40  	})
    41  	roPVC.SetAnnotations(map[string]string{
    42  		annotationReadOnlyName: "true",
    43  	})
    44  
    45  	defaultSecret1 := corev1.Secret{}
    46  	defaultSecret1.SetName("defaultSecret1")
    47  	defaultSecret1.SetLabels(map[string]string{
    48  		labelMountName: labelMountValue,
    49  	})
    50  
    51  	defaultSecret2 := corev1.Secret{}
    52  	defaultSecret2.SetName("defaultSecret2")
    53  	defaultSecret2.SetLabels(map[string]string{
    54  		labelMountName: labelMountValue,
    55  	})
    56  
    57  	secretMountPath := corev1.Secret{}
    58  	secretMountPath.SetName("secretMountPath")
    59  	secretMountPath.SetLabels(map[string]string{
    60  		labelMountName: labelMountValue,
    61  	})
    62  	secretMountPath.SetAnnotations(map[string]string{
    63  		annotationMountPathName: "/specific/secret/mount/path",
    64  	})
    65  
    66  	secretMountAsSubpath := corev1.Secret{}
    67  	secretMountAsSubpath.Data = map[string][]byte{
    68  		"secretKey1": []byte(""),
    69  		"secretKey2": []byte(""),
    70  	}
    71  	secretMountAsSubpath.SetName("secretMountAsSubpath")
    72  	secretMountAsSubpath.SetLabels(map[string]string{
    73  		labelMountName: labelMountValue,
    74  	})
    75  	secretMountAsSubpath.SetAnnotations(map[string]string{
    76  		annotationMountAsName: "subpath",
    77  	})
    78  
    79  	secretMountAsEnv := corev1.Secret{}
    80  	secretMountAsEnv.SetName("secretMountAsEnv")
    81  	secretMountAsEnv.SetLabels(map[string]string{
    82  		labelMountName: labelMountValue,
    83  	})
    84  	secretMountAsEnv.SetAnnotations(map[string]string{
    85  		annotationMountAsName: "env",
    86  	})
    87  
    88  	roSecret := corev1.Secret{}
    89  	roSecret.SetName("roSecret")
    90  	roSecret.SetLabels(map[string]string{
    91  		labelMountName: labelMountValue,
    92  	})
    93  	roSecret.SetAnnotations(map[string]string{
    94  		annotationReadOnlyName: "true",
    95  	})
    96  
    97  	secretMountAccessMode := corev1.Secret{}
    98  	secretMountAccessMode.SetName("secretMountAccessMode")
    99  	secretMountAccessMode.SetLabels(map[string]string{
   100  		labelMountName: labelMountValue,
   101  	})
   102  	secretMountAccessMode.SetAnnotations(map[string]string{
   103  		annotationMountAccessMode: "0400",
   104  	})
   105  
   106  	secretMountAccessModeInvalid := corev1.Secret{}
   107  	secretMountAccessModeInvalid.SetName("secretMountAccessModeInvalid")
   108  	secretMountAccessModeInvalid.SetLabels(map[string]string{
   109  		labelMountName: labelMountValue,
   110  	})
   111  	secretMountAccessModeInvalid.SetAnnotations(map[string]string{
   112  		annotationMountAccessMode: "01444",
   113  	})
   114  
   115  	defaultCM1 := corev1.ConfigMap{}
   116  	defaultCM1.SetName("defaultCM1")
   117  	defaultCM1.SetLabels(map[string]string{
   118  		labelMountName: labelMountValue,
   119  	})
   120  
   121  	defaultCM2 := corev1.ConfigMap{}
   122  	defaultCM2.SetName("defaultCM2")
   123  	defaultCM2.SetLabels(map[string]string{
   124  		labelMountName: labelMountValue,
   125  	})
   126  
   127  	cmMountPath := corev1.ConfigMap{}
   128  	cmMountPath.SetName("cmMountPath")
   129  	cmMountPath.SetLabels(map[string]string{
   130  		labelMountName: labelMountValue,
   131  	})
   132  	cmMountPath.SetAnnotations(map[string]string{
   133  		annotationMountPathName: "/specific/configmap/mount/path",
   134  	})
   135  
   136  	cmMountAsSubpath := corev1.ConfigMap{}
   137  	cmMountAsSubpath.Data = map[string]string{
   138  		"cmKey1": "",
   139  		"cmKey2": "",
   140  	}
   141  	cmMountAsSubpath.SetName("cmMountAsSubpath")
   142  	cmMountAsSubpath.SetLabels(map[string]string{
   143  		labelMountName: labelMountValue,
   144  	})
   145  	cmMountAsSubpath.SetAnnotations(map[string]string{
   146  		annotationMountAsName: "subpath",
   147  	})
   148  
   149  	cmMountAsEnv := corev1.ConfigMap{}
   150  	cmMountAsEnv.SetName("cmMountAsEnv")
   151  	cmMountAsEnv.SetLabels(map[string]string{
   152  		labelMountName: labelMountValue,
   153  	})
   154  	cmMountAsEnv.SetAnnotations(map[string]string{
   155  		annotationMountAsName: "env",
   156  	})
   157  
   158  	roCM := corev1.ConfigMap{}
   159  	roCM.SetName("roCM")
   160  	roCM.SetLabels(map[string]string{
   161  		labelMountName: labelMountValue,
   162  	})
   163  	roCM.SetAnnotations(map[string]string{
   164  		annotationReadOnlyName: "true",
   165  	})
   166  
   167  	cmMountAccessMode := corev1.ConfigMap{}
   168  	cmMountAccessMode.SetName("cmMountAccessMode")
   169  	cmMountAccessMode.SetLabels(map[string]string{
   170  		labelMountName: labelMountValue,
   171  	})
   172  	cmMountAccessMode.SetAnnotations(map[string]string{
   173  		annotationMountAccessMode: "0444",
   174  	})
   175  
   176  	cmMountAccessModeInvalid := corev1.ConfigMap{}
   177  	cmMountAccessModeInvalid.SetName("cmMountAccessModeInvalid")
   178  	cmMountAccessModeInvalid.SetLabels(map[string]string{
   179  		labelMountName: labelMountValue,
   180  	})
   181  	cmMountAccessModeInvalid.SetAnnotations(map[string]string{
   182  		annotationMountAccessMode: "01444",
   183  	})
   184  
   185  	type fields struct {
   186  		kubeClient func(ctrl *gomock.Controller) kclient.ClientInterface
   187  	}
   188  	tests := []struct {
   189  		name    string
   190  		fields  fields
   191  		want    []AutomountInfo
   192  		wantErr bool
   193  	}{
   194  		{
   195  			name: "Single default PVC",
   196  			fields: fields{
   197  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   198  					client := kclient.NewMockClientInterface(ctrl)
   199  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{defaultPVC1}, nil).AnyTimes()
   200  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{}, nil).AnyTimes()
   201  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{}, nil).AnyTimes()
   202  					return client
   203  				},
   204  			},
   205  			want: []AutomountInfo{
   206  				{
   207  					VolumeType: VolumeTypePVC,
   208  					VolumeName: "defaultPVC1",
   209  					MountPath:  "/tmp/defaultPVC1",
   210  					MountAs:    MountAsFile,
   211  				},
   212  			},
   213  			wantErr: false,
   214  		},
   215  		{
   216  			name: "Two default PVCs",
   217  			fields: fields{
   218  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   219  					client := kclient.NewMockClientInterface(ctrl)
   220  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{defaultPVC1, defaultPVC2}, nil).AnyTimes()
   221  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{}, nil).AnyTimes()
   222  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{}, nil).AnyTimes()
   223  					return client
   224  				},
   225  			},
   226  			want: []AutomountInfo{
   227  				{
   228  					VolumeType: VolumeTypePVC,
   229  					VolumeName: "defaultPVC1",
   230  					MountPath:  "/tmp/defaultPVC1",
   231  					MountAs:    MountAsFile,
   232  				},
   233  				{
   234  					VolumeType: VolumeTypePVC,
   235  					VolumeName: "defaultPVC2",
   236  					MountPath:  "/tmp/defaultPVC2",
   237  					MountAs:    MountAsFile,
   238  				},
   239  			},
   240  			wantErr: false,
   241  		},
   242  		{
   243  			name: "Two default secrets",
   244  			fields: fields{
   245  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   246  					client := kclient.NewMockClientInterface(ctrl)
   247  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{}, nil).AnyTimes()
   248  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{defaultSecret1, defaultSecret2}, nil).AnyTimes()
   249  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{}, nil).AnyTimes()
   250  					return client
   251  				},
   252  			},
   253  			want: []AutomountInfo{
   254  				{
   255  					VolumeType: VolumeTypeSecret,
   256  					VolumeName: "defaultSecret1",
   257  					MountPath:  "/etc/secret/defaultSecret1",
   258  					MountAs:    MountAsFile,
   259  				},
   260  				{
   261  					VolumeType: VolumeTypeSecret,
   262  					VolumeName: "defaultSecret2",
   263  					MountPath:  "/etc/secret/defaultSecret2",
   264  					MountAs:    MountAsFile,
   265  				},
   266  			},
   267  			wantErr: false,
   268  		},
   269  		{
   270  			name: "Two default configmaps",
   271  			fields: fields{
   272  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   273  					client := kclient.NewMockClientInterface(ctrl)
   274  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{}, nil).AnyTimes()
   275  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{}, nil).AnyTimes()
   276  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{defaultCM1, defaultCM2}, nil).AnyTimes()
   277  					return client
   278  				},
   279  			},
   280  			want: []AutomountInfo{
   281  				{
   282  					VolumeType: VolumeTypeConfigmap,
   283  					VolumeName: "defaultCM1",
   284  					MountPath:  "/etc/config/defaultCM1",
   285  					MountAs:    MountAsFile,
   286  				},
   287  				{
   288  					VolumeType: VolumeTypeConfigmap,
   289  					VolumeName: "defaultCM2",
   290  					MountPath:  "/etc/config/defaultCM2",
   291  					MountAs:    MountAsFile,
   292  				},
   293  			},
   294  			wantErr: false,
   295  		},
   296  		{
   297  			name: "PVC, Secret and ConfigMap with non default mount paths",
   298  			fields: fields{
   299  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   300  					client := kclient.NewMockClientInterface(ctrl)
   301  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{pvcMountPath}, nil).AnyTimes()
   302  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{secretMountPath}, nil).AnyTimes()
   303  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{cmMountPath}, nil).AnyTimes()
   304  					return client
   305  				},
   306  			},
   307  			want: []AutomountInfo{
   308  				{
   309  					VolumeType: VolumeTypePVC,
   310  					VolumeName: "pvcMountPath",
   311  					MountPath:  "/specific/pvc/mount/path",
   312  					MountAs:    MountAsFile,
   313  				},
   314  				{
   315  					VolumeType: VolumeTypeSecret,
   316  					VolumeName: "secretMountPath",
   317  					MountPath:  "/specific/secret/mount/path",
   318  					MountAs:    MountAsFile,
   319  				},
   320  				{
   321  					VolumeType: VolumeTypeConfigmap,
   322  					VolumeName: "cmMountPath",
   323  					MountPath:  "/specific/configmap/mount/path",
   324  					MountAs:    MountAsFile,
   325  				},
   326  			},
   327  			wantErr: false,
   328  		},
   329  		{
   330  			name: "Secret and ConfigMap with mount-as annotations",
   331  			fields: fields{
   332  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   333  					client := kclient.NewMockClientInterface(ctrl)
   334  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{}, nil).AnyTimes()
   335  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{secretMountAsSubpath, secretMountAsEnv}, nil).AnyTimes()
   336  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{cmMountAsSubpath, cmMountAsEnv}, nil).AnyTimes()
   337  					return client
   338  				},
   339  			},
   340  			want: []AutomountInfo{
   341  				{
   342  					VolumeType: VolumeTypeSecret,
   343  					VolumeName: "secretMountAsSubpath",
   344  					MountPath:  "/etc/secret/secretMountAsSubpath",
   345  					MountAs:    MountAsSubpath,
   346  					Keys:       []string{"secretKey1", "secretKey2"},
   347  				},
   348  				{
   349  					VolumeType: VolumeTypeSecret,
   350  					VolumeName: "secretMountAsEnv",
   351  					MountPath:  "",
   352  					MountAs:    MountAsEnv,
   353  				},
   354  				{
   355  					VolumeType: VolumeTypeConfigmap,
   356  					VolumeName: "cmMountAsSubpath",
   357  					MountPath:  "/etc/config/cmMountAsSubpath",
   358  					MountAs:    MountAsSubpath,
   359  					Keys:       []string{"cmKey1", "cmKey2"},
   360  				},
   361  				{
   362  					VolumeType: VolumeTypeConfigmap,
   363  					VolumeName: "cmMountAsEnv",
   364  					MountPath:  "",
   365  					MountAs:    MountAsEnv,
   366  				},
   367  			},
   368  			wantErr: false,
   369  		},
   370  		{
   371  			name: "Secret and ConfigMap with mount-access-mode annotations",
   372  			fields: fields{
   373  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   374  					client := kclient.NewMockClientInterface(ctrl)
   375  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{}, nil).AnyTimes()
   376  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{secretMountAccessMode}, nil).AnyTimes()
   377  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{cmMountAccessMode}, nil).AnyTimes()
   378  					return client
   379  				},
   380  			},
   381  			want: []AutomountInfo{
   382  				{
   383  					VolumeType:      VolumeTypeSecret,
   384  					VolumeName:      "secretMountAccessMode",
   385  					MountPath:       "/etc/secret/secretMountAccessMode",
   386  					MountAs:         MountAsFile,
   387  					MountAccessMode: pointer.Int32(0400),
   388  				},
   389  				{
   390  					VolumeType:      VolumeTypeConfigmap,
   391  					VolumeName:      "cmMountAccessMode",
   392  					MountPath:       "/etc/config/cmMountAccessMode",
   393  					MountAs:         MountAsFile,
   394  					MountAccessMode: pointer.Int32(0444),
   395  				},
   396  			},
   397  			wantErr: false,
   398  		},
   399  		{
   400  			name: "Secret with invalid mount-access-mode annotation",
   401  			fields: fields{
   402  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   403  					client := kclient.NewMockClientInterface(ctrl)
   404  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{}, nil).AnyTimes()
   405  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{secretMountAccessModeInvalid}, nil).AnyTimes()
   406  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{}, nil).AnyTimes()
   407  					return client
   408  				},
   409  			},
   410  			want:    nil,
   411  			wantErr: true,
   412  		},
   413  		{
   414  			name: "Configmap with invalid mount-access-mode annotation",
   415  			fields: fields{
   416  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   417  					client := kclient.NewMockClientInterface(ctrl)
   418  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{}, nil).AnyTimes()
   419  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{}, nil).AnyTimes()
   420  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{cmMountAccessModeInvalid}, nil).AnyTimes()
   421  					return client
   422  				},
   423  			},
   424  			want:    nil,
   425  			wantErr: true,
   426  		},
   427  		{
   428  			name: "PVC, Secret and ConfigMap read-only",
   429  			fields: fields{
   430  				kubeClient: func(ctrl *gomock.Controller) kclient.ClientInterface {
   431  					client := kclient.NewMockClientInterface(ctrl)
   432  					client.EXPECT().ListPVCs(gomock.Any()).Return([]corev1.PersistentVolumeClaim{roPVC}, nil).AnyTimes()
   433  					client.EXPECT().ListSecrets(gomock.Any()).Return([]corev1.Secret{roSecret}, nil).AnyTimes()
   434  					client.EXPECT().ListConfigMaps(gomock.Any()).Return([]corev1.ConfigMap{roCM}, nil).AnyTimes()
   435  					return client
   436  				},
   437  			},
   438  			want: []AutomountInfo{
   439  				{
   440  					VolumeType: VolumeTypePVC,
   441  					VolumeName: "roPVC",
   442  					MountPath:  "/tmp/roPVC",
   443  					MountAs:    MountAsFile,
   444  					ReadOnly:   true,
   445  				},
   446  				{
   447  					VolumeType: VolumeTypeSecret,
   448  					VolumeName: "roSecret",
   449  					MountPath:  "/etc/secret/roSecret",
   450  					MountAs:    MountAsFile,
   451  					ReadOnly:   true,
   452  				},
   453  				{
   454  					VolumeType: VolumeTypeConfigmap,
   455  					VolumeName: "roCM",
   456  					MountPath:  "/etc/config/roCM",
   457  					MountAs:    MountAsFile,
   458  					ReadOnly:   true,
   459  				},
   460  			},
   461  			wantErr: false,
   462  		}}
   463  	for _, tt := range tests {
   464  		t.Run(tt.name, func(t *testing.T) {
   465  			ctrl := gomock.NewController(t)
   466  			o := KubernetesClient{
   467  				kubeClient: tt.fields.kubeClient(ctrl),
   468  			}
   469  			got, err := o.GetAutomountingVolumes()
   470  			if (err != nil) != tt.wantErr {
   471  				t.Errorf("KubernetesClient.GetAutomountingVolumes() error = %v, wantErr %v", err, tt.wantErr)
   472  				return
   473  			}
   474  
   475  			if diff := cmp.Diff(tt.want, got); diff != "" {
   476  				t.Errorf("KubernetesClient.GetAutomountingVolumes() mismatch (-want +got):\n%s", diff)
   477  			}
   478  		})
   479  	}
   480  }
   481  

View as plain text