k8s.io/kubernetes@v1.29.3/pkg/api/v1/service/util_test.go (about) 1 /* 2 Copyright 2016 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 "strings" 21 "testing" 22 23 v1 "k8s.io/api/core/v1" 24 utilnet "k8s.io/utils/net" 25 ) 26 27 func TestGetLoadBalancerSourceRanges(t *testing.T) { 28 checkError := func(v string) { 29 t.Helper() 30 annotations := make(map[string]string) 31 annotations[v1.AnnotationLoadBalancerSourceRangesKey] = v 32 svc := v1.Service{} 33 svc.Annotations = annotations 34 _, err := GetLoadBalancerSourceRanges(&svc) 35 if err == nil { 36 t.Errorf("Expected error parsing: %q", v) 37 } 38 svc = v1.Service{} 39 svc.Spec.LoadBalancerSourceRanges = strings.Split(v, ",") 40 _, err = GetLoadBalancerSourceRanges(&svc) 41 if err == nil { 42 t.Errorf("Expected error parsing: %q", v) 43 } 44 } 45 checkError("10.0.0.1/33") 46 checkError("foo.bar") 47 checkError("10.0.0.1/32,*") 48 checkError("10.0.0.1/32,") 49 checkError("10.0.0.1/32, ") 50 checkError("10.0.0.1") 51 52 checkOK := func(v string) utilnet.IPNetSet { 53 t.Helper() 54 annotations := make(map[string]string) 55 annotations[v1.AnnotationLoadBalancerSourceRangesKey] = v 56 svc := v1.Service{} 57 svc.Annotations = annotations 58 _, err := GetLoadBalancerSourceRanges(&svc) 59 if err != nil { 60 t.Errorf("Unexpected error parsing: %q", v) 61 } 62 svc = v1.Service{} 63 svc.Spec.LoadBalancerSourceRanges = strings.Split(v, ",") 64 cidrs, err := GetLoadBalancerSourceRanges(&svc) 65 if err != nil { 66 t.Errorf("Unexpected error parsing: %q", v) 67 } 68 return cidrs 69 } 70 cidrs := checkOK("192.168.0.1/32") 71 if len(cidrs) != 1 { 72 t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice()) 73 } 74 cidrs = checkOK("192.168.0.1/32,192.168.0.1/32") 75 if len(cidrs) != 1 { 76 t.Errorf("Expected exactly one CIDR (after de-dup): %v", cidrs.StringSlice()) 77 } 78 cidrs = checkOK("192.168.0.1/32,192.168.0.2/32") 79 if len(cidrs) != 2 { 80 t.Errorf("Expected two CIDRs: %v", cidrs.StringSlice()) 81 } 82 cidrs = checkOK(" 192.168.0.1/32 , 192.168.0.2/32 ") 83 if len(cidrs) != 2 { 84 t.Errorf("Expected two CIDRs: %v", cidrs.StringSlice()) 85 } 86 // check LoadBalancerSourceRanges not specified 87 svc := v1.Service{} 88 cidrs, err := GetLoadBalancerSourceRanges(&svc) 89 if err != nil { 90 t.Errorf("Unexpected error: %v", err) 91 } 92 if len(cidrs) != 1 { 93 t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice()) 94 } 95 if !IsAllowAll(cidrs) { 96 t.Errorf("Expected default to be allow-all: %v", cidrs.StringSlice()) 97 } 98 // check SourceRanges annotation is empty 99 annotations := make(map[string]string) 100 annotations[v1.AnnotationLoadBalancerSourceRangesKey] = "" 101 svc = v1.Service{} 102 svc.Annotations = annotations 103 cidrs, err = GetLoadBalancerSourceRanges(&svc) 104 if err != nil { 105 t.Errorf("Unexpected error: %v", err) 106 } 107 if len(cidrs) != 1 { 108 t.Errorf("Expected exactly one CIDR: %v", cidrs.StringSlice()) 109 } 110 if !IsAllowAll(cidrs) { 111 t.Errorf("Expected default to be allow-all: %v", cidrs.StringSlice()) 112 } 113 } 114 115 func TestAllowAll(t *testing.T) { 116 checkAllowAll := func(allowAll bool, cidrs ...string) { 117 t.Helper() 118 ipnets, err := utilnet.ParseIPNets(cidrs...) 119 if err != nil { 120 t.Errorf("Unexpected error parsing cidrs: %v", cidrs) 121 } 122 if allowAll != IsAllowAll(ipnets) { 123 t.Errorf("IsAllowAll did not return expected value for %v", cidrs) 124 } 125 } 126 checkAllowAll(false, "10.0.0.1/32") 127 checkAllowAll(false, "10.0.0.1/32", "10.0.0.2/32") 128 checkAllowAll(false, "10.0.0.1/32", "10.0.0.1/32") 129 130 checkAllowAll(true, "0.0.0.0/0") 131 checkAllowAll(true, "192.168.0.0/0") 132 checkAllowAll(true, "192.168.0.1/32", "0.0.0.0/0") 133 } 134 135 func TestExternallyAccessible(t *testing.T) { 136 checkExternallyAccessible := func(expect bool, service *v1.Service) { 137 t.Helper() 138 res := ExternallyAccessible(service) 139 if res != expect { 140 t.Errorf("Expected ExternallyAccessible = %v, got %v", expect, res) 141 } 142 } 143 144 checkExternallyAccessible(false, &v1.Service{}) 145 checkExternallyAccessible(false, &v1.Service{ 146 Spec: v1.ServiceSpec{ 147 Type: v1.ServiceTypeClusterIP, 148 }, 149 }) 150 checkExternallyAccessible(true, &v1.Service{ 151 Spec: v1.ServiceSpec{ 152 Type: v1.ServiceTypeClusterIP, 153 ExternalIPs: []string{"1.2.3.4"}, 154 }, 155 }) 156 checkExternallyAccessible(true, &v1.Service{ 157 Spec: v1.ServiceSpec{ 158 Type: v1.ServiceTypeLoadBalancer, 159 }, 160 }) 161 checkExternallyAccessible(true, &v1.Service{ 162 Spec: v1.ServiceSpec{ 163 Type: v1.ServiceTypeNodePort, 164 }, 165 }) 166 checkExternallyAccessible(false, &v1.Service{ 167 Spec: v1.ServiceSpec{ 168 Type: v1.ServiceTypeExternalName, 169 }, 170 }) 171 checkExternallyAccessible(false, &v1.Service{ 172 Spec: v1.ServiceSpec{ 173 Type: v1.ServiceTypeExternalName, 174 ExternalIPs: []string{"1.2.3.4"}, 175 }, 176 }) 177 } 178 179 func TestExternalPolicyLocal(t *testing.T) { 180 checkExternalPolicyLocal := func(requestsOnlyLocalTraffic bool, service *v1.Service) { 181 t.Helper() 182 res := ExternalPolicyLocal(service) 183 if res != requestsOnlyLocalTraffic { 184 t.Errorf("Expected requests OnlyLocal traffic = %v, got %v", 185 requestsOnlyLocalTraffic, res) 186 } 187 } 188 189 checkExternalPolicyLocal(false, &v1.Service{}) 190 checkExternalPolicyLocal(false, &v1.Service{ 191 Spec: v1.ServiceSpec{ 192 Type: v1.ServiceTypeClusterIP, 193 }, 194 }) 195 checkExternalPolicyLocal(false, &v1.Service{ 196 Spec: v1.ServiceSpec{ 197 Type: v1.ServiceTypeClusterIP, 198 ExternalIPs: []string{"1.2.3.4"}, 199 }, 200 }) 201 checkExternalPolicyLocal(false, &v1.Service{ 202 Spec: v1.ServiceSpec{ 203 Type: v1.ServiceTypeClusterIP, 204 ExternalIPs: []string{"1.2.3.4"}, 205 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyCluster, 206 }, 207 }) 208 checkExternalPolicyLocal(true, &v1.Service{ 209 Spec: v1.ServiceSpec{ 210 Type: v1.ServiceTypeClusterIP, 211 ExternalIPs: []string{"1.2.3.4"}, 212 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal, 213 }, 214 }) 215 checkExternalPolicyLocal(false, &v1.Service{ 216 Spec: v1.ServiceSpec{ 217 Type: v1.ServiceTypeNodePort, 218 }, 219 }) 220 checkExternalPolicyLocal(false, &v1.Service{ 221 Spec: v1.ServiceSpec{ 222 Type: v1.ServiceTypeNodePort, 223 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyCluster, 224 }, 225 }) 226 checkExternalPolicyLocal(true, &v1.Service{ 227 Spec: v1.ServiceSpec{ 228 Type: v1.ServiceTypeNodePort, 229 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal, 230 }, 231 }) 232 checkExternalPolicyLocal(false, &v1.Service{ 233 Spec: v1.ServiceSpec{ 234 Type: v1.ServiceTypeLoadBalancer, 235 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyCluster, 236 }, 237 }) 238 checkExternalPolicyLocal(true, &v1.Service{ 239 Spec: v1.ServiceSpec{ 240 Type: v1.ServiceTypeLoadBalancer, 241 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal, 242 }, 243 }) 244 } 245 246 func TestNeedsHealthCheck(t *testing.T) { 247 checkNeedsHealthCheck := func(needsHealthCheck bool, service *v1.Service) { 248 t.Helper() 249 res := NeedsHealthCheck(service) 250 if res != needsHealthCheck { 251 t.Errorf("Expected needs health check = %v, got %v", 252 needsHealthCheck, res) 253 } 254 } 255 256 checkNeedsHealthCheck(false, &v1.Service{ 257 Spec: v1.ServiceSpec{ 258 Type: v1.ServiceTypeClusterIP, 259 }, 260 }) 261 checkNeedsHealthCheck(false, &v1.Service{ 262 Spec: v1.ServiceSpec{ 263 Type: v1.ServiceTypeNodePort, 264 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyCluster, 265 }, 266 }) 267 checkNeedsHealthCheck(false, &v1.Service{ 268 Spec: v1.ServiceSpec{ 269 Type: v1.ServiceTypeNodePort, 270 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal, 271 }, 272 }) 273 checkNeedsHealthCheck(false, &v1.Service{ 274 Spec: v1.ServiceSpec{ 275 Type: v1.ServiceTypeLoadBalancer, 276 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyCluster, 277 }, 278 }) 279 checkNeedsHealthCheck(true, &v1.Service{ 280 Spec: v1.ServiceSpec{ 281 Type: v1.ServiceTypeLoadBalancer, 282 ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyLocal, 283 }, 284 }) 285 } 286 287 func TestInternalPolicyLocal(t *testing.T) { 288 checkInternalPolicyLocal := func(expected bool, service *v1.Service) { 289 t.Helper() 290 res := InternalPolicyLocal(service) 291 if res != expected { 292 t.Errorf("Expected internal local traffic = %v, got %v", 293 expected, res) 294 } 295 } 296 297 // default InternalTrafficPolicy is nil 298 checkInternalPolicyLocal(false, &v1.Service{}) 299 300 local := v1.ServiceInternalTrafficPolicyLocal 301 checkInternalPolicyLocal(true, &v1.Service{ 302 Spec: v1.ServiceSpec{ 303 InternalTrafficPolicy: &local, 304 }, 305 }) 306 307 cluster := v1.ServiceInternalTrafficPolicyCluster 308 checkInternalPolicyLocal(false, &v1.Service{ 309 Spec: v1.ServiceSpec{ 310 InternalTrafficPolicy: &cluster, 311 }, 312 }) 313 }