示例#1
0
func TestValidatePodSpec(t *testing.T) {
	successCases := []api.PodSpec{
		{}, // empty is valid, if not very useful */
		{ // Populate basic fields, leave defaults for most.
			Volumes:    []api.Volume{{Name: "vol"}},
			Containers: []api.Container{{Name: "ctr", Image: "image"}},
		},
		{ // Populate all fields.
			Volumes: []api.Volume{
				{Name: "vol"},
			},
			Containers:    []api.Container{{Name: "ctr", Image: "image"}},
			RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}},
			DNSPolicy:     api.DNSClusterFirst,
			NodeSelector: map[string]string{
				"key": "value",
			},
			Host: "foobar",
		},
	}
	for i := range successCases {
		if errs := ValidatePodSpec(&successCases[i]); len(errs) != 0 {
			t.Errorf("expected success: %v", errs)
		}
	}

	failureCases := map[string]api.PodSpec{
		"bad volume": {
			Volumes: []api.Volume{{}},
		},
		"bad container": {
			Containers: []api.Container{{}},
		},
		"bad DNS policy": {
			DNSPolicy: api.DNSPolicy("invalid"),
		},
	}
	for k, v := range failureCases {
		if errs := ValidatePodSpec(&v); len(errs) == 0 {
			t.Errorf("expected failure for %q", k)
		}
	}

	defaultPod := api.PodSpec{} // all empty fields
	if errs := ValidatePodSpec(&defaultPod); len(errs) != 0 {
		t.Errorf("expected success: %v", errs)
	}
	if util.AllPtrFieldsNil(defaultPod.RestartPolicy) {
		t.Errorf("expected a default RestartPolicy")
	}
	if defaultPod.DNSPolicy == "" {
		t.Errorf("expected a default DNSPolicy")
	}
}
示例#2
0
func (plugin *emptyDirPlugin) CanSupport(spec *api.Volume) bool {
	if plugin.legacyMode {
		// Legacy mode instances can be cleaned up but not created anew.
		return false
	}

	if spec.Source == nil || util.AllPtrFieldsNil(spec.Source) {
		return true
	}
	if spec.Source.EmptyDir != nil {
		return true
	}
	return false
}
func init() {
	api.Scheme.AddDefaultingFuncs(
		func(obj *Volume) {
			if util.AllPtrFieldsNil(&obj.Source) {
				obj.Source = VolumeSource{
					EmptyDir: &EmptyDirVolumeSource{},
				}
			}
		},
		func(obj *Port) {
			if obj.Protocol == "" {
				obj.Protocol = ProtocolTCP
			}
		},
		func(obj *Container) {
			if obj.ImagePullPolicy == "" {
				// TODO(dchen1107): Move ParseImageName code to pkg/util
				parts := strings.Split(obj.Image, ":")
				// Check image tag
				if parts[len(parts)-1] == "latest" {
					obj.ImagePullPolicy = PullAlways
				} else {
					obj.ImagePullPolicy = PullIfNotPresent
				}
			}
			if obj.TerminationMessagePath == "" {
				obj.TerminationMessagePath = TerminationMessagePathDefault
			}
		},
		func(obj *RestartPolicy) {
			if util.AllPtrFieldsNil(obj) {
				obj.Always = &RestartPolicyAlways{}
			}
		},
		func(obj *Service) {
			if obj.Protocol == "" {
				obj.Protocol = ProtocolTCP
			}
			if obj.SessionAffinity == "" {
				obj.SessionAffinity = AffinityTypeNone
			}
		},
		func(obj *PodSpec) {
			if obj.DNSPolicy == "" {
				obj.DNSPolicy = DNSClusterFirst
			}
		},
		func(obj *ContainerManifest) {
			if obj.DNSPolicy == "" {
				obj.DNSPolicy = DNSClusterFirst
			}
		},
		func(obj *LivenessProbe) {
			if obj.TimeoutSeconds == 0 {
				obj.TimeoutSeconds = 1
			}
		},
		func(obj *Secret) {
			if obj.Type == "" {
				obj.Type = SecretTypeOpaque
			}
		},
		func(obj *Endpoints) {
			if obj.Protocol == "" {
				obj.Protocol = "TCP"
			}
		},
	)
}
示例#4
0
func addDefaultingFuncs() {
	api.Scheme.AddDefaultingFuncs(
		func(obj *ReplicationController) {
			var labels map[string]string
			if obj.Spec.Template != nil {
				labels = obj.Spec.Template.Labels
			}
			// TODO: support templates defined elsewhere when we support them in the API
			if labels != nil {
				if len(obj.Spec.Selector) == 0 {
					obj.Spec.Selector = labels
				}
				if len(obj.Labels) == 0 {
					obj.Labels = labels
				}
			}
			if obj.Spec.Replicas == nil {
				obj.Spec.Replicas = new(int)
				*obj.Spec.Replicas = 1
			}
		},
		func(obj *Volume) {
			if util.AllPtrFieldsNil(&obj.VolumeSource) {
				obj.VolumeSource = VolumeSource{
					EmptyDir: &EmptyDirVolumeSource{},
				}
			}
		},
		func(obj *ContainerPort) {
			if obj.Protocol == "" {
				obj.Protocol = ProtocolTCP
			}
		},
		func(obj *Container) {
			if obj.ImagePullPolicy == "" {
				// TODO(dchen1107): Move ParseImageName code to pkg/util
				parts := strings.Split(obj.Image, ":")
				// Check image tag
				if parts[len(parts)-1] == "latest" {
					obj.ImagePullPolicy = PullAlways
				} else {
					obj.ImagePullPolicy = PullIfNotPresent
				}
			}
			if obj.TerminationMessagePath == "" {
				obj.TerminationMessagePath = TerminationMessagePathDefault
			}
		},
		func(obj *ServiceSpec) {
			if obj.SessionAffinity == "" {
				obj.SessionAffinity = ServiceAffinityNone
			}
			if obj.Type == "" {
				obj.Type = ServiceTypeClusterIP
			}
			for i := range obj.Ports {
				sp := &obj.Ports[i]
				if sp.Protocol == "" {
					sp.Protocol = ProtocolTCP
				}
				if sp.TargetPort == util.NewIntOrStringFromInt(0) || sp.TargetPort == util.NewIntOrStringFromString("") {
					sp.TargetPort = util.NewIntOrStringFromInt(sp.Port)
				}
			}
		},
		func(obj *PodSpec) {
			if obj.DNSPolicy == "" {
				obj.DNSPolicy = DNSClusterFirst
			}
			if obj.RestartPolicy == "" {
				obj.RestartPolicy = RestartPolicyAlways
			}
			if obj.HostNetwork {
				defaultHostNetworkPorts(&obj.Containers)
			}
		},
		func(obj *Probe) {
			if obj.TimeoutSeconds == 0 {
				obj.TimeoutSeconds = 1
			}
		},
		func(obj *Secret) {
			if obj.Type == "" {
				obj.Type = SecretTypeOpaque
			}
		},
		func(obj *PersistentVolume) {
			if obj.Status.Phase == "" {
				obj.Status.Phase = VolumePending
			}
			if obj.Spec.PersistentVolumeReclaimPolicy == "" {
				obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain
			}
		},
		func(obj *PersistentVolumeClaim) {
			if obj.Status.Phase == "" {
				obj.Status.Phase = ClaimPending
			}
		},
		func(obj *Endpoints) {
			for i := range obj.Subsets {
				ss := &obj.Subsets[i]
				for i := range ss.Ports {
					ep := &ss.Ports[i]
					if ep.Protocol == "" {
						ep.Protocol = ProtocolTCP
					}
				}
			}
		},
		func(obj *HTTPGetAction) {
			if obj.Path == "" {
				obj.Path = "/"
			}
			if obj.Scheme == "" {
				obj.Scheme = URISchemeHTTP
			}
		},
		func(obj *NamespaceStatus) {
			if obj.Phase == "" {
				obj.Phase = NamespaceActive
			}
		},
		func(obj *Node) {
			if obj.Spec.ExternalID == "" {
				obj.Spec.ExternalID = obj.Name
			}
		},
		func(obj *ObjectFieldSelector) {
			if obj.APIVersion == "" {
				obj.APIVersion = "v1"
			}
		},
	)
}
示例#5
0
func init() {
	api.Scheme.AddDefaultingFuncs(
		func(obj *Volume) {
			if util.AllPtrFieldsNil(&obj.VolumeSource) {
				obj.VolumeSource = VolumeSource{
					EmptyDir: &EmptyDirVolumeSource{},
				}
			}
		},
		func(obj *ContainerPort) {
			if obj.Protocol == "" {
				obj.Protocol = ProtocolTCP
			}
		},
		func(obj *Container) {
			if obj.ImagePullPolicy == "" {
				// TODO(dchen1107): Move ParseImageName code to pkg/util
				parts := strings.Split(obj.Image, ":")
				// Check image tag
				if parts[len(parts)-1] == "latest" {
					obj.ImagePullPolicy = PullAlways
				} else {
					obj.ImagePullPolicy = PullIfNotPresent
				}
			}
			if obj.TerminationMessagePath == "" {
				obj.TerminationMessagePath = TerminationMessagePathDefault
			}
		},
		func(obj *Service) {
			if obj.Spec.Protocol == "" {
				obj.Spec.Protocol = ProtocolTCP
			}
			if obj.Spec.SessionAffinity == "" {
				obj.Spec.SessionAffinity = AffinityTypeNone
			}
		},
		func(obj *PodSpec) {
			if obj.DNSPolicy == "" {
				obj.DNSPolicy = DNSClusterFirst
			}
			if obj.RestartPolicy == "" {
				obj.RestartPolicy = RestartPolicyAlways
			}
		},
		func(obj *Probe) {
			if obj.TimeoutSeconds == 0 {
				obj.TimeoutSeconds = 1
			}
		},
		func(obj *Secret) {
			if obj.Type == "" {
				obj.Type = SecretTypeOpaque
			}
		},
		func(obj *Endpoints) {
			if obj.Protocol == "" {
				obj.Protocol = "TCP"
			}
		},
		func(obj *HTTPGetAction) {
			if obj.Path == "" {
				obj.Path = "/"
			}
		},
		func(obj *ServiceSpec) {
			if obj.ContainerPort.Kind == util.IntstrInt && obj.ContainerPort.IntVal == 0 ||
				obj.ContainerPort.Kind == util.IntstrString && obj.ContainerPort.StrVal == "" {
				obj.ContainerPort = util.NewIntOrStringFromInt(obj.Port)
			}
		},
		func(obj *NamespaceStatus) {
			if obj.Phase == "" {
				obj.Phase = NamespaceActive
			}
		},
	)
}
func init() {
	api.Scheme.AddDefaultingFuncs(
		func(obj *ReplicationController) {
			if len(obj.DesiredState.ReplicaSelector) == 0 {
				obj.DesiredState.ReplicaSelector = obj.DesiredState.PodTemplate.Labels
			}
			if len(obj.Labels) == 0 {
				obj.Labels = obj.DesiredState.PodTemplate.Labels
			}
		},
		func(obj *Volume) {
			if util.AllPtrFieldsNil(&obj.Source) {
				glog.Errorf("Defaulting volume source for %v", obj)
				obj.Source = VolumeSource{
					EmptyDir: &EmptyDirVolumeSource{},
				}
			}
		},
		func(obj *ContainerPort) {
			if obj.Protocol == "" {
				obj.Protocol = ProtocolTCP
			}
		},
		func(obj *Container) {
			if obj.ImagePullPolicy == "" {
				// TODO(dchen1107): Move ParseImageName code to pkg/util
				parts := strings.Split(obj.Image, ":")
				// Check image tag
				if parts[len(parts)-1] == "latest" {
					obj.ImagePullPolicy = PullAlways
				} else {
					obj.ImagePullPolicy = PullIfNotPresent
				}
			}
			if obj.TerminationMessagePath == "" {
				obj.TerminationMessagePath = TerminationMessagePathDefault
			}
		},
		func(obj *RestartPolicy) {
			if util.AllPtrFieldsNil(obj) {
				obj.Always = &RestartPolicyAlways{}
			}
		},
		func(obj *Service) {
			if obj.Protocol == "" {
				obj.Protocol = ProtocolTCP
			}
			if obj.SessionAffinity == "" {
				obj.SessionAffinity = AffinityTypeNone
			}
			for i := range obj.Ports {
				sp := &obj.Ports[i]
				if sp.Protocol == "" {
					sp.Protocol = ProtocolTCP
				}
				if sp.ContainerPort == util.NewIntOrStringFromInt(0) || sp.ContainerPort == util.NewIntOrStringFromString("") {
					sp.ContainerPort = util.NewIntOrStringFromInt(sp.Port)
				}
			}
		},
		func(obj *PodSpec) {
			if obj.DNSPolicy == "" {
				obj.DNSPolicy = DNSClusterFirst
			}
			if obj.HostNetwork {
				defaultHostNetworkPorts(&obj.Containers)
			}
		},
		func(obj *ContainerManifest) {
			if obj.DNSPolicy == "" {
				obj.DNSPolicy = DNSClusterFirst
			}
			if obj.HostNetwork {
				defaultHostNetworkPorts(&obj.Containers)
			}
		},
		func(obj *LivenessProbe) {
			if obj.TimeoutSeconds == 0 {
				obj.TimeoutSeconds = 1
			}
		},
		func(obj *Secret) {
			if obj.Type == "" {
				obj.Type = SecretTypeOpaque
			}
		},
		func(obj *Endpoints) {
			if obj.Protocol == "" {
				obj.Protocol = ProtocolTCP
			}
			if len(obj.Subsets) == 0 && len(obj.Endpoints) > 0 {
				// Must be a legacy-style object - populate
				// Subsets from the older fields.  Do this the
				// simplest way, which is dumb (but valid).
				for i := range obj.Endpoints {
					host, portStr, err := net.SplitHostPort(obj.Endpoints[i])
					if err != nil {
						glog.Errorf("failed to SplitHostPort(%q)", obj.Endpoints[i])
					}
					var tgtRef *ObjectReference
					for j := range obj.TargetRefs {
						if obj.TargetRefs[j].Endpoint == obj.Endpoints[i] {
							tgtRef = &ObjectReference{}
							*tgtRef = obj.TargetRefs[j].ObjectReference
						}
					}
					port, err := strconv.Atoi(portStr)
					if err != nil {
						glog.Errorf("failed to Atoi(%q)", portStr)
					}
					obj.Subsets = append(obj.Subsets, EndpointSubset{
						Addresses: []EndpointAddress{{IP: host, TargetRef: tgtRef}},
						Ports:     []EndpointPort{{Protocol: obj.Protocol, Port: port}},
					})
				}
			}
			for i := range obj.Subsets {
				ss := &obj.Subsets[i]
				for i := range ss.Ports {
					ep := &ss.Ports[i]
					if ep.Protocol == "" {
						ep.Protocol = ProtocolTCP
					}
				}
			}
		},
		func(obj *HTTPGetAction) {
			if obj.Path == "" {
				obj.Path = "/"
			}
		},
		func(obj *NamespaceStatus) {
			if obj.Phase == "" {
				obj.Phase = NamespaceActive
			}
		},
		func(obj *Minion) {
			if obj.ExternalID == "" {
				obj.ExternalID = obj.ID
			}
		},
	)
}