Example #1
0
func TestExtractFromDir(t *testing.T) {
	manifest, expectedPod := ExampleManifestAndPod("1")
	manifest2, expectedPod2 := ExampleManifestAndPod("2")

	manifests := []api.ContainerManifest{manifest, manifest2}
	pods := []api.BoundPod{expectedPod, expectedPod2}
	files := make([]*os.File, len(manifests))

	dirName, err := ioutil.TempDir("", "foo")
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	for i, manifest := range manifests {
		data, err := json.Marshal(manifest)
		if err != nil {
			t.Errorf("Unexpected error: %v", err)
			continue
		}
		file, err := ioutil.TempFile(dirName, manifest.ID)
		if err != nil {
			t.Errorf("Unexpected error: %v", err)
			continue
		}
		name := file.Name()
		if err := file.Close(); err != nil {
			t.Errorf("Unexpected error: %v", err)
			continue
		}
		ioutil.WriteFile(name, data, 0755)
		files[i] = file
	}

	ch := make(chan interface{}, 1)
	c := sourceFile{dirName, ch}
	err = c.extractFromPath()
	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	update := (<-ch).(kubelet.PodUpdate)
	for i := range update.Pods {
		update.Pods[i].Namespace = "foobar"
		update.Pods[i].SelfLink = ""
	}
	expected := CreatePodUpdate(kubelet.SET, kubelet.FileSource, pods...)
	for i := range expected.Pods {
		expected.Pods[i].Namespace = "foobar"
	}
	sort.Sort(sortedPods(update.Pods))
	sort.Sort(sortedPods(expected.Pods))
	if !api.Semantic.DeepEqual(expected, update) {
		t.Fatalf("Expected %#v, Got %#v", expected, update)
	}
	for i := range update.Pods {
		if errs := validation.ValidateBoundPod(&update.Pods[i]); len(errs) != 0 {
			t.Errorf("Expected no validation errors on %#v, Got %#v", update.Pods[i], errs)
		}
	}
}
Example #2
0
func filterInvalidPods(pods []api.BoundPod, source string) (filtered []*api.BoundPod) {
	names := util.StringSet{}
	for i := range pods {
		pod := &pods[i]
		var errlist []error
		if errs := validation.ValidateBoundPod(pod); len(errs) != 0 {
			errlist = append(errlist, errs...)
			// If validation fails, don't trust it any further -
			// even Name could be bad.
		} else {
			name := podUniqueName(pod)
			if names.Has(name) {
				errlist = append(errlist, apierrs.NewFieldDuplicate("name", pod.Name))
			} else {
				names.Insert(name)
			}
		}
		if len(errlist) > 0 {
			name := bestPodIdentString(pod)
			err := utilerrors.NewAggregate(errlist)
			glog.Warningf("Pod[%d] (%s) from %s failed validation, ignoring: %v", i+1, name, source, err)
			record.Eventf(pod, "failedValidation", "Error validating pod %s from %s, ignoring: %v", name, source, err)
			continue
		}
		filtered = append(filtered, pod)
	}
	return
}
Example #3
0
func filterInvalidPods(pods []api.BoundPod, source string) (filtered []*api.BoundPod) {
	names := util.StringSet{}
	for i := range pods {
		var errors []error
		name := podUniqueName(&pods[i])
		if names.Has(name) {
			errors = append(errors, apierrs.NewFieldDuplicate("name", pods[i].Name))
		} else {
			names.Insert(name)
		}
		if errs := validation.ValidateBoundPod(&pods[i]); len(errs) != 0 {
			errors = append(errors, errs...)
		}
		if len(errors) > 0 {
			glog.Warningf("Pod %d (%s) from %s failed validation, ignoring: %v", i+1, pods[i].Name, source, errors)
			continue
		}
		filtered = append(filtered, &pods[i])
	}
	return
}
Example #4
0
func TestExtractFromHTTP(t *testing.T) {
	var testCases = []struct {
		desc      string
		manifests interface{}
		expected  kubelet.PodUpdate
	}{
		{
			desc:      "Single manifest",
			manifests: api.ContainerManifest{Version: "v1beta1", ID: "foo"},
			expected: CreatePodUpdate(kubelet.SET,
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						Name:      "foo",
						Namespace: "default",
					},
					Spec: api.PodSpec{
						RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
					},
				}),
		},
		{
			desc: "Multiple manifests",
			manifests: []api.ContainerManifest{
				{Version: "v1beta1", ID: "", Containers: []api.Container{{Name: "1", Image: "foo"}}},
				{Version: "v1beta1", ID: "bar", Containers: []api.Container{{Name: "1", Image: "foo"}}},
			},
			expected: CreatePodUpdate(kubelet.SET,
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						Name:      "1",
						Namespace: "default",
					},
					Spec: api.PodSpec{
						Containers: []api.Container{{
							Name:  "1",
							Image: "foo",
							TerminationMessagePath: "/dev/termination-log"}},
					},
				},
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						Name:      "bar",
						Namespace: "default",
					},
					Spec: api.PodSpec{
						Containers: []api.Container{{
							Name:  "1",
							Image: "foo",
							TerminationMessagePath: "/dev/termination-log"}},
					},
				}),
		},
		{
			desc:      "Empty Array",
			manifests: []api.ContainerManifest{},
			expected:  CreatePodUpdate(kubelet.SET),
		},
	}
	for _, testCase := range testCases {
		data, err := json.Marshal(testCase.manifests)
		if err != nil {
			t.Fatalf("%s: Some weird json problem: %v", testCase.desc, err)
		}
		fakeHandler := util.FakeHandler{
			StatusCode:   200,
			ResponseBody: string(data),
		}
		testServer := httptest.NewServer(&fakeHandler)
		defer testServer.Close()
		ch := make(chan interface{}, 1)
		c := sourceURL{testServer.URL, ch, nil}
		if err := c.extractFromURL(); err != nil {
			t.Errorf("%s: Unexpected error: %v", testCase.desc, err)
			continue
		}
		update := (<-ch).(kubelet.PodUpdate)
		if !reflect.DeepEqual(testCase.expected, update) {
			t.Errorf("%s: Expected: %#v, Got: %#v", testCase.desc, testCase.expected, update)
		}
		for i := range update.Pods {
			if errs := validation.ValidateBoundPod(&update.Pods[i]); len(errs) != 0 {
				t.Errorf("%s: Expected no validation errors on %#v, Got %#v", testCase.desc, update.Pods[i], errs)
			}
		}
	}
}
Example #5
0
func TestExtractFromHTTP(t *testing.T) {
	var testCases = []struct {
		desc      string
		manifests interface{}
		expected  kubelet.PodUpdate
	}{
		{
			desc: "Single manifest",
			manifests: v1beta1.ContainerManifest{Version: "v1beta1", ID: "foo", UUID: "111",
				Containers: []v1beta1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1beta1.PullAlways}}},
			expected: CreatePodUpdate(kubelet.SET,
				kubelet.HTTPSource,
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						UID:       "111",
						Name:      "foo",
						Namespace: "foobar",
					},
					Spec: api.PodSpec{
						RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
						DNSPolicy:     api.DNSClusterFirst,
						Containers: []api.Container{{
							Name:  "1",
							Image: "foo",
							TerminationMessagePath: "/dev/termination-log",
							ImagePullPolicy:        "Always"}},
					},
				}),
		},
		{
			desc:      "Single manifest without ID",
			manifests: api.ContainerManifest{Version: "v1beta1", UUID: "111"},
			expected: CreatePodUpdate(kubelet.SET,
				kubelet.HTTPSource,
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						UID:       "111",
						Name:      "111",
						Namespace: "foobar",
					},
					Spec: api.PodSpec{
						RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
						DNSPolicy:     api.DNSClusterFirst,
					},
				}),
		},
		{
			desc: "Single manifest with v1beta2",
			manifests: v1beta1.ContainerManifest{Version: "v1beta2", ID: "foo", UUID: "111",
				Containers: []v1beta1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1beta1.PullAlways}}},
			expected: CreatePodUpdate(kubelet.SET,
				kubelet.HTTPSource,
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						UID:       "111",
						Name:      "foo",
						Namespace: "foobar",
					},
					Spec: api.PodSpec{
						RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
						DNSPolicy:     api.DNSClusterFirst,
						Containers: []api.Container{{
							Name:  "1",
							Image: "foo",
							TerminationMessagePath: "/dev/termination-log",
							ImagePullPolicy:        "Always"}},
					},
				}),
		},
		{
			desc: "Multiple manifests",
			manifests: []v1beta1.ContainerManifest{
				{Version: "v1beta1", ID: "foo", UUID: "111",
					Containers: []v1beta1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1beta1.PullAlways}}},
				{Version: "v1beta1", ID: "bar", UUID: "222",
					Containers: []v1beta1.Container{{Name: "1", Image: "foo", ImagePullPolicy: ""}}},
			},
			expected: CreatePodUpdate(kubelet.SET,
				kubelet.HTTPSource,
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						UID:       "111",
						Name:      "foo",
						Namespace: "foobar",
					},
					Spec: api.PodSpec{
						RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
						DNSPolicy:     api.DNSClusterFirst,
						Containers: []api.Container{{
							Name:  "1",
							Image: "foo",
							TerminationMessagePath: "/dev/termination-log",
							ImagePullPolicy:        "Always"}},
					},
				},
				api.BoundPod{
					ObjectMeta: api.ObjectMeta{
						UID:       "222",
						Name:      "bar",
						Namespace: "foobar",
					},
					Spec: api.PodSpec{
						RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
						DNSPolicy:     api.DNSClusterFirst,
						Containers: []api.Container{{
							Name:  "1",
							Image: "foo",
							TerminationMessagePath: "/dev/termination-log",
							ImagePullPolicy:        "PullIfNotPresent"}},
					},
				}),
		},
		{
			desc:      "Empty Array",
			manifests: []v1beta1.ContainerManifest{},
			expected:  CreatePodUpdate(kubelet.SET, kubelet.HTTPSource),
		},
	}
	for _, testCase := range testCases {
		data, err := json.Marshal(testCase.manifests)
		if err != nil {
			t.Fatalf("%s: Some weird json problem: %v", testCase.desc, err)
		}
		fakeHandler := util.FakeHandler{
			StatusCode:   200,
			ResponseBody: string(data),
		}
		testServer := httptest.NewServer(&fakeHandler)
		defer testServer.Close()
		ch := make(chan interface{}, 1)
		c := sourceURL{testServer.URL, ch, nil}
		if err := c.extractFromURL(); err != nil {
			t.Errorf("%s: Unexpected error: %v", testCase.desc, err)
			continue
		}
		update := (<-ch).(kubelet.PodUpdate)

		for i := range update.Pods {
			// There's no way to provide namespace in ContainerManifest, so
			// it will be defaulted.
			if !strings.HasPrefix(update.Pods[i].ObjectMeta.Namespace, "url-") {
				t.Errorf("Unexpected namespace: %s", update.Pods[0].ObjectMeta.Namespace)
			}
			update.Pods[i].ObjectMeta.Namespace = "foobar"
		}
		if !api.Semantic.DeepEqual(testCase.expected, update) {
			t.Errorf("%s: Expected: %#v, Got: %#v", testCase.desc, testCase.expected, update)
		}
		for i := range update.Pods {
			if errs := validation.ValidateBoundPod(&update.Pods[i]); len(errs) != 0 {
				t.Errorf("%s: Expected no validation errors on %#v, Got %v", testCase.desc, update.Pods[i], errors.NewAggregate(errs))
			}
		}
	}
}