Merge pull request #1713 from brendandburns/update

Add update to the pod etcd handler.
This commit is contained in:
Daniel Smith
2014-10-13 17:42:30 -07:00
4 changed files with 380 additions and 1 deletions

View File

@@ -17,6 +17,7 @@ limitations under the License.
package validation
import (
"reflect"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
@@ -341,6 +342,30 @@ func ValidatePod(pod *api.Pod) errs.ErrorList {
return allErrs
}
// ValidatePodUpdate tests to see if the update is legal
func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ErrorList {
allErrs := errs.ErrorList{}
if len(newPod.DesiredState.Manifest.Containers) != len(oldPod.DesiredState.Manifest.Containers) {
allErrs = append(allErrs, errs.NewFieldInvalid("DesiredState.Manifest.Containers", newPod.DesiredState.Manifest.Containers))
return allErrs
}
pod := *newPod
pod.Labels = oldPod.Labels
pod.TypeMeta.ResourceVersion = oldPod.TypeMeta.ResourceVersion
// Tricky, we need to copy the container list so that we don't overwrite the update
var newContainers []api.Container
for ix, container := range pod.DesiredState.Manifest.Containers {
container.Image = oldPod.DesiredState.Manifest.Containers[ix].Image
newContainers = append(newContainers, container)
}
pod.DesiredState.Manifest.Containers = newContainers
if !reflect.DeepEqual(&pod, oldPod) {
allErrs = append(allErrs, errs.NewFieldInvalid("DesiredState.Manifest.Containers", newPod.DesiredState.Manifest.Containers))
}
return allErrs
}
// ValidateService tests if required fields in the service are set.
func ValidateService(service *api.Service) errs.ErrorList {
allErrs := errs.ErrorList{}

View File

@@ -416,6 +416,179 @@ func TestValidatePod(t *testing.T) {
}
}
func TestValidatePodUpdate(t *testing.T) {
tests := []struct {
a api.Pod
b api.Pod
isValid bool
test string
}{
{api.Pod{}, api.Pod{}, true, "nothing"},
{
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
},
api.Pod{
TypeMeta: api.TypeMeta{ID: "bar"},
},
false,
"ids",
},
{
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
Labels: map[string]string{
"foo": "bar",
},
},
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
Labels: map[string]string{
"bar": "foo",
},
},
true,
"labels",
},
{
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V1",
},
},
},
},
},
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V2",
},
{
Image: "bar:V2",
},
},
},
},
},
false,
"more containers",
},
{
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V1",
},
},
},
},
},
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V2",
},
},
},
},
},
true,
"image change",
},
{
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V1",
CPU: 100,
},
},
},
},
},
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V2",
CPU: 1000,
},
},
},
},
},
false,
"cpu change",
},
{
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V1",
Ports: []api.Port{
{HostPort: 8080, ContainerPort: 80},
},
},
},
},
},
},
api.Pod{
TypeMeta: api.TypeMeta{ID: "foo"},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Containers: []api.Container{
{
Image: "foo:V2",
Ports: []api.Port{
{HostPort: 8000, ContainerPort: 80},
},
},
},
},
},
},
false,
"port change",
},
}
for _, test := range tests {
errs := ValidatePodUpdate(&test.a, &test.b)
if test.isValid {
if len(errs) != 0 {
t.Errorf("unexpected invalid: %s %v, %v", test.test, test.a, test.b)
}
} else {
if len(errs) == 0 {
t.Errorf("unexpected valid: %s %v, %v", test.test, test.a, test.b)
}
}
}
}
func TestValidateService(t *testing.T) {
testCases := []struct {
name string