...

Source file src/k8s.io/kubernetes/pkg/kubelet/config/common_test.go

Documentation: k8s.io/kubernetes/pkg/kubelet/config

     1  /*
     2  Copyright 2015 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 config
    18  
    19  import (
    20  	"errors"
    21  	"reflect"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  
    26  	v1 "k8s.io/api/core/v1"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/runtime"
    29  	"k8s.io/apimachinery/pkg/types"
    30  	clientscheme "k8s.io/client-go/kubernetes/scheme"
    31  	"k8s.io/kubernetes/pkg/api/legacyscheme"
    32  	"k8s.io/kubernetes/pkg/apis/core"
    33  	"k8s.io/kubernetes/pkg/apis/core/validation"
    34  	"k8s.io/kubernetes/pkg/securitycontext"
    35  	"k8s.io/utils/ptr"
    36  )
    37  
    38  func noDefault(*core.Pod) error { return nil }
    39  
    40  func TestDecodeSinglePod(t *testing.T) {
    41  	grace := int64(30)
    42  	enableServiceLinks := v1.DefaultEnableServiceLinks
    43  	pod := &v1.Pod{
    44  		TypeMeta: metav1.TypeMeta{
    45  			APIVersion: "",
    46  		},
    47  		ObjectMeta: metav1.ObjectMeta{
    48  			Name:      "test",
    49  			UID:       "12345",
    50  			Namespace: "mynamespace",
    51  		},
    52  		Spec: v1.PodSpec{
    53  			RestartPolicy:                 v1.RestartPolicyAlways,
    54  			DNSPolicy:                     v1.DNSClusterFirst,
    55  			TerminationGracePeriodSeconds: &grace,
    56  			Containers: []v1.Container{{
    57  				Name:                     "image",
    58  				Image:                    "test/image",
    59  				ImagePullPolicy:          "IfNotPresent",
    60  				TerminationMessagePath:   "/dev/termination-log",
    61  				TerminationMessagePolicy: v1.TerminationMessageReadFile,
    62  				SecurityContext:          securitycontext.ValidSecurityContextWithContainerDefaults(),
    63  			}},
    64  			SecurityContext:    &v1.PodSecurityContext{},
    65  			SchedulerName:      v1.DefaultSchedulerName,
    66  			EnableServiceLinks: &enableServiceLinks,
    67  		},
    68  		Status: v1.PodStatus{
    69  			PodIP: "1.2.3.4",
    70  			PodIPs: []v1.PodIP{
    71  				{
    72  					IP: "1.2.3.4",
    73  				},
    74  			},
    75  		},
    76  	}
    77  	json, err := runtime.Encode(clientscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), pod)
    78  	if err != nil {
    79  		t.Errorf("unexpected error: %v", err)
    80  	}
    81  	parsed, podOut, err := tryDecodeSinglePod(json, noDefault)
    82  	if !parsed {
    83  		t.Errorf("expected to have parsed file: (%s)", string(json))
    84  	}
    85  	if err != nil {
    86  		t.Errorf("unexpected error: %v (%s)", err, string(json))
    87  	}
    88  	if !reflect.DeepEqual(pod, podOut) {
    89  		t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(json))
    90  	}
    91  
    92  	for _, gv := range legacyscheme.Scheme.PrioritizedVersionsForGroup(v1.GroupName) {
    93  		info, _ := runtime.SerializerInfoForMediaType(legacyscheme.Codecs.SupportedMediaTypes(), "application/yaml")
    94  		encoder := legacyscheme.Codecs.EncoderForVersion(info.Serializer, gv)
    95  		yaml, err := runtime.Encode(encoder, pod)
    96  		if err != nil {
    97  			t.Errorf("unexpected error: %v", err)
    98  		}
    99  		parsed, podOut, err = tryDecodeSinglePod(yaml, noDefault)
   100  		if !parsed {
   101  			t.Errorf("expected to have parsed file: (%s)", string(yaml))
   102  		}
   103  		if err != nil {
   104  			t.Errorf("unexpected error: %v (%s)", err, string(yaml))
   105  		}
   106  		if !reflect.DeepEqual(pod, podOut) {
   107  			t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, podOut, string(yaml))
   108  		}
   109  	}
   110  }
   111  
   112  func TestDecodeSinglePodRejectsClusterTrustBundleVolumes(t *testing.T) {
   113  	grace := int64(30)
   114  	enableServiceLinks := v1.DefaultEnableServiceLinks
   115  	pod := &v1.Pod{
   116  		TypeMeta: metav1.TypeMeta{
   117  			APIVersion: "",
   118  		},
   119  		ObjectMeta: metav1.ObjectMeta{
   120  			Name:      "test",
   121  			UID:       "12345",
   122  			Namespace: "mynamespace",
   123  		},
   124  		Spec: v1.PodSpec{
   125  			RestartPolicy:                 v1.RestartPolicyAlways,
   126  			DNSPolicy:                     v1.DNSClusterFirst,
   127  			TerminationGracePeriodSeconds: &grace,
   128  			Containers: []v1.Container{{
   129  				Name:                     "image",
   130  				Image:                    "test/image",
   131  				ImagePullPolicy:          "IfNotPresent",
   132  				TerminationMessagePath:   "/dev/termination-log",
   133  				TerminationMessagePolicy: v1.TerminationMessageReadFile,
   134  				SecurityContext:          securitycontext.ValidSecurityContextWithContainerDefaults(),
   135  				VolumeMounts: []v1.VolumeMount{
   136  					{
   137  						Name:      "ctb-volume",
   138  						MountPath: "/var/run/ctb-volume",
   139  					},
   140  				},
   141  			}},
   142  			Volumes: []v1.Volume{
   143  				{
   144  					Name: "ctb-volume",
   145  					VolumeSource: v1.VolumeSource{
   146  						Projected: &v1.ProjectedVolumeSource{
   147  							Sources: []v1.VolumeProjection{
   148  								{
   149  									ClusterTrustBundle: &v1.ClusterTrustBundleProjection{
   150  										Name: ptr.To("my-ctb"),
   151  										Path: "ctb-file",
   152  									},
   153  								},
   154  							},
   155  						},
   156  					},
   157  				},
   158  			},
   159  			SecurityContext:    &v1.PodSecurityContext{},
   160  			SchedulerName:      v1.DefaultSchedulerName,
   161  			EnableServiceLinks: &enableServiceLinks,
   162  		},
   163  		Status: v1.PodStatus{
   164  			PodIP: "1.2.3.4",
   165  			PodIPs: []v1.PodIP{
   166  				{
   167  					IP: "1.2.3.4",
   168  				},
   169  			},
   170  		},
   171  	}
   172  	json, err := runtime.Encode(clientscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), pod)
   173  	if err != nil {
   174  		t.Errorf("unexpected error: %v", err)
   175  	}
   176  	_, _, err = tryDecodeSinglePod(json, noDefault)
   177  	if !errors.Is(err, ErrStaticPodTriedToUseClusterTrustBundle) {
   178  		t.Errorf("Got error %q, want %q", err, ErrStaticPodTriedToUseClusterTrustBundle)
   179  	}
   180  }
   181  
   182  func TestDecodePodList(t *testing.T) {
   183  	grace := int64(30)
   184  	enableServiceLinks := v1.DefaultEnableServiceLinks
   185  	pod := &v1.Pod{
   186  		TypeMeta: metav1.TypeMeta{
   187  			APIVersion: "",
   188  		},
   189  		ObjectMeta: metav1.ObjectMeta{
   190  			Name:      "test",
   191  			UID:       "12345",
   192  			Namespace: "mynamespace",
   193  		},
   194  		Spec: v1.PodSpec{
   195  			RestartPolicy:                 v1.RestartPolicyAlways,
   196  			DNSPolicy:                     v1.DNSClusterFirst,
   197  			TerminationGracePeriodSeconds: &grace,
   198  			Containers: []v1.Container{{
   199  				Name:                     "image",
   200  				Image:                    "test/image",
   201  				ImagePullPolicy:          "IfNotPresent",
   202  				TerminationMessagePath:   "/dev/termination-log",
   203  				TerminationMessagePolicy: v1.TerminationMessageReadFile,
   204  
   205  				SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
   206  			}},
   207  			SecurityContext:    &v1.PodSecurityContext{},
   208  			SchedulerName:      v1.DefaultSchedulerName,
   209  			EnableServiceLinks: &enableServiceLinks,
   210  		},
   211  		Status: v1.PodStatus{
   212  			PodIP: "1.2.3.4",
   213  			PodIPs: []v1.PodIP{
   214  				{
   215  					IP: "1.2.3.4",
   216  				},
   217  			},
   218  		},
   219  	}
   220  	podList := &v1.PodList{
   221  		Items: []v1.Pod{*pod},
   222  	}
   223  	json, err := runtime.Encode(clientscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), podList)
   224  	if err != nil {
   225  		t.Errorf("unexpected error: %v", err)
   226  	}
   227  	parsed, podListOut, err := tryDecodePodList(json, noDefault)
   228  	if !parsed {
   229  		t.Errorf("expected to have parsed file: (%s)", string(json))
   230  	}
   231  	if err != nil {
   232  		t.Errorf("unexpected error: %v (%s)", err, string(json))
   233  	}
   234  	if !reflect.DeepEqual(podList, &podListOut) {
   235  		t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", podList, &podListOut, string(json))
   236  	}
   237  
   238  	for _, gv := range legacyscheme.Scheme.PrioritizedVersionsForGroup(v1.GroupName) {
   239  		info, _ := runtime.SerializerInfoForMediaType(legacyscheme.Codecs.SupportedMediaTypes(), "application/yaml")
   240  		encoder := legacyscheme.Codecs.EncoderForVersion(info.Serializer, gv)
   241  		yaml, err := runtime.Encode(encoder, podList)
   242  		if err != nil {
   243  			t.Errorf("unexpected error: %v", err)
   244  		}
   245  
   246  		parsed, podListOut, err = tryDecodePodList(yaml, noDefault)
   247  		if !parsed {
   248  			t.Errorf("expected to have parsed file: (%s): %v", string(yaml), err)
   249  			continue
   250  		}
   251  		if err != nil {
   252  			t.Errorf("unexpected error: %v (%s)", err, string(yaml))
   253  			continue
   254  		}
   255  		if !reflect.DeepEqual(podList, &podListOut) {
   256  			t.Errorf("expected:\n%#v\ngot:\n%#v\n%s", pod, &podListOut, string(yaml))
   257  		}
   258  	}
   259  }
   260  
   261  func TestStaticPodNameGenerate(t *testing.T) {
   262  	testCases := []struct {
   263  		nodeName  types.NodeName
   264  		podName   string
   265  		expected  string
   266  		overwrite string
   267  		shouldErr bool
   268  	}{
   269  		{
   270  			"node1",
   271  			"static-pod1",
   272  			"static-pod1-node1",
   273  			"",
   274  			false,
   275  		},
   276  		{
   277  			"Node1",
   278  			"static-pod1",
   279  			"static-pod1-node1",
   280  			"",
   281  			false,
   282  		},
   283  		{
   284  			"NODE1",
   285  			"static-pod1",
   286  			"static-pod1-node1",
   287  			"static-pod1-NODE1",
   288  			true,
   289  		},
   290  	}
   291  	for _, c := range testCases {
   292  		assert.Equal(t, c.expected, generatePodName(c.podName, c.nodeName), "wrong pod name generated")
   293  		pod := &core.Pod{}
   294  		pod.Name = c.podName
   295  		if c.overwrite != "" {
   296  			pod.Name = c.overwrite
   297  		}
   298  		errs := validation.ValidatePodCreate(pod, validation.PodValidationOptions{})
   299  		if c.shouldErr {
   300  			specNameErrored := false
   301  			for _, err := range errs {
   302  				if err.Field == "metadata.name" {
   303  					specNameErrored = true
   304  				}
   305  			}
   306  			assert.NotEmpty(t, specNameErrored, "expecting error")
   307  		} else {
   308  			for _, err := range errs {
   309  				if err.Field == "metadata.name" {
   310  					t.Fail()
   311  				}
   312  			}
   313  		}
   314  	}
   315  }
   316  

View as plain text