k8s.io/kubernetes@v1.29.3/pkg/api/service/warnings.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package service
    18  
    19  import (
    20  	"fmt"
    21  	"net/netip"
    22  
    23  	"k8s.io/apimachinery/pkg/util/validation/field"
    24  	api "k8s.io/kubernetes/pkg/apis/core"
    25  	"k8s.io/kubernetes/pkg/apis/core/helper"
    26  )
    27  
    28  func GetWarningsForService(service, oldService *api.Service) []string {
    29  	if service == nil {
    30  		return nil
    31  	}
    32  	var warnings []string
    33  
    34  	if _, ok := service.Annotations[api.DeprecatedAnnotationTopologyAwareHints]; ok {
    35  		warnings = append(warnings, fmt.Sprintf("annotation %s is deprecated, please use %s instead", api.DeprecatedAnnotationTopologyAwareHints, api.AnnotationTopologyMode))
    36  	}
    37  
    38  	if helper.IsServiceIPSet(service) {
    39  		for i, clusterIP := range service.Spec.ClusterIPs {
    40  			warnings = append(warnings, getWarningsForIP(field.NewPath("spec").Child("clusterIPs").Index(i), clusterIP)...)
    41  		}
    42  	}
    43  
    44  	for i, externalIP := range service.Spec.ExternalIPs {
    45  		warnings = append(warnings, getWarningsForIP(field.NewPath("spec").Child("externalIPs").Index(i), externalIP)...)
    46  	}
    47  
    48  	if len(service.Spec.LoadBalancerIP) > 0 {
    49  		warnings = append(warnings, getWarningsForIP(field.NewPath("spec").Child("loadBalancerIP"), service.Spec.LoadBalancerIP)...)
    50  	}
    51  
    52  	for i, cidr := range service.Spec.LoadBalancerSourceRanges {
    53  		warnings = append(warnings, getWarningsForCIDR(field.NewPath("spec").Child("loadBalancerSourceRanges").Index(i), cidr)...)
    54  	}
    55  
    56  	if service.Spec.Type == api.ServiceTypeExternalName && len(service.Spec.ExternalIPs) > 0 {
    57  		warnings = append(warnings, fmt.Sprintf("spec.externalIPs is ignored when spec.type is %q", api.ServiceTypeExternalName))
    58  	}
    59  	if service.Spec.Type != api.ServiceTypeExternalName && service.Spec.ExternalName != "" {
    60  		warnings = append(warnings, fmt.Sprintf("spec.externalName is ignored when spec.type is not %q", api.ServiceTypeExternalName))
    61  	}
    62  
    63  	return warnings
    64  }
    65  
    66  func getWarningsForIP(fieldPath *field.Path, address string) []string {
    67  	// IPv4 addresses with leading zeros CVE-2021-29923 are not valid in golang since 1.17
    68  	// This will also warn about possible future changes on the golang std library
    69  	// xref: https://issues.k8s.io/108074
    70  	ip, err := netip.ParseAddr(address)
    71  	if err != nil {
    72  		return []string{fmt.Sprintf("%s: IP address was accepted, but will be invalid in a future Kubernetes release: %v", fieldPath, err)}
    73  	}
    74  	// A Recommendation for IPv6 Address Text Representation
    75  	//
    76  	// "All of the above examples represent the same IPv6 address.  This
    77  	// flexibility has caused many problems for operators, systems
    78  	// engineers, and customers.
    79  	// ..."
    80  	// https://datatracker.ietf.org/doc/rfc5952/
    81  	if ip.Is6() && ip.String() != address {
    82  		return []string{fmt.Sprintf("%s: IPv6 address %q is not in RFC 5952 canonical format (%q), which may cause controller apply-loops", fieldPath, address, ip.String())}
    83  	}
    84  	return []string{}
    85  }
    86  
    87  func getWarningsForCIDR(fieldPath *field.Path, cidr string) []string {
    88  	// IPv4 addresses with leading zeros CVE-2021-29923 are not valid in golang since 1.17
    89  	// This will also warn about possible future changes on the golang std library
    90  	// xref: https://issues.k8s.io/108074
    91  	prefix, err := netip.ParsePrefix(cidr)
    92  	if err != nil {
    93  		return []string{fmt.Sprintf("%s: IP prefix was accepted, but will be invalid in a future Kubernetes release: %v", fieldPath, err)}
    94  	}
    95  	// A Recommendation for IPv6 Address Text Representation
    96  	//
    97  	// "All of the above examples represent the same IPv6 address.  This
    98  	// flexibility has caused many problems for operators, systems
    99  	// engineers, and customers.
   100  	// ..."
   101  	// https://datatracker.ietf.org/doc/rfc5952/
   102  	if prefix.Addr().Is6() && prefix.String() != cidr {
   103  		return []string{fmt.Sprintf("%s: IPv6 prefix %q is not in RFC 5952 canonical format (%q), which may cause controller apply-loops", fieldPath, cidr, prefix.String())}
   104  	}
   105  	return []string{}
   106  }