Added unit tests

This commit is contained in:
sreeram-venkitesh
2025-06-25 23:59:44 +05:30
parent 5390f75360
commit f9a5aec318
3 changed files with 406 additions and 7 deletions

View File

@@ -4701,3 +4701,401 @@ func TestValidateAllowPodLifecycleSleepActionZeroValue(t *testing.T) {
})
}
}
func TestHasAPIReferences(t *testing.T) {
tests := []struct {
name string
pod *api.Pod
expectRejection bool
resource string
}{
{
name: "Empty ServiceAccount in Static Pod",
pod: &api.Pod{Spec: api.PodSpec{}},
expectRejection: false,
},
{
name: "Non empty ServiceAccount",
pod: &api.Pod{Spec: api.PodSpec{ServiceAccountName: "default"}},
expectRejection: true,
resource: "serviceaccounts",
},
{
name: "Empty Volume list",
pod: &api.Pod{Spec: api.PodSpec{Volumes: nil}},
expectRejection: false,
},
{
name: "Non empty volume list with HostPath volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-hostpath", VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with EmptyDir volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-emptydir", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with Secret volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-secret", VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{}}},
}}},
expectRejection: true,
resource: "secrets (via secret volumes)",
},
{
name: "Non empty volume list with ConfigMap volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-configmap", VolumeSource: api.VolumeSource{ConfigMap: &api.ConfigMapVolumeSource{}}},
}}},
expectRejection: true,
resource: "configmaps (via configmap volumes)",
},
{
name: "Non empty volume list with GCEPersistentDisk volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-gce", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with AWSElasticBlockStore volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-aws", VolumeSource: api.VolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with GitRepo volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-gitrepo", VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with NFS volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-nfs", VolumeSource: api.VolumeSource{NFS: &api.NFSVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with ISCSI volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-iscsi", VolumeSource: api.VolumeSource{ISCSI: &api.ISCSIVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with Glusterfs volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-glusterfs", VolumeSource: api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}},
}}},
expectRejection: true,
resource: "endpoints (via glusterFS volumes)",
},
{
name: "Non empty volume list with PersistentVolumeClaim",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-pvc", VolumeSource: api.VolumeSource{PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{}}},
}}},
expectRejection: true,
resource: "persistentvolumeclaims",
},
{
name: "Non empty volume list with RBD volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-rbd", VolumeSource: api.VolumeSource{RBD: &api.RBDVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with FlexVolume volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-flexvolume", VolumeSource: api.VolumeSource{FlexVolume: &api.FlexVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with Cinder volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-cinder", VolumeSource: api.VolumeSource{Cinder: &api.CinderVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with CephFS volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-cephfs", VolumeSource: api.VolumeSource{CephFS: &api.CephFSVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with Flocker volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-flocker", VolumeSource: api.VolumeSource{Flocker: &api.FlockerVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with DownwardAPI volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-downwardapi", VolumeSource: api.VolumeSource{DownwardAPI: &api.DownwardAPIVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with FC volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-fc", VolumeSource: api.VolumeSource{FC: &api.FCVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with AzureFile volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-azurefile", VolumeSource: api.VolumeSource{AzureFile: &api.AzureFileVolumeSource{}}},
}}},
expectRejection: true,
resource: "secrets (via azureFile volumes)",
},
{
name: "Non empty volume list with VsphereVolume volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-vsphere", VolumeSource: api.VolumeSource{VsphereVolume: &api.VsphereVirtualDiskVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with Quobyte volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-quobyte", VolumeSource: api.VolumeSource{Quobyte: &api.QuobyteVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with AzureDisk volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-azuredisk", VolumeSource: api.VolumeSource{AzureDisk: &api.AzureDiskVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with PhotonPersistentDisk volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-photon", VolumeSource: api.VolumeSource{PhotonPersistentDisk: &api.PhotonPersistentDiskVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with Projected volume with clustertrustbundles",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{ClusterTrustBundle: &api.ClusterTrustBundleProjection{}}}}}},
}}},
expectRejection: true,
resource: "clustertrustbundles",
},
{
name: "Non empty volume list with Projected volume with secrets",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{Secret: &api.SecretProjection{}}}}}},
}}},
expectRejection: true,
resource: "secrets (via projected volumes)",
},
{
name: "Non empty volume list with Projected volume with configmap",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{ConfigMap: &api.ConfigMapProjection{}}}}}},
}}},
expectRejection: true,
resource: "configmaps (via projected volumes)",
},
{
name: "Non empty volume list with Projected volume with serviceaccounttoken",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{ServiceAccountToken: &api.ServiceAccountTokenProjection{}}}}}},
}}},
expectRejection: true,
resource: "serviceaccounts (via projected volumes)",
},
{
name: "Non empty volume list with Projected volume with downwardapi",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{DownwardAPI: &api.DownwardAPIProjection{}}}}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with Portworx volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-portworx", VolumeSource: api.VolumeSource{PortworxVolume: &api.PortworxVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with ScaleIO volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-scaleio", VolumeSource: api.VolumeSource{ScaleIO: &api.ScaleIOVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with StorageOS volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-storageos", VolumeSource: api.VolumeSource{StorageOS: &api.StorageOSVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "Non empty volume list with CSI volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-csi", VolumeSource: api.VolumeSource{CSI: &api.CSIVolumeSource{}}},
}}},
expectRejection: true,
resource: "csidrivers (via CSI volumes)",
},
{
name: "Non empty volume list with Ephemeral volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-ephemeral", VolumeSource: api.VolumeSource{Ephemeral: &api.EphemeralVolumeSource{}}},
}}},
expectRejection: true,
resource: "persistentvolumeclaims (via ephemeral volumes)",
},
{
name: "Non empty volume list with Image volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-image", VolumeSource: api.VolumeSource{Image: &api.ImageVolumeSource{}}},
}}},
expectRejection: false,
},
{
name: "No envs",
pod: &api.Pod{Spec: api.PodSpec{}},
expectRejection: false,
},
{
name: "Non empty Env with value",
pod: &api.Pod{Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "test-container",
Env: []api.EnvVar{
{
Name: "test-env",
Value: "TEST_ENV_VAL",
},
},
},
},
}},
expectRejection: false,
},
{
name: "Non empty EnvFrom with ConfigMap",
pod: &api.Pod{Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "test-container",
EnvFrom: []api.EnvFromSource{
{ConfigMapRef: &api.ConfigMapEnvSource{LocalObjectReference: api.LocalObjectReference{Name: "test"}}},
},
},
},
}},
expectRejection: true,
resource: "configmaps",
},
{
name: "Non empty EnvFrom with Secret",
pod: &api.Pod{Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "test-container",
EnvFrom: []api.EnvFromSource{
{SecretRef: &api.SecretEnvSource{LocalObjectReference: api.LocalObjectReference{Name: "test"}}},
},
},
},
}},
expectRejection: true,
resource: "secrets",
},
{
name: "Non empty Env with ConfigMap",
pod: &api.Pod{Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "test-container",
Env: []api.EnvVar{
{
Name: "test-env",
ValueFrom: &api.EnvVarSource{ConfigMapKeyRef: &api.ConfigMapKeySelector{LocalObjectReference: api.LocalObjectReference{Name: "test"}}},
},
},
},
},
}},
expectRejection: true,
resource: "configmaps",
},
{
name: "Non empty Env with Secret",
pod: &api.Pod{Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "test-container",
Env: []api.EnvVar{
{
Name: "test-env",
ValueFrom: &api.EnvVarSource{SecretKeyRef: &api.SecretKeySelector{LocalObjectReference: api.LocalObjectReference{Name: "test"}}},
},
},
},
},
}},
expectRejection: true,
resource: "secrets",
},
{
name: "Multiple volume list where invalid volume comes after valid volume source",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-portworx", VolumeSource: api.VolumeSource{PortworxVolume: &api.PortworxVolumeSource{}}},
{Name: "test-volume-configmap", VolumeSource: api.VolumeSource{ConfigMap: &api.ConfigMapVolumeSource{}}},
}}},
expectRejection: true,
resource: "configmaps (via configmap volumes)",
},
{
name: "Multiple volume list where invalid configmap volume comes after valid downwardapi projected volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{DownwardAPI: &api.DownwardAPIProjection{}}}}}},
{Name: "test-volume-configmap", VolumeSource: api.VolumeSource{ConfigMap: &api.ConfigMapVolumeSource{}}},
}}},
expectRejection: true,
resource: "configmaps (via configmap volumes)",
},
{
name: "Multiple volume list where invalid configmap projected volume comes after valid downwardapi projected volume",
pod: &api.Pod{Spec: api.PodSpec{Volumes: []api.Volume{
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{DownwardAPI: &api.DownwardAPIProjection{}}}}}},
{Name: "test-volume-projected", VolumeSource: api.VolumeSource{Projected: &api.ProjectedVolumeSource{Sources: []api.VolumeProjection{{ConfigMap: &api.ConfigMapProjection{}}}}}},
}}},
expectRejection: true,
resource: "configmaps (via projected volumes)",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actualResult, resource, _ := HasAPIObjectReference(test.pod)
if test.expectRejection != actualResult || resource != test.resource {
t.Errorf("unexpected result, expected %v but got %v, expected resource %v, but got %v", test.expectRejection, actualResult, test.resource, resource)
}
})
}
}

View File

@@ -17,8 +17,9 @@ limitations under the License.
package config
import (
"errors"
"fmt"
"reflect"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -175,8 +176,8 @@ func TestDecodeSinglePodRejectsClusterTrustBundleVolumes(t *testing.T) {
t.Errorf("unexpected error: %v", err)
}
_, _, err = tryDecodeSinglePod(json, noDefault)
if !errors.Is(err, ErrStaticPodTriedToUseClusterTrustBundle) {
t.Errorf("Got error %q, want %q", err, ErrStaticPodTriedToUseClusterTrustBundle)
if !strings.Contains(err.Error(), "may not reference clustertrustbundles") {
t.Errorf("Got error %q, want %q", err, fmt.Errorf("static pods may not reference clustertrustbundles API objects"))
}
}
@@ -231,8 +232,8 @@ func TestDecodeSinglePodRejectsResourceClaims(t *testing.T) {
t.Errorf("unexpected error: %v", err)
}
_, _, err = tryDecodeSinglePod(json, noDefault)
if !errors.Is(err, ErrStaticPodTriedToUseResourceClaims) {
t.Errorf("Got error %q, want %q", err, ErrStaticPodTriedToUseResourceClaims)
if !strings.Contains(err.Error(), "may not reference resourceclaims") {
t.Errorf("Got error %q, want %q", err, fmt.Errorf("static pods may not reference resourceclaims API objects"))
}
}

View File

@@ -1032,7 +1032,7 @@ func Test_nodePlugin_Admit(t *testing.T) {
name: "forbid create of pod referencing service account",
podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(sapod, nil, podKind, sapod.Namespace, sapod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "reference a service account",
err: "can not create pods that reference serviceaccounts",
},
{
name: "forbid create of pod referencing secret",
@@ -1056,7 +1056,7 @@ func Test_nodePlugin_Admit(t *testing.T) {
name: "forbid create of pod referencing persistentvolumeclaim",
podsGetter: noExistingPods,
attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
err: "reference persistentvolumeclaims",
err: "can not create pods that reference persistentvolumeclaims",
},
{
name: "forbid create of pod referencing resourceclaim",