istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/model/policyattachment_test.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package model 16 17 import ( 18 "testing" 19 20 "k8s.io/apimachinery/pkg/types" 21 22 "istio.io/api/type/v1beta1" 23 "istio.io/istio/pilot/pkg/features" 24 "istio.io/istio/pkg/config" 25 "istio.io/istio/pkg/config/constants" 26 "istio.io/istio/pkg/config/labels" 27 "istio.io/istio/pkg/config/schema/gvk" 28 "istio.io/istio/pkg/test" 29 ) 30 31 func TestPolicyMatcher(t *testing.T) { 32 sampleTargetRef := &v1beta1.PolicyTargetReference{ 33 Group: gvk.KubernetesGateway.Group, 34 Kind: gvk.KubernetesGateway.Kind, 35 Name: "sample-gateway", 36 } 37 waypointTargetRef := &v1beta1.PolicyTargetReference{ 38 Group: gvk.KubernetesGateway.Group, 39 Kind: gvk.KubernetesGateway.Kind, 40 Name: "sample-waypoint", 41 } 42 serviceTargetRef := &v1beta1.PolicyTargetReference{ 43 Group: gvk.Service.Group, 44 Kind: gvk.Service.Kind, 45 Name: "sample-svc", 46 } 47 sampleSelector := &v1beta1.WorkloadSelector{ 48 MatchLabels: labels.Instance{ 49 "app": "my-app", 50 }, 51 } 52 sampleGatewaySelector := &v1beta1.WorkloadSelector{ 53 MatchLabels: labels.Instance{ 54 constants.GatewayNameLabel: "sample-gateway", 55 }, 56 } 57 sampleWaypointSelector := &v1beta1.WorkloadSelector{ 58 MatchLabels: labels.Instance{ 59 constants.GatewayNameLabel: "sample-waypoint", 60 }, 61 } 62 regularApp := WorkloadPolicyMatcher{ 63 Namespace: "default", 64 WorkloadLabels: labels.Instance{ 65 "app": "my-app", 66 }, 67 IsWaypoint: false, 68 } 69 sampleGateway := WorkloadPolicyMatcher{ 70 Namespace: "default", 71 WorkloadLabels: labels.Instance{ 72 constants.GatewayNameLabel: "sample-gateway", 73 }, 74 IsWaypoint: false, 75 } 76 sampleWaypoint := WorkloadPolicyMatcher{ 77 Namespace: "default", 78 WorkloadLabels: labels.Instance{ 79 constants.GatewayNameLabel: "sample-waypoint", 80 }, 81 IsWaypoint: true, 82 } 83 serviceTarget := WorkloadPolicyMatcher{ 84 Namespace: "default", 85 WorkloadLabels: labels.Instance{ 86 "app": "my-app", 87 constants.GatewayNameLabel: "sample-waypoint", 88 }, 89 IsWaypoint: true, 90 Service: "sample-svc", 91 } 92 tests := []struct { 93 name string 94 selection WorkloadPolicyMatcher 95 policy TargetablePolicy 96 enableSelectorPolicies bool 97 98 expected bool 99 }{ 100 { 101 name: "non-gateway API workload and a targetRef", 102 selection: regularApp, 103 policy: &mockPolicyTargetGetter{ 104 targetRef: sampleTargetRef, 105 }, 106 expected: false, 107 enableSelectorPolicies: true, 108 }, 109 { 110 name: "non-gateway API workload and a selector", 111 selection: regularApp, 112 policy: &mockPolicyTargetGetter{ 113 selector: sampleSelector, 114 }, 115 expected: true, 116 enableSelectorPolicies: true, 117 }, 118 { 119 name: "non-gateway API workload and both a targetRef and a selector", 120 selection: regularApp, 121 policy: &mockPolicyTargetGetter{ 122 selector: sampleSelector, 123 targetRef: sampleTargetRef, 124 }, 125 expected: false, 126 enableSelectorPolicies: true, 127 }, 128 { 129 name: "non-gateway API workload and no targetRef or selector", 130 policy: &mockPolicyTargetGetter{}, 131 selection: regularApp, 132 expected: true, 133 enableSelectorPolicies: true, 134 }, 135 { 136 name: "gateway API ingress and a targetRef", 137 policy: &mockPolicyTargetGetter{ 138 targetRef: sampleTargetRef, 139 }, 140 selection: sampleGateway, 141 expected: true, 142 }, 143 { 144 name: "gateway API ingress and a selector", 145 policy: &mockPolicyTargetGetter{ 146 selector: sampleGatewaySelector, 147 }, 148 selection: sampleGateway, 149 expected: true, 150 enableSelectorPolicies: true, 151 }, 152 { 153 name: "gateway API ingress and a selector (policy attachment only)", 154 policy: &mockPolicyTargetGetter{ 155 selector: sampleGatewaySelector, 156 }, 157 selection: sampleGateway, 158 expected: false, 159 enableSelectorPolicies: false, 160 }, 161 { 162 name: "gateway API ingress and both a targetRef and a selector", 163 policy: &mockPolicyTargetGetter{ 164 targetRef: sampleTargetRef, 165 selector: sampleGatewaySelector, 166 }, 167 selection: sampleGateway, 168 expected: true, 169 }, 170 { 171 name: "gateway API ingress and non-matching targetRef", 172 policy: &mockPolicyTargetGetter{ 173 targetRef: waypointTargetRef, 174 }, 175 selection: sampleGateway, 176 expected: false, 177 enableSelectorPolicies: true, 178 }, 179 { 180 name: "gateway API ingress and no targetRef or selector", 181 selection: sampleGateway, 182 policy: &mockPolicyTargetGetter{}, 183 expected: true, 184 enableSelectorPolicies: true, 185 }, 186 { 187 name: "waypoint and a targetRef", 188 policy: &mockPolicyTargetGetter{ 189 targetRef: waypointTargetRef, 190 }, 191 selection: sampleWaypoint, 192 expected: true, 193 enableSelectorPolicies: true, 194 }, 195 { 196 name: "waypoint and a selector", 197 policy: &mockPolicyTargetGetter{ 198 selector: sampleWaypointSelector, 199 }, 200 selection: sampleWaypoint, 201 expected: false, 202 enableSelectorPolicies: true, 203 }, 204 { 205 name: "waypoint and both a targetRef and a selector", 206 policy: &mockPolicyTargetGetter{ 207 targetRef: waypointTargetRef, 208 selector: sampleWaypointSelector, 209 }, 210 selection: sampleWaypoint, 211 expected: true, 212 enableSelectorPolicies: true, 213 }, 214 { 215 name: "waypoint and no targetRef or selector", 216 selection: sampleWaypoint, 217 policy: &mockPolicyTargetGetter{}, 218 expected: false, 219 enableSelectorPolicies: true, 220 }, 221 { 222 name: "waypoint and non-matching targetRef", 223 selection: sampleWaypoint, 224 policy: &mockPolicyTargetGetter{ 225 targetRef: sampleTargetRef, 226 }, 227 expected: false, 228 enableSelectorPolicies: true, 229 }, 230 { 231 name: "waypoint and matching targetRefs", 232 selection: sampleWaypoint, 233 policy: &mockPolicyTargetGetter{ 234 targetRefs: []*v1beta1.PolicyTargetReference{waypointTargetRef}, 235 }, 236 expected: true, 237 enableSelectorPolicies: true, 238 }, 239 { 240 name: "waypoint and partial matching targetRefs", 241 selection: sampleWaypoint, 242 policy: &mockPolicyTargetGetter{ 243 targetRefs: []*v1beta1.PolicyTargetReference{waypointTargetRef, sampleTargetRef}, 244 }, 245 expected: true, 246 enableSelectorPolicies: true, 247 }, 248 { 249 name: "waypoint and non matching targetRefs", 250 selection: sampleWaypoint, 251 policy: &mockPolicyTargetGetter{ 252 targetRefs: []*v1beta1.PolicyTargetReference{sampleTargetRef}, 253 }, 254 expected: false, 255 enableSelectorPolicies: true, 256 }, 257 { 258 name: "service attached policy", 259 selection: serviceTarget, 260 policy: &mockPolicyTargetGetter{ 261 targetRefs: []*v1beta1.PolicyTargetReference{serviceTargetRef}, 262 }, 263 enableSelectorPolicies: false, 264 expected: true, 265 }, 266 } 267 268 for _, tt := range tests { 269 t.Run(tt.name, func(t *testing.T) { 270 test.SetForTest(t, &features.EnableSelectorBasedK8sGatewayPolicy, tt.enableSelectorPolicies) 271 nsName := types.NamespacedName{Name: "policy1", Namespace: "default"} 272 matcher := tt.selection.ShouldAttachPolicy(mockKind, nsName, tt.policy) 273 274 if matcher != tt.expected { 275 t.Errorf("Expected %v, but got %v", tt.expected, matcher) 276 } 277 }) 278 } 279 } 280 281 type mockPolicyTargetGetter struct { 282 targetRef *v1beta1.PolicyTargetReference 283 targetRefs []*v1beta1.PolicyTargetReference 284 selector *v1beta1.WorkloadSelector 285 } 286 287 func (m *mockPolicyTargetGetter) GetTargetRef() *v1beta1.PolicyTargetReference { 288 return m.targetRef 289 } 290 291 func (m *mockPolicyTargetGetter) GetTargetRefs() []*v1beta1.PolicyTargetReference { 292 return m.targetRefs 293 } 294 295 func (m *mockPolicyTargetGetter) GetSelector() *v1beta1.WorkloadSelector { 296 return m.selector 297 } 298 299 var mockKind = config.GroupVersionKind{ 300 Group: "mock.istio.io", 301 Version: "v1", 302 Kind: "MockKind", 303 }