k8s.io/kubernetes@v1.29.3/pkg/api/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 api "k8s.io/kubernetes/pkg/apis/core" 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[api.AnnotationLoadBalancerSourceRangesKey] = v 32 svc := api.Service{} 33 svc.Annotations = annotations 34 _, err := GetLoadBalancerSourceRanges(&svc) 35 if err == nil { 36 t.Errorf("Expected error parsing: %q", v) 37 } 38 svc = api.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[api.AnnotationLoadBalancerSourceRangesKey] = v 56 svc := api.Service{} 57 svc.Annotations = annotations 58 _, err := GetLoadBalancerSourceRanges(&svc) 59 if err != nil { 60 t.Errorf("Unexpected error parsing: %q", v) 61 } 62 svc = api.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 := api.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[api.AnnotationLoadBalancerSourceRangesKey] = "" 101 svc = api.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 *api.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, &api.Service{}) 145 checkExternallyAccessible(false, &api.Service{ 146 Spec: api.ServiceSpec{ 147 Type: api.ServiceTypeClusterIP, 148 }, 149 }) 150 checkExternallyAccessible(true, &api.Service{ 151 Spec: api.ServiceSpec{ 152 Type: api.ServiceTypeClusterIP, 153 ExternalIPs: []string{"1.2.3.4"}, 154 }, 155 }) 156 checkExternallyAccessible(true, &api.Service{ 157 Spec: api.ServiceSpec{ 158 Type: api.ServiceTypeLoadBalancer, 159 }, 160 }) 161 checkExternallyAccessible(true, &api.Service{ 162 Spec: api.ServiceSpec{ 163 Type: api.ServiceTypeNodePort, 164 }, 165 }) 166 checkExternallyAccessible(false, &api.Service{ 167 Spec: api.ServiceSpec{ 168 Type: api.ServiceTypeExternalName, 169 }, 170 }) 171 checkExternallyAccessible(false, &api.Service{ 172 Spec: api.ServiceSpec{ 173 Type: api.ServiceTypeExternalName, 174 ExternalIPs: []string{"1.2.3.4"}, 175 }, 176 }) 177 } 178 179 func TestRequestsOnlyLocalTraffic(t *testing.T) { 180 checkRequestsOnlyLocalTraffic := func(requestsOnlyLocalTraffic bool, service *api.Service) { 181 t.Helper() 182 res := RequestsOnlyLocalTraffic(service) 183 if res != requestsOnlyLocalTraffic { 184 t.Errorf("Expected requests OnlyLocal traffic = %v, got %v", 185 requestsOnlyLocalTraffic, res) 186 } 187 } 188 189 checkRequestsOnlyLocalTraffic(false, &api.Service{}) 190 checkRequestsOnlyLocalTraffic(false, &api.Service{ 191 Spec: api.ServiceSpec{ 192 Type: api.ServiceTypeClusterIP, 193 }, 194 }) 195 checkRequestsOnlyLocalTraffic(false, &api.Service{ 196 Spec: api.ServiceSpec{ 197 Type: api.ServiceTypeNodePort, 198 }, 199 }) 200 checkRequestsOnlyLocalTraffic(false, &api.Service{ 201 Spec: api.ServiceSpec{ 202 Type: api.ServiceTypeNodePort, 203 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyCluster, 204 }, 205 }) 206 checkRequestsOnlyLocalTraffic(true, &api.Service{ 207 Spec: api.ServiceSpec{ 208 Type: api.ServiceTypeNodePort, 209 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyLocal, 210 }, 211 }) 212 checkRequestsOnlyLocalTraffic(false, &api.Service{ 213 Spec: api.ServiceSpec{ 214 Type: api.ServiceTypeLoadBalancer, 215 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyCluster, 216 }, 217 }) 218 checkRequestsOnlyLocalTraffic(true, &api.Service{ 219 Spec: api.ServiceSpec{ 220 Type: api.ServiceTypeLoadBalancer, 221 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyLocal, 222 }, 223 }) 224 } 225 226 func TestNeedsHealthCheck(t *testing.T) { 227 checkNeedsHealthCheck := func(needsHealthCheck bool, service *api.Service) { 228 t.Helper() 229 res := NeedsHealthCheck(service) 230 if res != needsHealthCheck { 231 t.Errorf("Expected needs health check = %v, got %v", 232 needsHealthCheck, res) 233 } 234 } 235 236 checkNeedsHealthCheck(false, &api.Service{ 237 Spec: api.ServiceSpec{ 238 Type: api.ServiceTypeClusterIP, 239 }, 240 }) 241 checkNeedsHealthCheck(false, &api.Service{ 242 Spec: api.ServiceSpec{ 243 Type: api.ServiceTypeNodePort, 244 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyCluster, 245 }, 246 }) 247 checkNeedsHealthCheck(false, &api.Service{ 248 Spec: api.ServiceSpec{ 249 Type: api.ServiceTypeNodePort, 250 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyLocal, 251 }, 252 }) 253 checkNeedsHealthCheck(false, &api.Service{ 254 Spec: api.ServiceSpec{ 255 Type: api.ServiceTypeLoadBalancer, 256 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyCluster, 257 }, 258 }) 259 checkNeedsHealthCheck(true, &api.Service{ 260 Spec: api.ServiceSpec{ 261 Type: api.ServiceTypeLoadBalancer, 262 ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyLocal, 263 }, 264 }) 265 }