Skip to content

Commit 870ab7e

Browse files
Punakshi Chaandpchaand
andcommitted
MESH-5873,5474-Adding creation check and handling deletion flow for routing VS,DR (#940)
* enhance logging for VirtualService deletion handling * MESH-5873: add logging and skip updates for custom VS/DR in reconciliation process * enhance virtual service generation with error handling and logging for missing hosts and routes * refactor virtual service deletion logic to consolidate routing resource cleanup * update virtual service deletion test to not return an error for non-existent services * add annotations to existing DestinationRules in routing tests * remove redundant old virtual service retrieval logic in routing controller * MESH-5873: refactor VS/DR naming with common suffix constants for consistency * MESH-5873: Fix parameter passed to deleteVirtualService function * MESH-5873: Remove unused destination rule deletion logic and constant * MESH-5873: Enhance error handling in deleteVSRoutingResources function * MESH-5873: Remove unused context initialization in virtualservice routing test --------- Co-authored-by: pchaand <[email protected]>
1 parent 00949ca commit 870ab7e

File tree

3 files changed

+94
-24
lines changed

3 files changed

+94
-24
lines changed

admiral/pkg/clusters/virtualservice_routing.go

Lines changed: 86 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
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
595631
func 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
654692
func 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",

admiral/pkg/clusters/virtualservice_routing_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3512,8 +3512,9 @@ func TestAddUpdateInClusterDestinationRule(t *testing.T) {
35123512

35133513
existingDR := &apiNetworkingV1Alpha3.DestinationRule{
35143514
ObjectMeta: metaV1.ObjectMeta{
3515-
Name: "test-ns.svc.cluster.local-incluster-dr",
3516-
Namespace: util.IstioSystemNamespace,
3515+
Name: "test-ns.svc.cluster.local-incluster-dr",
3516+
Namespace: util.IstioSystemNamespace,
3517+
Annotations: map[string]string{resourceCreatedByAnnotationLabel: resourceCreatedByAnnotationValue},
35173518
},
35183519
Spec: networkingV1Alpha3.DestinationRule{
35193520
Host: "*.test-ns.svc.cluster.local",
@@ -3841,8 +3842,9 @@ func TestAddUpdateDestinationRuleForSourceIngress(t *testing.T) {
38413842

38423843
existingDR := &apiNetworkingV1Alpha3.DestinationRule{
38433844
ObjectMeta: metaV1.ObjectMeta{
3844-
Name: "test-ns.svc.cluster.local-routing-dr",
3845-
Namespace: util.IstioSystemNamespace,
3845+
Name: "test-ns.svc.cluster.local-routing-dr",
3846+
Namespace: util.IstioSystemNamespace,
3847+
Annotations: map[string]string{resourceCreatedByAnnotationLabel: resourceCreatedByAnnotationValue},
38463848
},
38473849
Spec: networkingV1Alpha3.DestinationRule{
38483850
Host: "*.test-ns.svc.cluster.local",

admiral/pkg/controller/common/common.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ const (
139139
// VSRoutingType This label has been added in order to make the API call efficient
140140
VSRoutingType = "admiral.io/vs-routing-type"
141141
InclusterVSNameSuffix = "incluster-vs"
142+
InclusterDRNameSuffix = "incluster-dr"
143+
RoutingVSNameSuffix = "routing-vs"
142144
VSRoutingTypeInCluster = "incluster"
143145
CreatedByLabel = "createdBy"
144146
CreatedForLabel = "createdFor"

0 commit comments

Comments
 (0)