istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/accesslog_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 core 16 17 import ( 18 "testing" 19 20 accesslog "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v3" 21 core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 22 listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" 23 fileaccesslog "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/file/v3" 24 hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" 25 tcp "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3" 26 "github.com/envoyproxy/go-control-plane/pkg/conversion" 27 "github.com/google/go-cmp/cmp" 28 "google.golang.org/protobuf/testing/protocmp" 29 "google.golang.org/protobuf/types/known/wrapperspb" 30 31 meshconfig "istio.io/api/mesh/v1alpha1" 32 tpb "istio.io/api/telemetry/v1alpha1" 33 "istio.io/api/type/v1beta1" 34 "istio.io/istio/pilot/pkg/config/memory" 35 "istio.io/istio/pilot/pkg/model" 36 "istio.io/istio/pilot/pkg/networking" 37 "istio.io/istio/pilot/pkg/networking/util" 38 memregistry "istio.io/istio/pilot/pkg/serviceregistry/memory" 39 "istio.io/istio/pilot/pkg/util/protoconv" 40 "istio.io/istio/pilot/test/xdstest" 41 "istio.io/istio/pkg/config" 42 "istio.io/istio/pkg/config/mesh" 43 "istio.io/istio/pkg/config/protocol" 44 "istio.io/istio/pkg/config/schema/collections" 45 "istio.io/istio/pkg/config/schema/gvk" 46 "istio.io/istio/pkg/test/util/assert" 47 "istio.io/istio/pkg/util/protomarshal" 48 "istio.io/istio/pkg/wellknown" 49 ) 50 51 func TestListenerAccessLog(t *testing.T) { 52 defaultFormatJSON, _ := protomarshal.ToJSON(model.EnvoyJSONLogFormatIstio) 53 54 for _, tc := range []struct { 55 name string 56 encoding meshconfig.MeshConfig_AccessLogEncoding 57 format string 58 wantFormat string 59 }{ 60 { 61 name: "valid json object", 62 encoding: meshconfig.MeshConfig_JSON, 63 format: `{"foo": "bar"}`, 64 wantFormat: `{"foo":"bar"}`, 65 }, 66 { 67 name: "valid nested json object", 68 encoding: meshconfig.MeshConfig_JSON, 69 format: `{"foo": {"bar": "ha"}}`, 70 wantFormat: `{"foo":{"bar":"ha"}}`, 71 }, 72 { 73 name: "invalid json object", 74 encoding: meshconfig.MeshConfig_JSON, 75 format: `foo`, 76 wantFormat: defaultFormatJSON, 77 }, 78 { 79 name: "incorrect json type", 80 encoding: meshconfig.MeshConfig_JSON, 81 format: `[]`, 82 wantFormat: defaultFormatJSON, 83 }, 84 { 85 name: "incorrect json type", 86 encoding: meshconfig.MeshConfig_JSON, 87 format: `"{}"`, 88 wantFormat: defaultFormatJSON, 89 }, 90 { 91 name: "default json format", 92 encoding: meshconfig.MeshConfig_JSON, 93 wantFormat: defaultFormatJSON, 94 }, 95 { 96 name: "default text format", 97 encoding: meshconfig.MeshConfig_TEXT, 98 wantFormat: model.EnvoyTextLogFormat, 99 }, 100 } { 101 tc := tc 102 t.Run(tc.name, func(t *testing.T) { 103 accessLogBuilder.reset() 104 // Update MeshConfig 105 m := mesh.DefaultMeshConfig() 106 m.AccessLogFile = "foo" 107 m.AccessLogEncoding = tc.encoding 108 m.AccessLogFormat = tc.format 109 listeners := buildListeners(t, TestOptions{MeshConfig: m}, nil) 110 if len(listeners) != 2 { 111 t.Errorf("expected to have 2 listeners, but got %v", len(listeners)) 112 } 113 // Validate that access log filter uses the new format. 114 for _, l := range listeners { 115 if l.AccessLog[0].Filter == nil { 116 t.Fatal("expected filter config in listener access log configuration") 117 } 118 // Verify listener access log. 119 verify(t, tc.encoding, l.AccessLog[0], tc.wantFormat) 120 121 for _, fc := range l.FilterChains { 122 for _, filter := range fc.Filters { 123 switch filter.Name { 124 case wellknown.TCPProxy: 125 tcpConfig := &tcp.TcpProxy{} 126 if err := filter.GetTypedConfig().UnmarshalTo(tcpConfig); err != nil { 127 t.Fatal(err) 128 } 129 if tcpConfig.GetCluster() == util.BlackHoleCluster { 130 // Ignore the tcp_proxy filter with black hole cluster that just doesn't have access log. 131 continue 132 } 133 if len(tcpConfig.AccessLog) < 1 { 134 t.Fatalf("tcp_proxy want at least 1 access log, got 0") 135 } 136 137 for _, tcpAccessLog := range tcpConfig.AccessLog { 138 if tcpAccessLog.Filter != nil { 139 t.Fatalf("tcp_proxy filter chain's accesslog filter must be empty") 140 } 141 } 142 143 // Verify tcp proxy access log. 144 verify(t, tc.encoding, tcpConfig.AccessLog[0], tc.wantFormat) 145 case wellknown.HTTPConnectionManager: 146 httpConfig := &hcm.HttpConnectionManager{} 147 if err := filter.GetTypedConfig().UnmarshalTo(httpConfig); err != nil { 148 t.Fatal(err) 149 } 150 if len(httpConfig.AccessLog) < 1 { 151 t.Fatalf("http_connection_manager want at least 1 access log, got 0") 152 } 153 // Verify HTTP connection manager access log. 154 verify(t, tc.encoding, httpConfig.AccessLog[0], tc.wantFormat) 155 } 156 } 157 } 158 } 159 }) 160 } 161 } 162 163 func verify(t *testing.T, encoding meshconfig.MeshConfig_AccessLogEncoding, got *accesslog.AccessLog, wantFormat string) { 164 cfg, _ := conversion.MessageToStruct(got.GetTypedConfig()) 165 if encoding == meshconfig.MeshConfig_JSON { 166 jsonFormat := cfg.GetFields()["log_format"].GetStructValue().GetFields()["json_format"] 167 jsonFormatString, _ := protomarshal.ToJSON(jsonFormat) 168 if jsonFormatString != wantFormat { 169 t.Errorf("\nwant: %s\n got: %s", wantFormat, jsonFormatString) 170 } 171 } else { 172 textFormatString := cfg.GetFields()["log_format"].GetStructValue().GetFields()["text_format_source"].GetStructValue(). 173 GetFields()["inline_string"].GetStringValue() 174 if textFormatString != wantFormat { 175 t.Errorf("\nwant: %s\n got: %s", wantFormat, textFormatString) 176 } 177 } 178 } 179 180 func TestAccessLogPatch(t *testing.T) { 181 // Regression test for https://github.com/istio/istio/issues/35778 182 cg := NewConfigGenTest(t, TestOptions{ 183 Configs: nil, 184 ConfigPointers: nil, 185 ConfigString: ` 186 apiVersion: networking.istio.io/v1alpha3 187 kind: EnvoyFilter 188 metadata: 189 name: access-log-format 190 namespace: default 191 spec: 192 configPatches: 193 - applyTo: NETWORK_FILTER 194 match: 195 context: ANY 196 listener: 197 filterChain: 198 filter: 199 name: envoy.filters.network.tcp_proxy 200 patch: 201 operation: MERGE 202 value: 203 typed_config: 204 '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy 205 access_log: 206 - name: envoy.access_loggers.stream 207 typed_config: 208 '@type': type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog 209 log_format: 210 json_format: 211 envoyproxy_authority: '%REQ(:AUTHORITY)%' 212 `, 213 }) 214 215 proxy := cg.SetupProxy(nil) 216 l1 := cg.Listeners(proxy) 217 l2 := cg.Listeners(proxy) 218 // Make sure it doesn't change between patches 219 if d := cmp.Diff(l1, l2, protocmp.Transform()); d != "" { 220 t.Fatal(d) 221 } 222 // Make sure we have exactly 1 access log 223 fc := xdstest.ExtractFilterChain("virtualOutbound-blackhole", xdstest.ExtractListener("virtualOutbound", l1)) 224 if len(xdstest.ExtractTCPProxy(t, fc).GetAccessLog()) != 1 { 225 t.Fatalf("unexpected access log: %v", xdstest.ExtractTCPProxy(t, fc).GetAccessLog()) 226 } 227 } 228 229 func newTestEnviroment() *model.Environment { 230 serviceDiscovery := memregistry.NewServiceDiscovery(&model.Service{ 231 Hostname: "test.example.org", 232 DefaultAddress: "1.1.1.1", 233 Ports: model.PortList{ 234 &model.Port{ 235 Name: "default", 236 Port: 8080, 237 Protocol: protocol.HTTP, 238 }, 239 }, 240 }) 241 242 meshConfig := mesh.DefaultMeshConfig() 243 meshConfig.AccessLogFile = model.DevStdout 244 meshConfig.ExtensionProviders = append(meshConfig.ExtensionProviders, &meshconfig.MeshConfig_ExtensionProvider{ 245 Name: "envoy-json", 246 Provider: &meshconfig.MeshConfig_ExtensionProvider_EnvoyFileAccessLog{ 247 EnvoyFileAccessLog: &meshconfig.MeshConfig_ExtensionProvider_EnvoyFileAccessLogProvider{ 248 Path: model.DevStdout, 249 LogFormat: &meshconfig.MeshConfig_ExtensionProvider_EnvoyFileAccessLogProvider_LogFormat{ 250 LogFormat: &meshconfig.MeshConfig_ExtensionProvider_EnvoyFileAccessLogProvider_LogFormat_Labels{}, 251 }, 252 }, 253 }, 254 }) 255 256 configStore := memory.Make(collections.Pilot) 257 configStore.Create(config.Config{ 258 Meta: config.Meta{ 259 Name: "test", 260 Namespace: "default", 261 GroupVersionKind: gvk.Telemetry, 262 }, 263 Spec: &tpb.Telemetry{ 264 Selector: &v1beta1.WorkloadSelector{ 265 MatchLabels: map[string]string{ 266 "app": "test", 267 }, 268 }, 269 AccessLogging: []*tpb.AccessLogging{ 270 { 271 Providers: []*tpb.ProviderRef{ 272 { 273 Name: "envoy-json", 274 }, 275 }, 276 }, 277 }, 278 }, 279 }) 280 configStore.Create(config.Config{ 281 Meta: config.Meta{ 282 Name: "test-with-server-accesslog-filter", 283 Namespace: "default", 284 GroupVersionKind: gvk.Telemetry, 285 }, 286 Spec: &tpb.Telemetry{ 287 Selector: &v1beta1.WorkloadSelector{ 288 MatchLabels: map[string]string{ 289 "app": "test-with-server-accesslog-filter", 290 }, 291 }, 292 AccessLogging: []*tpb.AccessLogging{ 293 { 294 Match: &tpb.AccessLogging_LogSelector{ 295 Mode: tpb.WorkloadMode_SERVER, 296 }, 297 Providers: []*tpb.ProviderRef{ 298 { 299 Name: "envoy-json", 300 }, 301 }, 302 }, 303 }, 304 }, 305 }) 306 configStore.Create(config.Config{ 307 Meta: config.Meta{ 308 Name: "test-disable-accesslog", 309 Namespace: "default", 310 GroupVersionKind: gvk.Telemetry, 311 }, 312 Spec: &tpb.Telemetry{ 313 Selector: &v1beta1.WorkloadSelector{ 314 MatchLabels: map[string]string{ 315 "app": "test-disable-accesslog", 316 }, 317 }, 318 AccessLogging: []*tpb.AccessLogging{ 319 { 320 Providers: []*tpb.ProviderRef{ 321 { 322 Name: "envoy", 323 }, 324 }, 325 Disabled: wrapperspb.Bool(true), 326 }, 327 }, 328 }, 329 }) 330 331 env := model.NewEnvironment() 332 env.ServiceDiscovery = serviceDiscovery 333 env.ConfigStore = configStore 334 env.Watcher = mesh.NewFixedWatcher(meshConfig) 335 336 pushContext := model.NewPushContext() 337 env.Init() 338 pushContext.InitContext(env, nil, nil) 339 env.SetPushContext(pushContext) 340 341 return env 342 } 343 344 var ( 345 defaultJSONLabelsOut = &fileaccesslog.FileAccessLog{ 346 Path: model.DevStdout, 347 AccessLogFormat: &fileaccesslog.FileAccessLog_LogFormat{ 348 LogFormat: &core.SubstitutionFormatString{ 349 Format: &core.SubstitutionFormatString_JsonFormat{ 350 JsonFormat: model.EnvoyJSONLogFormatIstio, 351 }, 352 JsonFormatOptions: &core.JsonFormatOptions{SortProperties: true}, 353 }, 354 }, 355 } 356 357 defaultOut = &fileaccesslog.FileAccessLog{ 358 Path: model.DevStdout, 359 AccessLogFormat: &fileaccesslog.FileAccessLog_LogFormat{ 360 LogFormat: &core.SubstitutionFormatString{ 361 Format: &core.SubstitutionFormatString_TextFormatSource{ 362 TextFormatSource: &core.DataSource{ 363 Specifier: &core.DataSource_InlineString{ 364 InlineString: model.EnvoyTextLogFormat, 365 }, 366 }, 367 }, 368 }, 369 }, 370 } 371 ) 372 373 func TestSetTCPAccessLog(t *testing.T) { 374 b := newAccessLogBuilder() 375 376 env := newTestEnviroment() 377 378 cases := []struct { 379 name string 380 push *model.PushContext 381 proxy *model.Proxy 382 tcp *tcp.TcpProxy 383 class networking.ListenerClass 384 expected *tcp.TcpProxy 385 }{ 386 { 387 name: "telemetry", 388 push: env.PushContext(), 389 proxy: &model.Proxy{ 390 ConfigNamespace: "default", 391 Labels: map[string]string{"app": "test"}, 392 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test"}}, 393 }, 394 tcp: &tcp.TcpProxy{}, 395 class: networking.ListenerClassSidecarInbound, 396 expected: &tcp.TcpProxy{ 397 AccessLog: []*accesslog.AccessLog{ 398 { 399 Name: wellknown.FileAccessLog, 400 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultJSONLabelsOut)}, 401 }, 402 }, 403 }, 404 }, 405 { 406 name: "log-selector-unmatched-telemetry", 407 push: env.PushContext(), 408 proxy: &model.Proxy{ 409 ConfigNamespace: "default", 410 Labels: map[string]string{"app": "test-with-server-accesslog-filter"}, 411 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test-with-server-accesslog-filter"}}, 412 }, 413 tcp: &tcp.TcpProxy{}, 414 class: networking.ListenerClassSidecarOutbound, 415 expected: &tcp.TcpProxy{ 416 AccessLog: []*accesslog.AccessLog{ 417 { 418 Name: wellknown.FileAccessLog, 419 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultOut)}, 420 }, 421 }, 422 }, 423 }, 424 { 425 name: "without-telemetry", 426 push: env.PushContext(), 427 proxy: &model.Proxy{ 428 ConfigNamespace: "default", 429 Labels: map[string]string{"app": "without-telemetry"}, 430 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "without-telemetry"}}, 431 }, 432 tcp: &tcp.TcpProxy{}, 433 class: networking.ListenerClassSidecarInbound, 434 expected: &tcp.TcpProxy{ 435 AccessLog: []*accesslog.AccessLog{ 436 { 437 Name: wellknown.FileAccessLog, 438 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultOut)}, 439 }, 440 }, 441 }, 442 }, 443 { 444 name: "disable-accesslog", 445 push: env.PushContext(), 446 proxy: &model.Proxy{ 447 ConfigNamespace: "default", 448 Labels: map[string]string{"app": "test-disable-accesslog"}, 449 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test-disable-accesslog"}}, 450 }, 451 tcp: &tcp.TcpProxy{}, 452 class: networking.ListenerClassSidecarInbound, 453 expected: &tcp.TcpProxy{}, 454 }, 455 } 456 457 for _, tc := range cases { 458 t.Run(tc.name, func(t *testing.T) { 459 b.setTCPAccessLog(tc.push, tc.proxy, tc.tcp, tc.class, nil) 460 assert.Equal(t, tc.expected, tc.tcp) 461 }) 462 } 463 } 464 465 func TestSetHttpAccessLog(t *testing.T) { 466 b := newAccessLogBuilder() 467 468 env := newTestEnviroment() 469 470 cases := []struct { 471 name string 472 push *model.PushContext 473 proxy *model.Proxy 474 hcm *hcm.HttpConnectionManager 475 class networking.ListenerClass 476 expected *hcm.HttpConnectionManager 477 }{ 478 { 479 name: "telemetry", 480 push: env.PushContext(), 481 proxy: &model.Proxy{ 482 ConfigNamespace: "default", 483 Labels: map[string]string{"app": "test"}, 484 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test"}}, 485 }, 486 hcm: &hcm.HttpConnectionManager{}, 487 class: networking.ListenerClassSidecarInbound, 488 expected: &hcm.HttpConnectionManager{ 489 AccessLog: []*accesslog.AccessLog{ 490 { 491 Name: wellknown.FileAccessLog, 492 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultJSONLabelsOut)}, 493 }, 494 }, 495 }, 496 }, 497 { 498 name: "log-selector-unmatched-telemetry", 499 push: env.PushContext(), 500 proxy: &model.Proxy{ 501 ConfigNamespace: "default", 502 Labels: map[string]string{"app": "test-with-server-accesslog-filter"}, 503 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test-with-server-accesslog-filter"}}, 504 }, 505 hcm: &hcm.HttpConnectionManager{}, 506 class: networking.ListenerClassSidecarOutbound, 507 expected: &hcm.HttpConnectionManager{ 508 AccessLog: []*accesslog.AccessLog{ 509 { 510 Name: wellknown.FileAccessLog, 511 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultOut)}, 512 }, 513 }, 514 }, 515 }, 516 { 517 name: "without-telemetry", 518 push: env.PushContext(), 519 proxy: &model.Proxy{ 520 ConfigNamespace: "default", 521 Labels: map[string]string{"app": "without-telemetry"}, 522 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "without-telemetry"}}, 523 }, 524 hcm: &hcm.HttpConnectionManager{}, 525 class: networking.ListenerClassSidecarInbound, 526 expected: &hcm.HttpConnectionManager{ 527 AccessLog: []*accesslog.AccessLog{ 528 { 529 Name: wellknown.FileAccessLog, 530 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultOut)}, 531 }, 532 }, 533 }, 534 }, 535 { 536 name: "disable-accesslog", 537 push: env.PushContext(), 538 proxy: &model.Proxy{ 539 ConfigNamespace: "default", 540 Labels: map[string]string{"app": "test-disable-accesslog"}, 541 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test-disable-accesslog"}}, 542 }, 543 hcm: &hcm.HttpConnectionManager{}, 544 class: networking.ListenerClassSidecarInbound, 545 expected: &hcm.HttpConnectionManager{}, 546 }, 547 } 548 549 for _, tc := range cases { 550 t.Run(tc.name, func(t *testing.T) { 551 b.setHTTPAccessLog(tc.push, tc.proxy, tc.hcm, tc.class, nil) 552 assert.Equal(t, tc.expected, tc.hcm) 553 }) 554 } 555 } 556 557 func TestSetListenerAccessLog(t *testing.T) { 558 b := newAccessLogBuilder() 559 560 env := newTestEnviroment() 561 562 cases := []struct { 563 name string 564 push *model.PushContext 565 proxy *model.Proxy 566 listener *listener.Listener 567 class networking.ListenerClass 568 expected *listener.Listener 569 }{ 570 { 571 name: "telemetry", 572 push: env.PushContext(), 573 proxy: &model.Proxy{ 574 ConfigNamespace: "default", 575 Labels: map[string]string{"app": "test"}, 576 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test"}}, 577 }, 578 listener: &listener.Listener{}, 579 class: networking.ListenerClassSidecarInbound, 580 expected: &listener.Listener{ 581 AccessLog: []*accesslog.AccessLog{ 582 { 583 Name: wellknown.FileAccessLog, 584 Filter: &accesslog.AccessLogFilter{ 585 FilterSpecifier: &accesslog.AccessLogFilter_ResponseFlagFilter{ 586 ResponseFlagFilter: &accesslog.ResponseFlagFilter{Flags: []string{"NR"}}, 587 }, 588 }, 589 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultJSONLabelsOut)}, 590 }, 591 }, 592 }, 593 }, 594 { 595 name: "log-selector-unmatched-telemetry", 596 push: env.PushContext(), 597 proxy: &model.Proxy{ 598 ConfigNamespace: "default", 599 Labels: map[string]string{"app": "test-with-server-accesslog-filter"}, 600 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test-with-server-accesslog-filter"}}, 601 }, 602 listener: &listener.Listener{}, 603 class: networking.ListenerClassSidecarOutbound, 604 expected: &listener.Listener{ 605 AccessLog: []*accesslog.AccessLog{ 606 { 607 Name: wellknown.FileAccessLog, 608 Filter: &accesslog.AccessLogFilter{ 609 FilterSpecifier: &accesslog.AccessLogFilter_ResponseFlagFilter{ 610 ResponseFlagFilter: &accesslog.ResponseFlagFilter{Flags: []string{"NR"}}, 611 }, 612 }, 613 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultOut)}, 614 }, 615 }, 616 }, 617 }, 618 { 619 name: "without-telemetry", 620 push: env.PushContext(), 621 proxy: &model.Proxy{ 622 ConfigNamespace: "default", 623 Labels: map[string]string{"app": "without-telemetry"}, 624 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "without-telemetry"}}, 625 }, 626 listener: &listener.Listener{}, 627 class: networking.ListenerClassSidecarInbound, 628 expected: &listener.Listener{ 629 AccessLog: []*accesslog.AccessLog{ 630 { 631 Name: wellknown.FileAccessLog, 632 Filter: &accesslog.AccessLogFilter{ 633 FilterSpecifier: &accesslog.AccessLogFilter_ResponseFlagFilter{ 634 ResponseFlagFilter: &accesslog.ResponseFlagFilter{Flags: []string{"NR"}}, 635 }, 636 }, 637 ConfigType: &accesslog.AccessLog_TypedConfig{TypedConfig: protoconv.MessageToAny(defaultOut)}, 638 }, 639 }, 640 }, 641 }, 642 { 643 name: "disable-accesslog", 644 push: env.PushContext(), 645 proxy: &model.Proxy{ 646 ConfigNamespace: "default", 647 Labels: map[string]string{"app": "test-disable-accesslog"}, 648 Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "test-disable-accesslog"}}, 649 }, 650 listener: &listener.Listener{}, 651 class: networking.ListenerClassSidecarInbound, 652 expected: &listener.Listener{}, 653 }, 654 } 655 656 for _, tc := range cases { 657 t.Run(tc.name, func(t *testing.T) { 658 b.setListenerAccessLog(tc.push, tc.proxy, tc.listener, tc.class) 659 assert.Equal(t, tc.expected, tc.listener) 660 }) 661 } 662 }