@@ -46,6 +46,7 @@ import (
4646 "istio.io/istio/pkg/config"
4747 "istio.io/istio/pkg/config/constants"
4848 "istio.io/istio/pkg/config/mesh"
49+ "istio.io/istio/pkg/config/mesh/meshwatcher"
4950 "istio.io/istio/pkg/config/schema/gvk"
5051 "istio.io/istio/pkg/config/schema/gvr"
5152 "istio.io/istio/pkg/kube"
@@ -574,7 +575,7 @@ metadata:
574575 kclient.NewWriteClient [* k8sbeta.Gateway ](client ).Create (tt .gw .DeepCopy ())
575576 kclient.NewWriteClient [* appsv1.Deployment ](client ).Create (upgradeDeployment )
576577 stop := test .NewStop (t )
577- env := model . NewEnvironment ()
578+ env := newTestEnv ()
578579 env .PushContext ().ProxyConfigs = tt .pcs
579580 tw := revisions .NewTagWatcher (client , "" )
580581 go tw .Run (stop )
@@ -612,6 +613,79 @@ metadata:
612613 }
613614}
614615
616+ func TestMeshGatewayReconciliation (t * testing.T ) {
617+ c := kube .NewFakeClient (& corev1.Namespace {
618+ ObjectMeta : metav1.ObjectMeta {
619+ Name : "default" ,
620+ },
621+ })
622+ tw := revisions .NewTagWatcher (c , "default" )
623+
624+ // not using the new helper becase
625+ // we need to explicitly modify this
626+ // later in the thread
627+ env := model .NewEnvironment ()
628+ m := mesh .DefaultMeshConfig ()
629+ watch := meshwatcher .NewTestWatcher (m )
630+ env .Watcher = watch
631+ d := NewDeploymentController (c , "" , env , testInjectionConfig (t , "" ), func (fn func ()) {}, tw , "" , "" )
632+
633+ reconciles := atomic .NewInt32 (0 )
634+ wantReconcile := int32 (0 )
635+ expectReconciled := func () {
636+ t .Helper ()
637+ wantReconcile ++
638+ assert .EventuallyEqual (t , reconciles .Load , wantReconcile , retry .Timeout (time .Second * 5 ), retry .Message ("no reconciliation" ))
639+ }
640+
641+ writes := make (chan string , 2 )
642+ d .patcher = func (g schema.GroupVersionResource , name string , namespace string , data []byte , subresources ... string ) error {
643+ if g == gvr .Service {
644+ reconciles .Inc ()
645+ }
646+ if g == gvr .KubernetesGateway {
647+ b , err := yaml .JSONToYAML (data )
648+ if err != nil {
649+ return err
650+ }
651+ writes <- string (b )
652+ }
653+ return nil
654+ }
655+
656+ stop := test .NewStop (t )
657+ gws := clienttest .Wrap (t , d .gateways )
658+ go tw .Run (stop )
659+ go d .Run (stop )
660+ c .RunAndWait (stop )
661+ kube .WaitForCacheSync ("test" , stop , d .queue .HasSynced )
662+
663+ // create the initial gateway for the deployment controller
664+ // to reconcile when the meshconfig changes
665+ defaultGateway := & k8sbeta.Gateway {
666+ ObjectMeta : metav1.ObjectMeta {
667+ Name : "gw" ,
668+ Namespace : "default" ,
669+ },
670+ Spec : k8s.GatewaySpec {
671+ GatewayClassName : k8s .ObjectName (features .GatewayAPIDefaultGatewayClass ),
672+ },
673+ }
674+ gws .Create (defaultGateway )
675+ assert .Equal (t , assert .ChannelHasItem (t , writes ), buildPatch ())
676+ expectReconciled ()
677+ assert .ChannelIsEmpty (t , writes )
678+
679+ // modify the meshconfig to trigger a reprocess of the gateways
680+ m .DefaultConfig .Image = & istioio_networking_v1beta1.ProxyImage {ImageType : "distroless" }
681+ watch .Set (m )
682+
683+ // confirm the gateway is reconciled
684+ assert .ChannelHasItem (t , writes )
685+ expectReconciled ()
686+ assert .ChannelIsEmpty (t , writes )
687+ }
688+
615689func buildFilter (allowedNamespace string ) kubetypes.DynamicObjectFilter {
616690 return kubetypes .NewStaticObjectFilter (func (obj any ) bool {
617691 if ns , ok := obj .(string ); ok {
@@ -638,7 +712,7 @@ func TestVersionManagement(t *testing.T) {
638712 },
639713 })
640714 tw := revisions .NewTagWatcher (c , "default" )
641- env := & model. Environment {}
715+ env := newTestEnv ()
642716 d := NewDeploymentController (c , "" , env , testInjectionConfig (t , "" ), func (fn func ()) {}, tw , "" , "" )
643717 reconciles := atomic .NewInt32 (0 )
644718 wantReconcile := int32 (0 )
@@ -678,7 +752,7 @@ func TestVersionManagement(t *testing.T) {
678752 },
679753 }
680754 gws .Create (defaultGateway )
681- assert .Equal (t , assert .ChannelHasItem (t , writes ), buildPatch (ControllerVersion ))
755+ assert .Equal (t , assert .ChannelHasItem (t , writes ), buildPatch ())
682756 expectReconciled ()
683757 assert .ChannelIsEmpty (t , writes )
684758 // Test fake doesn't actual do Apply, so manually do this
@@ -699,7 +773,7 @@ func TestVersionManagement(t *testing.T) {
699773 defaultGateway .Annotations = map [string ]string {}
700774 gws .Update (defaultGateway )
701775 expectReconciled ()
702- assert .Equal (t , assert .ChannelHasItem (t , writes ), buildPatch (ControllerVersion ))
776+ assert .Equal (t , assert .ChannelHasItem (t , writes ), buildPatch ())
703777 assert .ChannelIsEmpty (t , writes )
704778 // Test fake doesn't actual do Apply, so manually do this
705779 defaultGateway .Annotations = map [string ]string {ControllerVersionAnnotation : fmt .Sprint (ControllerVersion )}
@@ -712,7 +786,7 @@ func TestVersionManagement(t *testing.T) {
712786 defaultGateway .Annotations = map [string ]string {ControllerVersionAnnotation : fmt .Sprint (1 )}
713787 gws .Update (defaultGateway )
714788 expectReconciled ()
715- assert .Equal (t , assert .ChannelHasItem (t , writes ), buildPatch (ControllerVersion ))
789+ assert .Equal (t , assert .ChannelHasItem (t , writes ), buildPatch ())
716790 assert .ChannelIsEmpty (t , writes )
717791 // Test fake doesn't actual do Apply, so manually do this
718792 defaultGateway .Annotations = map [string ]string {ControllerVersionAnnotation : fmt .Sprint (ControllerVersion )}
@@ -995,7 +1069,7 @@ func TestHandlerEnqueueFunction(t *testing.T) {
9951069 client .Kube ().Discovery ().(* fakediscovery.FakeDiscovery ).FakedServerVersion = & kubeVersion.Info {Major : "1" , Minor : "28" }
9961070
9971071 tw := revisions .NewTagWatcher (client , "" )
998- env := model . NewEnvironment ()
1072+ env := newTestEnv ()
9991073 go tw .Run (stop )
10001074
10011075 d := NewDeploymentController (client , cluster .ID (features .ClusterName ), env , dummyWebHookInjectFn , func (fn func ()) {
@@ -1075,11 +1149,22 @@ global:
10751149 return injConfig
10761150}
10771151
1078- func buildPatch (version int ) string {
1152+ // buildPatch used to accept a version
1153+ // but lint flagged that ControllerVersion
1154+ // was always used so the function has been
1155+ // adjusted to hardcode ControllerVersion
1156+ func buildPatch () string {
10791157 return fmt .Sprintf (`apiVersion: gateway.networking.k8s.io/v1beta1
10801158kind: Gateway
10811159metadata:
10821160 annotations:
10831161 gateway.istio.io/controller-version: "%d"
1084- ` , version )
1162+ ` , ControllerVersion )
1163+ }
1164+
1165+ func newTestEnv () * model.Environment {
1166+ env := model .NewEnvironment ()
1167+ env .Watcher = meshwatcher .NewTestWatcher (mesh .DefaultMeshConfig ())
1168+
1169+ return env
10851170}
0 commit comments