Field status.hostIPs added for Pod (#101566)

* Add FeatureGate PodHostIPs

* Add HostIPs field and update PodIPs field

* Types conversion

* Add dropDisabledStatusFields

* Add HostIPs for kubelet

* Add fuzzer for PodStatus

* Add status.hostIPs in ConvertDownwardAPIFieldLabel

* Add status.hostIPs in validEnvDownwardAPIFieldPathExpressions

* Downward API support for status.hostIPs

* Add DownwardAPI validation for status.hostIPs

* Add e2e to check that hostIPs works

* Add e2e to check that Downward API works

* Regenerate
This commit is contained in:
Shiming Zhang
2022-03-30 02:46:07 +08:00
committed by GitHub
parent 05b59e7717
commit 61b3c028ba
32 changed files with 2064 additions and 1072 deletions

View File

@@ -434,6 +434,8 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
AllowExpandedDNSConfig: utilfeature.DefaultFeatureGate.Enabled(features.ExpandedDNSConfig) || haveSameExpandedDNSConfig(podSpec, oldPodSpec),
// Allow pod spec to use OS field
AllowOSField: utilfeature.DefaultFeatureGate.Enabled(features.IdentifyPodOS),
// Allow pod spec to use status.hostIPs in downward API if feature is enabled
AllowHostIPsField: utilfeature.DefaultFeatureGate.Enabled(features.PodHostIPs),
// The default sysctl value does not contain a forward slash, and in 1.24 we intend to relax this to be true by default
AllowSysctlRegexContainSlash: false,
}
@@ -454,6 +456,9 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
// if old spec has OS field set, we must allow it
opts.AllowOSField = opts.AllowOSField || oldPodSpec.OS != nil
// if old spec has status.hostIPs downwardAPI set, we must allow it
opts.AllowHostIPsField = opts.AllowHostIPsField || hasUsedDownwardAPIFieldPathWithPodSpec(oldPodSpec, "status.hostIPs")
// if old spec used non-integer multiple of huge page unit size, we must allow it
opts.AllowIndivisibleHugePagesValues = usesIndivisibleHugePagesValues(oldPodSpec)
@@ -470,6 +475,57 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
return opts
}
func hasUsedDownwardAPIFieldPathWithPodSpec(podSpec *api.PodSpec, fieldPath string) bool {
if podSpec == nil {
return false
}
for _, vol := range podSpec.Volumes {
if hasUsedDownwardAPIFieldPathWithVolume(&vol, fieldPath) {
return true
}
}
for _, c := range podSpec.InitContainers {
if hasUsedDownwardAPIFieldPathWithContainer(&c, fieldPath) {
return true
}
}
for _, c := range podSpec.Containers {
if hasUsedDownwardAPIFieldPathWithContainer(&c, fieldPath) {
return true
}
}
return false
}
func hasUsedDownwardAPIFieldPathWithVolume(volume *api.Volume, fieldPath string) bool {
if volume == nil {
return false
}
if volume.DownwardAPI != nil {
for _, file := range volume.DownwardAPI.Items {
if file.FieldRef != nil &&
file.FieldRef.FieldPath == fieldPath {
return true
}
}
}
return false
}
func hasUsedDownwardAPIFieldPathWithContainer(container *api.Container, fieldPath string) bool {
if container == nil {
return false
}
for _, env := range container.Env {
if env.ValueFrom != nil &&
env.ValueFrom.FieldRef != nil &&
env.ValueFrom.FieldRef.FieldPath == fieldPath {
return true
}
}
return false
}
// GetValidationOptionsFromPodTemplate will return pod validation options for specified template.
func GetValidationOptionsFromPodTemplate(podTemplate, oldPodTemplate *api.PodTemplateSpec) apivalidation.PodValidationOptions {
var newPodSpec, oldPodSpec *api.PodSpec
@@ -512,19 +568,39 @@ func DropDisabledTemplateFields(podTemplate, oldPodTemplate *api.PodTemplateSpec
func DropDisabledPodFields(pod, oldPod *api.Pod) {
var (
podSpec *api.PodSpec
podStatus *api.PodStatus
podAnnotations map[string]string
oldPodSpec *api.PodSpec
oldPodStatus *api.PodStatus
oldPodAnnotations map[string]string
)
if pod != nil {
podSpec = &pod.Spec
podAnnotations = pod.Annotations
podStatus = &pod.Status
}
if oldPod != nil {
oldPodSpec = &oldPod.Spec
oldPodAnnotations = oldPod.Annotations
oldPodStatus = &oldPod.Status
}
dropDisabledFields(podSpec, podAnnotations, oldPodSpec, oldPodAnnotations)
dropDisabledStatusFields(podStatus, oldPodStatus)
}
// dropDisabledStatusFields removes disabled fields from the pod status
func dropDisabledStatusFields(podStatus *api.PodStatus, oldPodStatus *api.PodStatus) {
// drop HostIPs to empty (disable PodHostIPs).
if !utilfeature.DefaultFeatureGate.Enabled(features.PodHostIPs) && !hostIPsInUse(oldPodStatus) {
podStatus.HostIPs = nil
}
}
func hostIPsInUse(podStatus *api.PodStatus) bool {
if podStatus == nil {
return false
}
return len(podStatus.HostIPs) > 0
}
// dropDisabledFields removes disabled fields from the pod metadata and spec.