99 "sort"
1010 "strconv"
1111 "strings"
12+ "time"
1213
1314 "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/model"
1415 "k8s.io/apimachinery/pkg/labels"
@@ -18,6 +19,7 @@ import (
1819 "github.com/golang/protobuf/ptypes/wrappers"
1920 "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/v1alpha1"
2021 "github.com/istio-ecosystem/admiral/admiral/pkg/controller/common"
22+ controllerutils "github.com/istio-ecosystem/admiral/admiral/pkg/controller/util"
2123 "github.com/istio-ecosystem/admiral/admiral/pkg/core/vsrouting"
2224 "github.com/istio-ecosystem/admiral/admiral/pkg/util"
2325 log "github.com/sirupsen/logrus"
@@ -557,13 +559,14 @@ func generateVirtualServiceForIncluster(
557559 vsHosts = append (vsHosts , globalFQDN )
558560 }
559561
562+ virtualService .Name = fmt .Sprintf ("%s-%s" , vsName , common .InclusterVSNameSuffix )
560563 if len (vsHosts ) == 0 {
561- return nil , fmt . Errorf (
562- "skipped creating virtualservice as there are no valid hosts found" )
564+ err := deleteVSRoutingResources ( ctx , ctxLogger , remoteRegistry , sourceCluster , vsName , false )
565+ return nil , fmt . Errorf ( "deleting old in-cluster virtual service as there are no valid hosts found for %s, error=%v" , virtualService . Name , err )
563566 }
564567 if len (httpRoutes ) == 0 {
565- return nil , fmt . Errorf (
566- "skipped creating virtualservice on cluster as there are no valid http routes found" )
568+ err := deleteVSRoutingResources ( ctx , ctxLogger , remoteRegistry , sourceCluster , vsName , false )
569+ return nil , fmt . Errorf ( "deleting old in- cluster virtual service as there are no valid http routes found for %s, error=%v" , virtualService . Name , err )
567570 }
568571 sort .Strings (vsHosts )
569572 virtualService .Spec .Hosts = vsHosts
@@ -572,8 +575,6 @@ func generateVirtualServiceForIncluster(
572575 })
573576 virtualService .Spec .Http = httpRoutes
574577
575- virtualService .Name = fmt .Sprintf ("%s-%s" , vsName , common .InclusterVSNameSuffix )
576-
577578 // Add the exportTo namespaces to the virtual service
578579 virtualService .Spec .ExportTo = []string {common .GetSyncNamespace ()}
579580 vsRoutingInclusterEnabledForClusterAndIdentity := false
@@ -591,8 +592,47 @@ func generateVirtualServiceForIncluster(
591592 return virtualService , nil
592593}
593594
595+ func deleteVSRoutingResources (ctx context.Context , ctxLogger * log.Entry , remoteRegistry * RemoteRegistry , sourceCluster string , vsName string , crossCluster bool ) error {
596+ var err error
597+ start := time .Now ()
598+ rc := remoteRegistry .GetRemoteController (sourceCluster )
599+ if rc == nil {
600+ return fmt .Errorf ("remote controller not initialized on this cluster" )
601+ }
602+
603+ if crossCluster {
604+ vsName = vsName + "-" + common .RoutingVSNameSuffix
605+ } else {
606+ vsName = vsName + "-" + common .InclusterVSNameSuffix
607+ }
608+
609+ oldVirtualService := rc .VirtualServiceController .VirtualServiceCache .Get (vsName )
610+ if oldVirtualService != nil && isGeneratedByAdmiral (oldVirtualService .Annotations ) {
611+ err = deleteVirtualService (ctx , vsName , util .IstioSystemNamespace , rc )
612+ controllerutils .LogElapsedTimeSinceTask (ctxLogger , "deleteVSRoutingResources" , vsName , util .IstioSystemNamespace , sourceCluster , "" , start )
613+ }
614+ if err != nil {
615+ var vsAlreadyDeletedErr * IsVSAlreadyDeletedErr
616+ if errors .As (err , & vsAlreadyDeletedErr ) {
617+ ctxLogger .Infof (LogFormat , "Delete" , "VirtualService" , vsName , rc .ClusterID , "Either VirtualService was already deleted, or it never existed" )
618+ return nil
619+ }
620+ if isDeadCluster (err ) {
621+ ctxLogger .Warnf (LogErrFormat , "Delete" , common .VirtualServiceResourceType , vsName , rc .ClusterID , "dead cluster" )
622+ return nil
623+ }
624+ return fmt .Errorf (LogErrFormat , "Delete" , "VirtualService" , vsName , rc .ClusterID , err )
625+ }
626+ ctxLogger .Infof (LogFormat , "Delete" , "VirtualService" , vsName , rc .ClusterID , "Success" )
627+ return err
628+ }
629+
594630// generateVirtualServiceForIngress generates the VirtualService for the cross-cluster routing
595631func generateVirtualServiceForIngress (
632+ ctx context.Context ,
633+ ctxLogger * log.Entry ,
634+ remoteRegistry * RemoteRegistry ,
635+ sourceCluster string ,
596636 destination map [string ][]* vsrouting.RouteDestination ,
597637 vsName string ) (* v1alpha3.VirtualService , error ) {
598638
@@ -628,14 +668,14 @@ func generateVirtualServiceForIngress(
628668 tlsRoutes = append (tlsRoutes , & tlsRoute )
629669 vsHosts = append (vsHosts , hostWithSNIPrefix )
630670 }
631-
671+ virtualService . Name = vsName + "-" + common . RoutingVSNameSuffix
632672 if len (vsHosts ) == 0 {
633- return nil , fmt . Errorf (
634- "skipped creating virtualservice as there are no valid hosts found" )
673+ err := deleteVSRoutingResources ( ctx , ctxLogger , remoteRegistry , sourceCluster , vsName , true )
674+ return nil , fmt . Errorf ( "deleting old ingress virtual service as there are no valid hosts found for %s, error=%v" , virtualService . Name , err )
635675 }
636676 if len (tlsRoutes ) == 0 {
637- return nil , fmt . Errorf (
638- "skipped creating virtualservice on cluster as there are no valid tls routes found" )
677+ err := deleteVSRoutingResources ( ctx , ctxLogger , remoteRegistry , sourceCluster , vsName , true )
678+ return nil , fmt . Errorf ( "deleting old ingress virtual service as there are no valid tls routes found for %s, error=%v" , virtualService . Name , err )
639679 }
640680 sort .Strings (vsHosts )
641681 virtualService .Spec .Hosts = vsHosts
@@ -644,17 +684,17 @@ func generateVirtualServiceForIngress(
644684 })
645685 virtualService .Spec .Tls = tlsRoutes
646686
647- virtualService .Name = vsName + "-routing-vs"
648-
649687 return virtualService , nil
650688}
651689
652690// doReconcileVirtualService checks if desired virtualservice state has changed from the one that is cached
653691// returns true if it has, else returns false
654692func doReconcileVirtualService (
693+ ctxLogger * log.Entry ,
655694 rc * RemoteController ,
656695 desiredVirtualService * v1alpha3.VirtualService ,
657696 doRoutesMatch VSRouteComparator ,
697+ sourceCluster string ,
658698) (bool , error ) {
659699 if rc == nil {
660700 return true , fmt .Errorf ("remoteController is nil" )
@@ -671,30 +711,46 @@ func doReconcileVirtualService(
671711 vsName := desiredVirtualService .Name
672712 cachedVS := rc .VirtualServiceController .VirtualServiceCache .Get (vsName )
673713 if cachedVS == nil {
714+ ctxLogger .Infof (common .CtxLogFormat , "ReconcileVirtualService" , vsName , "" , sourceCluster ,
715+ fmt .Sprintf ("missing cached VS" ))
674716 return true , nil
675717 }
718+
719+ if ! isGeneratedByAdmiral (cachedVS .Annotations ) {
720+ ctxLogger .Infof (common .CtxLogFormat , "AddServiceEntriesWithDrWorker" , cachedVS .Name , cachedVS .Namespace , rc .ClusterID , "skipped updating the VS as there exists a custom VS with the same name" )
721+ return false , nil
722+ }
723+
676724 cachedVSSpec := cachedVS .Spec .DeepCopy ()
677725 desiredVirtualServiceSpec := desiredVirtualService .Spec .DeepCopy ()
678726 // Check if exportTo has a diff
679727 slices .Sort (cachedVSSpec .ExportTo )
680728 slices .Sort (desiredVirtualServiceSpec .ExportTo )
681729 if ! reflect .DeepEqual (cachedVSSpec .ExportTo , desiredVirtualServiceSpec .ExportTo ) {
730+ ctxLogger .Infof (common .CtxLogFormat , "ReconcileVirtualService" , vsName , "" , sourceCluster ,
731+ fmt .Sprintf ("VS exportTo has changed, cached: %v, desired: %v" , cachedVSSpec .ExportTo , desiredVirtualServiceSpec .ExportTo ))
682732 return true , nil
683733 }
684734
685735 // Check if hosts have a diff
686736 slices .Sort (cachedVSSpec .Hosts )
687737 slices .Sort (desiredVirtualServiceSpec .Hosts )
688738 if ! reflect .DeepEqual (cachedVSSpec .Hosts , desiredVirtualServiceSpec .Hosts ) {
739+ ctxLogger .Infof (common .CtxLogFormat , "ReconcileVirtualService" , vsName , "" , sourceCluster ,
740+ fmt .Sprintf ("VS hosts has changed, cached: %v, desired: %v" , cachedVSSpec .Hosts , desiredVirtualServiceSpec .Hosts ))
689741 return true , nil
690742 }
691743
692744 // Check if routes have a diff
693745 routeMatched , err := doRoutesMatch (cachedVSSpec , desiredVirtualServiceSpec )
694746 if err != nil {
747+ ctxLogger .Infof (common .CtxLogFormat , "ReconcileVirtualService" , vsName , "" , sourceCluster ,
748+ fmt .Sprintf ("error in routeMatch check %v" , err .Error ()))
695749 return true , err
696750 }
697751 if ! routeMatched {
752+ ctxLogger .Infof (common .CtxLogFormat , "ReconcileVirtualService" , vsName , "" , sourceCluster ,
753+ fmt .Sprintf ("diff in routes, cached: %v, desired: %v" , cachedVSSpec , desiredVirtualServiceSpec ))
698754 return true , err
699755 }
700756
@@ -703,6 +759,8 @@ func doReconcileVirtualService(
703759 slices .Sort (cachedVSSpec .Gateways )
704760 slices .Sort (desiredVirtualServiceSpec .Gateways )
705761 if ! reflect .DeepEqual (cachedVSSpec .Gateways , desiredVirtualServiceSpec .Gateways ) {
762+ ctxLogger .Infof (common .CtxLogFormat , "ReconcileVirtualService" , vsName , "" , sourceCluster ,
763+ fmt .Sprintf ("diff in gateways, cached: %v, desired: %v" , cachedVSSpec .Gateways , desiredVirtualServiceSpec .Gateways ))
706764 return true , nil
707765 }
708766 }
@@ -793,7 +851,7 @@ func addUpdateInClusterVirtualServices(
793851 common .CtxLogFormat , "ReconcileVirtualService" , vs .Name , "" , sourceCluster ,
794852 "checking if incluster routing virtualService requires reconciliation" )
795853 reconcileRequired , err :=
796- doReconcileVirtualService (rc , vs , httpRoutesComparator )
854+ doReconcileVirtualService (ctxLogger , rc , vs , httpRoutesComparator , sourceCluster )
797855 if err != nil {
798856 ctxLogger .Errorf (common .CtxLogFormat , "addUpdateInClusterVirtualServices" ,
799857 vs .Name , vs .Namespace , sourceCluster ,
@@ -1448,7 +1506,7 @@ func addUpdateVirtualServicesForIngress(
14481506 continue
14491507 }
14501508
1451- virtualService , err := generateVirtualServiceForIngress (destination , vsName )
1509+ virtualService , err := generateVirtualServiceForIngress (ctx , ctxLogger , remoteRegistry , sourceCluster , destination , vsName )
14521510 if err != nil {
14531511 ctxLogger .Errorf (common .CtxLogFormat , "addUpdateVirtualServicesForIngress" ,
14541512 "" , "" , sourceCluster , err .Error ())
@@ -1459,7 +1517,7 @@ func addUpdateVirtualServicesForIngress(
14591517 common .CtxLogFormat , "ReconcileVirtualService" , virtualService .Name , "" , sourceCluster ,
14601518 "checking if ingress routing virtualService requires reconciliation" )
14611519 reconcileRequired , err :=
1462- doReconcileVirtualService (rc , virtualService , tlsRoutesComparator )
1520+ doReconcileVirtualService (ctxLogger , rc , virtualService , tlsRoutesComparator , sourceCluster )
14631521 if err != nil {
14641522 ctxLogger .Errorf (common .CtxLogFormat , "addUpdateVirtualServicesForIngress" ,
14651523 virtualService .Name , virtualService .Namespace , sourceCluster ,
@@ -1573,6 +1631,9 @@ func processGTPAndAddWeightsByCluster(ctxLogger *log.Entry,
15731631 if err != nil {
15741632 ctxLogger .Warnf (common .CtxLogFormat , "doActivePassiveInClusterVS" ,
15751633 cname , "" , sourceCluster , err .Error ())
1634+ } else {
1635+ ctxLogger .Infof (common .CtxLogFormat , "doActivePassiveInClusterVS" ,
1636+ cname , "" , sourceCluster , "active/passive routing for in-cluster VS enabled" )
15761637 }
15771638 }
15781639 if globalTrafficPolicy != nil {
@@ -1915,7 +1976,7 @@ func addUpdateInClusterDestinationRule(
19151976
19161977 err := addUpdateRoutingDestinationRule (
19171978 ctx , ctxLogger , remoteRegistry , drHosts , sourceCluster ,
1918- common .InclusterDRSuffix , exportToNamespaces , clientTLSSettings , clientConnectionSettings )
1979+ common .InclusterDRSuffix , exportToNamespaces , clientTLSSettings , clientConnectionSettings , sourceIdentity )
19191980
19201981 if err != nil {
19211982 ctxLogger .Errorf (common .CtxLogFormat , "addUpdateDestinationRuleForSourceIngress" ,
@@ -1965,7 +2026,7 @@ func addUpdateDestinationRuleForSourceIngress(
19652026
19662027 err := addUpdateRoutingDestinationRule (
19672028 ctx , ctxLogger , remoteRegistry , drHosts , sourceCluster ,
1968- common .RoutingDRSuffix , common .GetIngressVSExportToNamespace (), clientTLSSettings , nil )
2029+ common .RoutingDRSuffix , common .GetIngressVSExportToNamespace (), clientTLSSettings , nil , sourceIdentity )
19692030
19702031 if err != nil {
19712032 ctxLogger .Errorf (common .CtxLogFormat , "addUpdateDestinationRuleForSourceIngress" ,
@@ -1986,7 +2047,8 @@ func addUpdateRoutingDestinationRule(
19862047 drNameSuffix string ,
19872048 exportToNamespaces []string ,
19882049 clientTLSSettings * networkingV1Alpha3.ClientTLSSettings ,
1989- clientConnectionSettings * v1alpha1.ClientConnectionConfig ) error {
2050+ clientConnectionSettings * v1alpha1.ClientConnectionConfig ,
2051+ sourceIdentity string ) error {
19902052
19912053 if remoteRegistry == nil {
19922054 return fmt .Errorf ("remoteRegistry is nil" )
@@ -2054,6 +2116,7 @@ func addUpdateRoutingDestinationRule(
20542116 }
20552117
20562118 newDR .Spec .ExportTo = exportToNamespaces
2119+ newDR .Spec = * addNLBIdleTimeout (ctx , ctxLogger , remoteRegistry , rc , newDR .Spec .DeepCopy (), sourceCluster , sourceIdentity )
20572120
20582121 doReconcileDR := reconcileDestinationRule (
20592122 ctxLogger , true , rc , & newDR .Spec , drName , sourceCluster , util .IstioSystemNamespace )
@@ -2075,7 +2138,10 @@ func addUpdateRoutingDestinationRule(
20752138 sourceCluster , fmt .Sprintf ("failed getting existing DR, error=%v" , err ))
20762139 existingDR = nil
20772140 }
2078-
2141+ if existingDR != nil && ! isGeneratedByAdmiral (existingDR .Annotations ) {
2142+ ctxLogger .Infof (LogFormat , "update" , "DestinationRule" , existingDR .Name , rc .ClusterID , "skipped updating the DR as there exists a custom DR with the same name in " + util .IstioSystemNamespace + " namespace" )
2143+ continue
2144+ }
20792145 err = addUpdateDestinationRule (ctxLogger , ctx , newDR , existingDR , util .IstioSystemNamespace , rc , remoteRegistry )
20802146 if err != nil {
20812147 ctxLogger .Errorf (common .CtxLogFormat , "addUpdateRoutingDestinationRule" ,
0 commit comments