istio.io/istio@v0.0.0-20240520182934-d79c90f27776/tests/integration/ambient/main_test.go (about) 1 //go:build integ 2 // +build integ 3 4 // Copyright Istio Authors 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package ambient 19 20 import ( 21 "context" 22 "strings" 23 "testing" 24 25 kerrors "k8s.io/apimachinery/pkg/api/errors" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 28 "istio.io/istio/pkg/config/constants" 29 "istio.io/istio/pkg/test/framework" 30 "istio.io/istio/pkg/test/framework/components/ambient" 31 "istio.io/istio/pkg/test/framework/components/echo" 32 cdeployment "istio.io/istio/pkg/test/framework/components/echo/common/deployment" 33 "istio.io/istio/pkg/test/framework/components/echo/common/ports" 34 "istio.io/istio/pkg/test/framework/components/echo/deployment" 35 "istio.io/istio/pkg/test/framework/components/echo/match" 36 "istio.io/istio/pkg/test/framework/components/istio" 37 "istio.io/istio/pkg/test/framework/components/namespace" 38 "istio.io/istio/pkg/test/framework/components/prometheus" 39 "istio.io/istio/pkg/test/framework/label" 40 "istio.io/istio/pkg/test/framework/resource" 41 "istio.io/istio/pkg/test/framework/resource/config/apply" 42 "istio.io/istio/pkg/test/scopes" 43 "istio.io/istio/tests/integration/security/util/cert" 44 ) 45 46 var ( 47 i istio.Instance 48 49 // Below are various preconfigured echo deployments. Whenever possible, tests should utilize these 50 // to avoid excessive creation/tear down of deployments. In general, a test should only deploy echo if 51 // its doing something unique to that specific test. 52 apps = &EchoDeployments{} 53 54 // used to validate telemetry in-cluster 55 prom prometheus.Instance 56 ) 57 58 type EchoDeployments struct { 59 // Namespace echo apps will be deployed 60 Namespace namespace.Instance 61 ExternalNamespace namespace.Instance 62 63 // AllWaypoint is a waypoint for all types 64 AllWaypoint echo.Instances 65 // WorkloadAddressedWaypoint is a workload only waypoint 66 WorkloadAddressedWaypoint echo.Instances 67 // ServiceAddressedWaypoint is a serviceonly waypoint 68 ServiceAddressedWaypoint echo.Instances 69 // Captured echo service 70 Captured echo.Instances 71 // Uncaptured echo Service 72 Uncaptured echo.Instances 73 // SidecarWaypoint is a sidecar with a waypoint 74 SidecarWaypoint echo.Instances 75 // SidecarCaptured echo services with sidecar and ambient capture 76 SidecarCaptured echo.Instances 77 // SidecarUncaptured echo services with sidecar and no ambient capture 78 SidecarUncaptured echo.Instances 79 80 // All echo services 81 All echo.Instances 82 // Echo services that are in the mesh 83 Mesh echo.Instances 84 // Echo services that are not in mesh 85 MeshExternal echo.Instances 86 87 MockExternal echo.Instances 88 89 // WaypointProxies by 90 WaypointProxies map[string]ambient.WaypointProxy 91 } 92 93 // TestMain defines the entrypoint for pilot tests using a standard Istio installation. 94 // If a test requires a custom install it should go into its own package, otherwise it should go 95 // here to reuse a single install across tests. 96 func TestMain(m *testing.M) { 97 // nolint: staticcheck 98 framework. 99 NewSuite(m). 100 RequireMinVersion(24). 101 Label(label.IPv4). // https://github.com/istio/istio/issues/41008 102 Setup(func(t resource.Context) error { 103 t.Settings().Ambient = true 104 return nil 105 }). 106 Setup(istio.Setup(&i, func(ctx resource.Context, cfg *istio.Config) { 107 // can't deploy VMs without eastwest gateway 108 ctx.Settings().SkipVMs() 109 cfg.EnableCNI = true 110 cfg.DeployEastWestGW = false 111 cfg.ControlPlaneValues = ` 112 values: 113 cni: 114 # The CNI repair feature is disabled for these tests because this is a controlled environment, 115 # and it is important to catch issues that might otherwise be automatically fixed. 116 # Refer to issue #49207 for more context. 117 repair: 118 enabled: false 119 ztunnel: 120 terminationGracePeriodSeconds: 5 121 env: 122 SECRET_TTL: 5m 123 ` 124 }, cert.CreateCASecretAlt)). 125 Setup(func(t resource.Context) error { 126 gatewayConformanceInputs.Client = t.Clusters().Default() 127 gatewayConformanceInputs.Cleanup = !t.Settings().NoCleanup 128 129 return nil 130 }). 131 Setup(func(t resource.Context) error { 132 return SetupApps(t, i, apps) 133 }). 134 Run() 135 } 136 137 const ( 138 WorkloadAddressedWaypoint = "workload-addressed-waypoint" 139 ServiceAddressedWaypoint = "service-addressed-waypoint" 140 Captured = "captured" 141 Uncaptured = "uncaptured" 142 SidecarWaypoint = "sidecar-waypoint" 143 SidecarCaptured = "sidecar-captured" 144 SidecarUncaptured = "sidecar-uncaptured" 145 ) 146 147 var inMesh = match.Matcher(func(instance echo.Instance) bool { 148 names := []string{"waypoint", "captured", "sidecar"} 149 for _, name := range names { 150 if strings.Contains(instance.Config().Service, name) { 151 return true 152 } 153 } 154 return false 155 }) 156 157 func SetupApps(t resource.Context, i istio.Instance, apps *EchoDeployments) error { 158 var err error 159 apps.Namespace, err = namespace.New(t, namespace.Config{ 160 Prefix: "echo", 161 Inject: false, 162 Labels: map[string]string{ 163 constants.DataplaneModeLabel: "ambient", 164 }, 165 }) 166 if err != nil { 167 return err 168 } 169 apps.ExternalNamespace, err = namespace.New(t, namespace.Config{ 170 Prefix: "external", 171 Inject: false, 172 }) 173 if err != nil { 174 return err 175 } 176 177 prom, err = prometheus.New(t, prometheus.Config{}) 178 if err != nil { 179 return err 180 } 181 182 // Headless services don't work with targetPort, set to same port 183 headlessPorts := make([]echo.Port, len(ports.All())) 184 for i, p := range ports.All() { 185 p.ServicePort = p.WorkloadPort 186 headlessPorts[i] = p 187 } 188 builder := deployment.New(t). 189 WithClusters(t.Clusters()...). 190 WithConfig(echo.Config{ 191 Service: WorkloadAddressedWaypoint, 192 Namespace: apps.Namespace, 193 Ports: ports.All(), 194 ServiceAccount: true, 195 WorkloadWaypointProxy: "waypoint", 196 Subsets: []echo.SubsetConfig{ 197 { 198 Replicas: 1, 199 Version: "v1", 200 Labels: map[string]string{ 201 "app": WorkloadAddressedWaypoint, 202 "version": "v1", 203 constants.AmbientUseWaypointLabel: "waypoint", 204 }, 205 }, 206 { 207 Replicas: 1, 208 Version: "v2", 209 Labels: map[string]string{ 210 "app": WorkloadAddressedWaypoint, 211 "version": "v2", 212 constants.AmbientUseWaypointLabel: "waypoint", 213 }, 214 }, 215 }, 216 }). 217 WithConfig(echo.Config{ 218 Service: ServiceAddressedWaypoint, 219 Namespace: apps.Namespace, 220 Ports: ports.All(), 221 ServiceLabels: map[string]string{constants.AmbientUseWaypointLabel: "waypoint"}, 222 ServiceAccount: true, 223 ServiceWaypointProxy: "waypoint", 224 Subsets: []echo.SubsetConfig{ 225 { 226 Replicas: 1, 227 Version: "v1", 228 Labels: map[string]string{ 229 "app": ServiceAddressedWaypoint, 230 "version": "v1", 231 }, 232 }, 233 { 234 Replicas: 1, 235 Version: "v2", 236 Labels: map[string]string{ 237 "app": ServiceAddressedWaypoint, 238 "version": "v2", 239 }, 240 }, 241 }, 242 }). 243 WithConfig(echo.Config{ 244 Service: Captured, 245 Namespace: apps.Namespace, 246 Ports: ports.All(), 247 ServiceAccount: true, 248 Subsets: []echo.SubsetConfig{ 249 { 250 Replicas: 1, 251 Version: "v1", 252 }, 253 { 254 Replicas: 1, 255 Version: "v2", 256 }, 257 }, 258 }). 259 WithConfig(echo.Config{ 260 Service: Uncaptured, 261 Namespace: apps.Namespace, 262 Ports: ports.All(), 263 ServiceAccount: true, 264 Subsets: []echo.SubsetConfig{ 265 { 266 Replicas: 1, 267 Version: "v1", 268 Labels: map[string]string{constants.DataplaneModeLabel: constants.DataplaneModeNone}, 269 }, 270 { 271 Replicas: 1, 272 Version: "v2", 273 Labels: map[string]string{constants.DataplaneModeLabel: constants.DataplaneModeNone}, 274 }, 275 }, 276 }) 277 278 _, whErr := t.Clusters().Default(). 279 Kube().AdmissionregistrationV1().MutatingWebhookConfigurations(). 280 Get(context.Background(), "istio-sidecar-injector", metav1.GetOptions{}) 281 if whErr != nil && !kerrors.IsNotFound(whErr) { 282 return whErr 283 } 284 // Only setup sidecar tests if webhook is installed 285 if whErr == nil { 286 // TODO(https://github.com/istio/istio/issues/43244) support sidecars that are captured 287 //builder = builder.WithConfig(echo.Config{ 288 // Service: SidecarWaypoint, 289 // Namespace: apps.Namespace, 290 // Ports: ports.All(), 291 // Subsets: []echo.SubsetConfig{ 292 // { 293 // Replicas: 1, 294 // Version: "v1", 295 // Labels: map[string]string{ 296 // "ambient-type": "workload", 297 // "sidecar.istio.io/inject": "true", 298 // }, 299 // }, 300 // { 301 // Replicas: 1, 302 // Version: "v2", 303 // Labels: map[string]string{ 304 // "ambient-type": "workload", 305 // "sidecar.istio.io/inject": "true", 306 // }, 307 // }, 308 // }, 309 //}) 310 // builder = builder.WithConfig(echo.Config{ 311 // Service: SidecarCaptured, 312 // Namespace: apps.Namespace, 313 // Ports: ports.All(), 314 // Subsets: []echo.SubsetConfig{ 315 // { 316 // Replicas: 1, 317 // Version: "v1", 318 // Labels: map[string]string{ 319 // "ambient-type": "workload", 320 // "sidecar.istio.io/inject": "true", 321 // }, 322 // }, 323 // { 324 // Replicas: 1, 325 // Version: "v2", 326 // Labels: map[string]string{ 327 // "ambient-type": "workload", 328 // "sidecar.istio.io/inject": "true", 329 // }, 330 // }, 331 // }, 332 // }) 333 builder = builder.WithConfig(echo.Config{ 334 Service: SidecarUncaptured, 335 Namespace: apps.Namespace, 336 Ports: ports.All(), 337 ServiceAccount: true, 338 Subsets: []echo.SubsetConfig{ 339 { 340 Replicas: 1, 341 Version: "v1", 342 Labels: map[string]string{ 343 "sidecar.istio.io/inject": "true", 344 constants.DataplaneModeLabel: constants.DataplaneModeNone, 345 }, 346 }, 347 { 348 Replicas: 1, 349 Version: "v2", 350 Labels: map[string]string{ 351 "sidecar.istio.io/inject": "true", 352 constants.DataplaneModeLabel: constants.DataplaneModeNone, 353 }, 354 }, 355 }, 356 }) 357 } 358 359 external := cdeployment.External{Namespace: apps.ExternalNamespace} 360 external.Build(t, builder) 361 362 echos, err := builder.Build() 363 if err != nil { 364 return err 365 } 366 for _, b := range echos { 367 scopes.Framework.Infof("built %v", b.Config().Service) 368 } 369 370 external.LoadValues(echos) 371 apps.MockExternal = external.All 372 373 // All does not include external 374 echos = match.Not(match.ServiceName(echo.NamespacedName{Name: cdeployment.ExternalSvc, Namespace: apps.ExternalNamespace})).GetMatches(echos) 375 apps.MockExternal = external.All 376 apps.All = echos 377 apps.WorkloadAddressedWaypoint = match.ServiceName(echo.NamespacedName{Name: WorkloadAddressedWaypoint, Namespace: apps.Namespace}).GetMatches(echos) 378 apps.ServiceAddressedWaypoint = match.ServiceName(echo.NamespacedName{Name: ServiceAddressedWaypoint, Namespace: apps.Namespace}).GetMatches(echos) 379 apps.AllWaypoint = apps.AllWaypoint.Append(apps.WorkloadAddressedWaypoint) 380 apps.AllWaypoint = apps.AllWaypoint.Append(apps.ServiceAddressedWaypoint) 381 apps.Uncaptured = match.ServiceName(echo.NamespacedName{Name: Uncaptured, Namespace: apps.Namespace}).GetMatches(echos) 382 apps.Captured = match.ServiceName(echo.NamespacedName{Name: Captured, Namespace: apps.Namespace}).GetMatches(echos) 383 apps.SidecarWaypoint = match.ServiceName(echo.NamespacedName{Name: SidecarWaypoint, Namespace: apps.Namespace}).GetMatches(echos) 384 apps.SidecarUncaptured = match.ServiceName(echo.NamespacedName{Name: SidecarUncaptured, Namespace: apps.Namespace}).GetMatches(echos) 385 apps.SidecarCaptured = match.ServiceName(echo.NamespacedName{Name: SidecarCaptured, Namespace: apps.Namespace}).GetMatches(echos) 386 apps.Mesh = inMesh.GetMatches(echos) 387 apps.MeshExternal = match.Not(inMesh).GetMatches(echos) 388 389 // TODO(https://github.com/istio/istio/issues/51083) remove manually allocate 390 if err := cdeployment.DeployExternalServiceEntry(t.ConfigIstio(), apps.Namespace, apps.ExternalNamespace, true). 391 Apply(apply.CleanupConditionally); err != nil { 392 return err 393 } 394 395 if apps.WaypointProxies == nil { 396 apps.WaypointProxies = make(map[string]ambient.WaypointProxy) 397 } 398 399 for _, echo := range echos { 400 svcwp := echo.Config().ServiceWaypointProxy 401 wlwp := echo.Config().WorkloadWaypointProxy 402 if svcwp != "" { 403 if _, found := apps.WaypointProxies[svcwp]; !found { 404 apps.WaypointProxies[svcwp], err = ambient.NewWaypointProxy(t, apps.Namespace, svcwp) 405 if err != nil { 406 return err 407 } 408 } 409 } 410 if wlwp != "" { 411 if _, found := apps.WaypointProxies[wlwp]; !found { 412 apps.WaypointProxies[wlwp], err = ambient.NewWaypointProxy(t, apps.Namespace, wlwp) 413 if err != nil { 414 return err 415 } 416 } 417 } 418 419 } 420 421 return nil 422 }