mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Allow same-hostport-different-protocol
This commit is contained in:
		@@ -673,22 +673,23 @@ func validateProbe(probe *api.Probe) errs.ValidationErrorList {
 | 
				
			|||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AccumulateUniquePorts runs an extraction function on each Port of each Container,
 | 
					// accumulateUniquePorts runs an extraction function on each Port of each Container,
 | 
				
			||||||
// accumulating the results and returning an error if any ports conflict.
 | 
					// accumulating the results and returning an error if any ports conflict.
 | 
				
			||||||
func AccumulateUniquePorts(containers []api.Container, accumulator map[int]bool, extract func(*api.ContainerPort) int) errs.ValidationErrorList {
 | 
					func accumulateUniqueHostPorts(containers []api.Container, accumulator map[string]bool) errs.ValidationErrorList {
 | 
				
			||||||
	allErrs := errs.ValidationErrorList{}
 | 
						allErrs := errs.ValidationErrorList{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for ci, ctr := range containers {
 | 
						for ci, ctr := range containers {
 | 
				
			||||||
		cErrs := errs.ValidationErrorList{}
 | 
							cErrs := errs.ValidationErrorList{}
 | 
				
			||||||
		for pi := range ctr.Ports {
 | 
							for pi := range ctr.Ports {
 | 
				
			||||||
			port := extract(&ctr.Ports[pi])
 | 
								port := ctr.Ports[pi].HostPort
 | 
				
			||||||
			if port == 0 {
 | 
								if port == 0 {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if accumulator[port] {
 | 
								str := fmt.Sprintf("%d/%s", port, ctr.Ports[pi].Protocol)
 | 
				
			||||||
				cErrs = append(cErrs, errs.NewFieldDuplicate("port", port))
 | 
								if accumulator[str] {
 | 
				
			||||||
 | 
									cErrs = append(cErrs, errs.NewFieldDuplicate("port", str))
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				accumulator[port] = true
 | 
									accumulator[str] = true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		allErrs = append(allErrs, cErrs.PrefixIndex(ci)...)
 | 
							allErrs = append(allErrs, cErrs.PrefixIndex(ci)...)
 | 
				
			||||||
@@ -696,11 +697,11 @@ func AccumulateUniquePorts(containers []api.Container, accumulator map[int]bool,
 | 
				
			|||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// checkHostPortConflicts checks for colliding Port.HostPort values across
 | 
					// ValidateHostPorts checks for colliding Port.HostPort values across
 | 
				
			||||||
// a slice of containers.
 | 
					// a slice of containers.
 | 
				
			||||||
func checkHostPortConflicts(containers []api.Container) errs.ValidationErrorList {
 | 
					func ValidateHostPorts(containers []api.Container) errs.ValidationErrorList {
 | 
				
			||||||
	allPorts := map[int]bool{}
 | 
						allPorts := map[string]bool{}
 | 
				
			||||||
	return AccumulateUniquePorts(containers, allPorts, func(p *api.ContainerPort) int { return p.HostPort })
 | 
						return accumulateUniqueHostPorts(containers, allPorts)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func validateExecAction(exec *api.ExecAction) errs.ValidationErrorList {
 | 
					func validateExecAction(exec *api.ExecAction) errs.ValidationErrorList {
 | 
				
			||||||
@@ -817,11 +818,7 @@ func validateContainers(containers []api.Container, volumes util.StringSet) errs
 | 
				
			|||||||
		allErrs = append(allErrs, cErrs.PrefixIndex(i)...)
 | 
							allErrs = append(allErrs, cErrs.PrefixIndex(i)...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Check for colliding ports across all containers.
 | 
						// Check for colliding ports across all containers.
 | 
				
			||||||
	// TODO(thockin): This really is dependent on the network config of the host (IP per pod?)
 | 
						allErrs = append(allErrs, ValidateHostPorts(containers)...)
 | 
				
			||||||
	// and the config of the new manifest.  But we have not specced that out yet, so we'll just
 | 
					 | 
				
			||||||
	// make some assumptions for now.  As of now, pods share a network namespace, which means that
 | 
					 | 
				
			||||||
	// every Port.HostPort across the whole pod must be unique.
 | 
					 | 
				
			||||||
	allErrs = append(allErrs, checkHostPortConflicts(containers)...)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -785,6 +785,15 @@ func TestValidateContainers(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			ImagePullPolicy: "IfNotPresent",
 | 
								ImagePullPolicy: "IfNotPresent",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:  "same-host-port-different-protocol",
 | 
				
			||||||
 | 
								Image: "image",
 | 
				
			||||||
 | 
								Ports: []api.ContainerPort{
 | 
				
			||||||
 | 
									{ContainerPort: 80, HostPort: 80, Protocol: "TCP"},
 | 
				
			||||||
 | 
									{ContainerPort: 80, HostPort: 80, Protocol: "UDP"},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								ImagePullPolicy: "IfNotPresent",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{Name: "abc-1234", Image: "image", ImagePullPolicy: "IfNotPresent", SecurityContext: fakeValidSecurityContext(true)},
 | 
							{Name: "abc-1234", Image: "image", ImagePullPolicy: "IfNotPresent", SecurityContext: fakeValidSecurityContext(true)},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if errs := validateContainers(successCase, volumes); len(errs) != 0 {
 | 
						if errs := validateContainers(successCase, volumes); len(errs) != 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1354,14 +1354,11 @@ func (s podsByCreationTime) Less(i, j int) bool {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// checkHostPortConflicts detects pods with conflicted host ports.
 | 
					// checkHostPortConflicts detects pods with conflicted host ports.
 | 
				
			||||||
func checkHostPortConflicts(pods []*api.Pod) (fitting []*api.Pod, notFitting []*api.Pod) {
 | 
					func checkHostPortConflicts(pods []*api.Pod) (fitting []*api.Pod, notFitting []*api.Pod) {
 | 
				
			||||||
	ports := map[int]bool{}
 | 
					 | 
				
			||||||
	extract := func(p *api.ContainerPort) int { return p.HostPort }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Respect the pod creation order when resolving conflicts.
 | 
						// Respect the pod creation order when resolving conflicts.
 | 
				
			||||||
	sort.Sort(podsByCreationTime(pods))
 | 
						sort.Sort(podsByCreationTime(pods))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, pod := range pods {
 | 
						for _, pod := range pods {
 | 
				
			||||||
		if errs := validation.AccumulateUniquePorts(pod.Spec.Containers, ports, extract); len(errs) != 0 {
 | 
							if errs := validation.ValidateHostPorts(pod.Spec.Containers); len(errs) != 0 {
 | 
				
			||||||
			glog.Errorf("Pod %q: HostPort is already allocated, ignoring: %v", kubecontainer.GetPodFullName(pod), errs)
 | 
								glog.Errorf("Pod %q: HostPort is already allocated, ignoring: %v", kubecontainer.GetPodFullName(pod), errs)
 | 
				
			||||||
			notFitting = append(notFitting, pod)
 | 
								notFitting = append(notFitting, pod)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user