diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 0b13b25e..23298952 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -105,17 +105,25 @@ func NewController( flaggerInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: ctrl.enqueue, UpdateFunc: func(old, new interface{}) { - oldRoll, ok := checkCustomResourceType(old, logger) + oldCanary, ok := checkCustomResourceType(old, logger) if !ok { return } - newRoll, ok := checkCustomResourceType(new, logger) + newCanary, ok := checkCustomResourceType(new, logger) if !ok { return } - if diff := cmp.Diff(newRoll.Spec, oldRoll.Spec); diff != "" { - ctrl.logger.Debugf("Diff detected %s.%s %s", oldRoll.Name, oldRoll.Namespace, diff) + if diff := cmp.Diff(newCanary.Spec, oldCanary.Spec); diff != "" { + ctrl.logger.Debugf("Diff detected %s.%s %s", oldCanary.Name, oldCanary.Namespace, diff) + + // warn about routing conflicts when service name changes + if oldCanary.Spec.Service.Name != "" && oldCanary.Spec.Service.Name != newCanary.Spec.Service.Name { + ctrl.logger.With("canary", fmt.Sprintf("%s.%s", oldCanary.Name, oldCanary.Namespace)). + Warnf("The service name changed to %s, remove %s objects to avoid routing conflicts", + newCanary.Spec.Service.Name, oldCanary.Spec.Service.Name) + } + ctrl.enqueue(new) } }, diff --git a/pkg/router/appmesh.go b/pkg/router/appmesh.go index 33136035..50876004 100644 --- a/pkg/router/appmesh.go +++ b/pkg/router/appmesh.go @@ -33,16 +33,14 @@ func (ar *AppMeshRouter) Reconcile(canary *flaggerv1.Canary) error { return fmt.Errorf("mesh name cannot be empty") } - targetName := canary.Spec.TargetRef.Name - targetHost := fmt.Sprintf("%s.%s", targetName, canary.Namespace) - primaryName := fmt.Sprintf("%s-primary", targetName) + apexName, primaryName, canaryName := canary.GetServiceNames() + targetHost := fmt.Sprintf("%s.%s", apexName, canary.Namespace) primaryHost := fmt.Sprintf("%s.%s", primaryName, canary.Namespace) - canaryName := fmt.Sprintf("%s-canary", targetName) canaryHost := fmt.Sprintf("%s.%s", canaryName, canary.Namespace) // sync virtual node e.g. app-namespace // DNS app.namespace - err := ar.reconcileVirtualNode(canary, targetName, primaryHost) + err := ar.reconcileVirtualNode(canary, apexName, primaryHost) if err != nil { return err } @@ -162,14 +160,14 @@ func (ar *AppMeshRouter) reconcileVirtualNode(canary *flaggerv1.Canary, name str // reconcileVirtualService creates or updates a virtual service func (ar *AppMeshRouter) reconcileVirtualService(canary *flaggerv1.Canary, name string, canaryWeight int64) error { - targetName := canary.Spec.TargetRef.Name - canaryVirtualNode := fmt.Sprintf("%s-canary", targetName) - primaryVirtualNode := fmt.Sprintf("%s-primary", targetName) + apexName, _, _ := canary.GetServiceNames() + canaryVirtualNode := fmt.Sprintf("%s-canary", apexName) + primaryVirtualNode := fmt.Sprintf("%s-primary", apexName) protocol := ar.getProtocol(canary) - routerName := targetName + routerName := apexName if canaryWeight > 0 { - routerName = fmt.Sprintf("%s-canary", targetName) + routerName = fmt.Sprintf("%s-canary", apexName) } // App Mesh supports only URI prefix routePrefix := "/" @@ -208,7 +206,7 @@ func (ar *AppMeshRouter) reconcileVirtualService(canary *flaggerv1.Canary, name if len(canary.Spec.CanaryAnalysis.Match) > 0 && canaryWeight == 0 { routes = []appmeshv1.Route{ { - Name: fmt.Sprintf("%s-a", targetName), + Name: fmt.Sprintf("%s-a", apexName), Priority: int64p(10), Http: &appmeshv1.HttpRoute{ Match: appmeshv1.HttpRouteMatch{ @@ -231,7 +229,7 @@ func (ar *AppMeshRouter) reconcileVirtualService(canary *flaggerv1.Canary, name }, }, { - Name: fmt.Sprintf("%s-b", targetName), + Name: fmt.Sprintf("%s-b", apexName), Priority: int64p(20), Http: &appmeshv1.HttpRoute{ Match: appmeshv1.HttpRouteMatch{ @@ -341,8 +339,8 @@ func (ar *AppMeshRouter) GetRoutes(canary *flaggerv1.Canary) ( mirrored bool, err error, ) { - targetName := canary.Spec.TargetRef.Name - vsName := fmt.Sprintf("%s.%s", targetName, canary.Namespace) + apexName, _, _ := canary.GetServiceNames() + vsName := fmt.Sprintf("%s.%s", apexName, canary.Namespace) vs, err := ar.appmeshClient.AppmeshV1beta1().VirtualServices(canary.Namespace).Get(vsName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { @@ -360,17 +358,17 @@ func (ar *AppMeshRouter) GetRoutes(canary *flaggerv1.Canary) ( targets := vs.Spec.Routes[0].Http.Action.WeightedTargets for _, t := range targets { - if t.VirtualNodeName == fmt.Sprintf("%s-canary", targetName) { + if t.VirtualNodeName == fmt.Sprintf("%s-canary", apexName) { canaryWeight = int(t.Weight) } - if t.VirtualNodeName == fmt.Sprintf("%s-primary", targetName) { + if t.VirtualNodeName == fmt.Sprintf("%s-primary", apexName) { primaryWeight = int(t.Weight) } } if primaryWeight == 0 && canaryWeight == 0 { err = fmt.Errorf("VirtualService %s does not contain routes for %s-primary and %s-canary", - vsName, targetName, targetName) + vsName, apexName, apexName) } mirrored = false @@ -385,8 +383,8 @@ func (ar *AppMeshRouter) SetRoutes( canaryWeight int, mirrored bool, ) error { - targetName := canary.Spec.TargetRef.Name - vsName := fmt.Sprintf("%s.%s", targetName, canary.Namespace) + apexName, _, _ := canary.GetServiceNames() + vsName := fmt.Sprintf("%s.%s", apexName, canary.Namespace) vs, err := ar.appmeshClient.AppmeshV1beta1().VirtualServices(canary.Namespace).Get(vsName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { @@ -399,11 +397,11 @@ func (ar *AppMeshRouter) SetRoutes( vsClone.Spec.Routes[0].Http.Action = appmeshv1.HttpRouteAction{ WeightedTargets: []appmeshv1.WeightedTarget{ { - VirtualNodeName: fmt.Sprintf("%s-canary", targetName), + VirtualNodeName: fmt.Sprintf("%s-canary", apexName), Weight: int64(canaryWeight), }, { - VirtualNodeName: fmt.Sprintf("%s-primary", targetName), + VirtualNodeName: fmt.Sprintf("%s-primary", apexName), Weight: int64(primaryWeight), }, }, diff --git a/pkg/router/contour.go b/pkg/router/contour.go index 1a041210..9e994409 100644 --- a/pkg/router/contour.go +++ b/pkg/router/contour.go @@ -26,9 +26,7 @@ type ContourRouter struct { // Reconcile creates or updates the HTTP proxy func (cr *ContourRouter) Reconcile(canary *flaggerv1.Canary) error { - targetName := canary.Spec.TargetRef.Name - primaryName := fmt.Sprintf("%s-primary", targetName) - canaryName := fmt.Sprintf("%s-canary", targetName) + apexName, primaryName, canaryName := canary.GetServiceNames() newSpec := contourv1.HTTPProxySpec{ Routes: []contourv1.Route{ @@ -131,11 +129,11 @@ func (cr *ContourRouter) Reconcile(canary *flaggerv1.Canary) error { } } - proxy, err := cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Get(targetName, metav1.GetOptions{}) + proxy, err := cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Get(apexName, metav1.GetOptions{}) if errors.IsNotFound(err) { proxy = &contourv1.HTTPProxy{ ObjectMeta: metav1.ObjectMeta{ - Name: targetName, + Name: apexName, Namespace: canary.Namespace, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(canary, schema.GroupVersionKind{ @@ -154,7 +152,7 @@ func (cr *ContourRouter) Reconcile(canary *flaggerv1.Canary) error { _, err = cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Create(proxy) if err != nil { - return fmt.Errorf("HTTPProxy %s.%s create error %v", targetName, canary.Namespace, err) + return fmt.Errorf("HTTPProxy %s.%s create error %v", apexName, canary.Namespace, err) } cr.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). Infof("HTTPProxy %s.%s created", proxy.GetName(), canary.Namespace) @@ -162,7 +160,7 @@ func (cr *ContourRouter) Reconcile(canary *flaggerv1.Canary) error { } if err != nil { - return fmt.Errorf("HTTPProxy %s.%s query error %v", targetName, canary.Namespace, err) + return fmt.Errorf("HTTPProxy %s.%s query error %v", apexName, canary.Namespace, err) } // update HTTPProxy but keep the original destination weights @@ -177,7 +175,7 @@ func (cr *ContourRouter) Reconcile(canary *flaggerv1.Canary) error { _, err = cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Update(clone) if err != nil { - return fmt.Errorf("HTTPProxy %s.%s update error %v", targetName, canary.Namespace, err) + return fmt.Errorf("HTTPProxy %s.%s update error %v", apexName, canary.Namespace, err) } cr.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). Infof("HTTPProxy %s.%s updated", proxy.GetName(), canary.Namespace) @@ -194,21 +192,20 @@ func (cr *ContourRouter) GetRoutes(canary *flaggerv1.Canary) ( mirrored bool, err error, ) { - targetName := canary.Spec.TargetRef.Name - primaryName := fmt.Sprintf("%s-primary", targetName) + apexName, primaryName, _ := canary.GetServiceNames() - proxy, err := cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Get(targetName, metav1.GetOptions{}) + proxy, err := cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - err = fmt.Errorf("HTTPProxy %s.%s not found", targetName, canary.Namespace) + err = fmt.Errorf("HTTPProxy %s.%s not found", apexName, canary.Namespace) return } - err = fmt.Errorf("HTTPProxy %s.%s query error %v", targetName, canary.Namespace, err) + err = fmt.Errorf("HTTPProxy %s.%s query error %v", apexName, canary.Namespace, err) return } if len(proxy.Spec.Routes) < 1 || len(proxy.Spec.Routes[0].Services) < 2 { - err = fmt.Errorf("HTTPProxy %s.%s services not found", targetName, canary.Namespace) + err = fmt.Errorf("HTTPProxy %s.%s services not found", apexName, canary.Namespace) return } @@ -230,21 +227,19 @@ func (cr *ContourRouter) SetRoutes( canaryWeight int, mirrored bool, ) error { - targetName := canary.Spec.TargetRef.Name - primaryName := fmt.Sprintf("%s-primary", targetName) - canaryName := fmt.Sprintf("%s-canary", targetName) + apexName, primaryName, canaryName := canary.GetServiceNames() if primaryWeight == 0 && canaryWeight == 0 { - return fmt.Errorf("HTTPProxy %s.%s update failed: no valid weights", targetName, canary.Namespace) + return fmt.Errorf("HTTPProxy %s.%s update failed: no valid weights", apexName, canary.Namespace) } - proxy, err := cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Get(targetName, metav1.GetOptions{}) + proxy, err := cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - return fmt.Errorf("HTTPProxy %s.%s not found", targetName, canary.Namespace) + return fmt.Errorf("HTTPProxy %s.%s not found", apexName, canary.Namespace) } - return fmt.Errorf("HTTPProxy %s.%s query error %v", targetName, canary.Namespace, err) + return fmt.Errorf("HTTPProxy %s.%s query error %v", apexName, canary.Namespace, err) } proxy.Spec = contourv1.HTTPProxySpec{ @@ -349,7 +344,7 @@ func (cr *ContourRouter) SetRoutes( _, err = cr.contourClient.ProjectcontourV1().HTTPProxies(canary.Namespace).Update(proxy) if err != nil { - return fmt.Errorf("HTTPProxy %s.%s update error %v", targetName, canary.Namespace, err) + return fmt.Errorf("HTTPProxy %s.%s update error %v", apexName, canary.Namespace, err) } return nil } diff --git a/pkg/router/gloo.go b/pkg/router/gloo.go index ceae8c0f..516c7043 100644 --- a/pkg/router/gloo.go +++ b/pkg/router/gloo.go @@ -27,9 +27,9 @@ type GlooRouter struct { // Reconcile creates or updates the Istio virtual service func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error { - targetName := canary.Spec.TargetRef.Name - canaryName := fmt.Sprintf("%s-%s-canary-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port) - primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port) + apexName, _, _ := canary.GetServiceNames() + canaryName := fmt.Sprintf("%s-%s-canary-%v", canary.Namespace, apexName, canary.Spec.Service.Port) + primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, apexName, canary.Spec.Service.Port) newSpec := gloov1.UpstreamGroupSpec{ Destinations: []gloov1.WeightedDestination{ @@ -54,11 +54,11 @@ func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error { }, } - upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(targetName, metav1.GetOptions{}) + upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(apexName, metav1.GetOptions{}) if errors.IsNotFound(err) { upstreamGroup = &gloov1.UpstreamGroup{ ObjectMeta: metav1.ObjectMeta{ - Name: targetName, + Name: apexName, Namespace: canary.Namespace, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(canary, schema.GroupVersionKind{ @@ -73,7 +73,7 @@ func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error { _, err = gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Create(upstreamGroup) if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s create error %v", targetName, canary.Namespace, err) + return fmt.Errorf("UpstreamGroup %s.%s create error %v", apexName, canary.Namespace, err) } gr.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). Infof("UpstreamGroup %s.%s created", upstreamGroup.GetName(), canary.Namespace) @@ -81,7 +81,7 @@ func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error { } if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s query error %v", targetName, canary.Namespace, err) + return fmt.Errorf("UpstreamGroup %s.%s query error %v", apexName, canary.Namespace, err) } // update upstreamGroup but keep the original destination weights @@ -96,7 +96,7 @@ func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error { _, err = gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Update(clone) if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s update error %v", targetName, canary.Namespace, err) + return fmt.Errorf("UpstreamGroup %s.%s update error %v", apexName, canary.Namespace, err) } gr.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). Infof("UpstreamGroup %s.%s updated", upstreamGroup.GetName(), canary.Namespace) @@ -113,21 +113,21 @@ func (gr *GlooRouter) GetRoutes(canary *flaggerv1.Canary) ( mirrored bool, err error, ) { - targetName := canary.Spec.TargetRef.Name + apexName := canary.Spec.TargetRef.Name primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port) - upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(targetName, metav1.GetOptions{}) + upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - err = fmt.Errorf("UpstreamGroup %s.%s not found", targetName, canary.Namespace) + err = fmt.Errorf("UpstreamGroup %s.%s not found", apexName, canary.Namespace) return } - err = fmt.Errorf("UpstreamGroup %s.%s query error %v", targetName, canary.Namespace, err) + err = fmt.Errorf("UpstreamGroup %s.%s query error %v", apexName, canary.Namespace, err) return } if len(upstreamGroup.Spec.Destinations) < 2 { - err = fmt.Errorf("UpstreamGroup %s.%s destinations not found", targetName, canary.Namespace) + err = fmt.Errorf("UpstreamGroup %s.%s destinations not found", apexName, canary.Namespace) return } @@ -149,21 +149,21 @@ func (gr *GlooRouter) SetRoutes( canaryWeight int, mirrored bool, ) error { - targetName := canary.Spec.TargetRef.Name - canaryName := fmt.Sprintf("%s-%s-canary-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port) - primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port) + apexName, _, _ := canary.GetServiceNames() + canaryName := fmt.Sprintf("%s-%s-canary-%v", canary.Namespace, apexName, canary.Spec.Service.Port) + primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, apexName, canary.Spec.Service.Port) if primaryWeight == 0 && canaryWeight == 0 { - return fmt.Errorf("RoutingRule %s.%s update failed: no valid weights", targetName, canary.Namespace) + return fmt.Errorf("RoutingRule %s.%s update failed: no valid weights", apexName, canary.Namespace) } - upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(targetName, metav1.GetOptions{}) + upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - return fmt.Errorf("UpstreamGroup %s.%s not found", targetName, canary.Namespace) + return fmt.Errorf("UpstreamGroup %s.%s not found", apexName, canary.Namespace) } - return fmt.Errorf("UpstreamGroup %s.%s query error %v", targetName, canary.Namespace, err) + return fmt.Errorf("UpstreamGroup %s.%s query error %v", apexName, canary.Namespace, err) } upstreamGroup.Spec = gloov1.UpstreamGroupSpec{ @@ -191,7 +191,7 @@ func (gr *GlooRouter) SetRoutes( _, err = gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Update(upstreamGroup) if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s update error %v", targetName, canary.Namespace, err) + return fmt.Errorf("UpstreamGroup %s.%s update error %v", apexName, canary.Namespace, err) } return nil } diff --git a/pkg/router/ingress.go b/pkg/router/ingress.go index 01da959b..3eebf620 100644 --- a/pkg/router/ingress.go +++ b/pkg/router/ingress.go @@ -27,8 +27,8 @@ func (i *IngressRouter) Reconcile(canary *flaggerv1.Canary) error { return fmt.Errorf("ingress selector is empty") } - targetName := canary.Spec.TargetRef.Name - canaryName := fmt.Sprintf("%s-canary", targetName) + apexName, _, _ := canary.GetServiceNames() + canaryName := fmt.Sprintf("%s-canary", apexName) canaryIngressName := fmt.Sprintf("%s-canary", canary.Spec.IngressRef.Name) ingress, err := i.kubeClient.ExtensionsV1beta1().Ingresses(canary.Namespace).Get(canary.Spec.IngressRef.Name, metav1.GetOptions{}) @@ -42,7 +42,7 @@ func (i *IngressRouter) Reconcile(canary *flaggerv1.Canary) error { backendExists := false for k, v := range ingressClone.Spec.Rules { for x, y := range v.HTTP.Paths { - if y.Backend.ServiceName == targetName { + if y.Backend.ServiceName == apexName { ingressClone.Spec.Rules[k].HTTP.Paths[x].Backend.ServiceName = canaryName backendExists = true break @@ -51,7 +51,7 @@ func (i *IngressRouter) Reconcile(canary *flaggerv1.Canary) error { } if !backendExists { - return fmt.Errorf("backend %s not found in ingress %s", targetName, canary.Spec.IngressRef.Name) + return fmt.Errorf("backend %s not found in ingress %s", apexName, canary.Spec.IngressRef.Name) } canaryIngress, err := i.kubeClient.ExtensionsV1beta1().Ingresses(canary.Namespace).Get(canaryIngressName, metav1.GetOptions{}) diff --git a/pkg/router/istio.go b/pkg/router/istio.go index 8037c595..2f774698 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -26,8 +26,7 @@ type IstioRouter struct { // Reconcile creates or updates the Istio virtual service and destination rules func (ir *IstioRouter) Reconcile(canary *flaggerv1.Canary) error { - canaryName := fmt.Sprintf("%s-canary", canary.Spec.TargetRef.Name) - primaryName := fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name) + _, primaryName, canaryName := canary.GetServiceNames() err := ir.reconcileDestinationRule(canary, canaryName) if err != nil { @@ -101,19 +100,19 @@ func (ir *IstioRouter) reconcileDestinationRule(canary *flaggerv1.Canary, name s } func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { - targetName := canary.Spec.TargetRef.Name + apexName, primaryName, canaryName := canary.GetServiceNames() // set hosts and add the ClusterIP service host if it doesn't exists hosts := canary.Spec.Service.Hosts var hasServiceHost bool for _, h := range hosts { - if h == targetName || h == "*" { + if h == apexName || h == "*" { hasServiceHost = true break } } if !hasServiceHost { - hosts = append(hosts, targetName) + hosts = append(hosts, apexName) } // set gateways and add the mesh gateway if it doesn't exists @@ -132,8 +131,6 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { } // create destinations with primary weight 100% and canary weight 0% - primaryName := fmt.Sprintf("%s-primary", targetName) - canaryName := fmt.Sprintf("%s-canary", targetName) canaryRoute := []istiov1alpha3.DestinationWeight{ makeDestination(canary, primaryName, 100), makeDestination(canary, canaryName, 0), @@ -181,12 +178,12 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { } } - virtualService, err := ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Get(targetName, metav1.GetOptions{}) + virtualService, err := ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Get(apexName, metav1.GetOptions{}) // insert if errors.IsNotFound(err) { virtualService = &istiov1alpha3.VirtualService{ ObjectMeta: metav1.ObjectMeta{ - Name: targetName, + Name: apexName, Namespace: canary.Namespace, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(canary, schema.GroupVersionKind{ @@ -200,7 +197,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { } _, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Create(virtualService) if err != nil { - return fmt.Errorf("VirtualService %s.%s create error %v", targetName, canary.Namespace, err) + return fmt.Errorf("VirtualService %s.%s create error %v", apexName, canary.Namespace, err) } ir.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). Infof("VirtualService %s.%s created", virtualService.GetName(), canary.Namespace) @@ -208,7 +205,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { } if err != nil { - return fmt.Errorf("VirtualService %s.%s query error %v", targetName, canary.Namespace, err) + return fmt.Errorf("VirtualService %s.%s query error %v", apexName, canary.Namespace, err) } // update service but keep the original destination weights and mirror @@ -224,7 +221,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { _, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Update(vtClone) if err != nil { - return fmt.Errorf("VirtualService %s.%s update error %v", targetName, canary.Namespace, err) + return fmt.Errorf("VirtualService %s.%s update error %v", apexName, canary.Namespace, err) } ir.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). Infof("VirtualService %s.%s updated", virtualService.GetName(), canary.Namespace) @@ -241,22 +238,22 @@ func (ir *IstioRouter) GetRoutes(canary *flaggerv1.Canary) ( mirrored bool, err error, ) { - targetName := canary.Spec.TargetRef.Name + apexName, primaryName, canaryName := canary.GetServiceNames() vs := &istiov1alpha3.VirtualService{} - vs, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Get(targetName, metav1.GetOptions{}) + vs, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - err = fmt.Errorf("VirtualService %s.%s not found", targetName, canary.Namespace) + err = fmt.Errorf("VirtualService %s.%s not found", apexName, canary.Namespace) return } - err = fmt.Errorf("VirtualService %s.%s query error %v", targetName, canary.Namespace, err) + err = fmt.Errorf("VirtualService %s.%s query error %v", apexName, canary.Namespace, err) return } var httpRoute istiov1alpha3.HTTPRoute for _, http := range vs.Spec.Http { for _, r := range http.Route { - if r.Destination.Host == fmt.Sprintf("%s-canary", targetName) { + if r.Destination.Host == canaryName { httpRoute = http break } @@ -264,10 +261,10 @@ func (ir *IstioRouter) GetRoutes(canary *flaggerv1.Canary) ( } for _, route := range httpRoute.Route { - if route.Destination.Host == fmt.Sprintf("%s-primary", targetName) { + if route.Destination.Host == primaryName { primaryWeight = route.Weight } - if route.Destination.Host == fmt.Sprintf("%s-canary", targetName) { + if route.Destination.Host == canaryName { canaryWeight = route.Weight } } @@ -277,7 +274,7 @@ func (ir *IstioRouter) GetRoutes(canary *flaggerv1.Canary) ( if primaryWeight == 0 && canaryWeight == 0 { err = fmt.Errorf("VirtualService %s.%s does not contain routes for %s-primary and %s-canary", - targetName, canary.Namespace, targetName, targetName) + apexName, canary.Namespace, apexName, apexName) } return @@ -290,17 +287,15 @@ func (ir *IstioRouter) SetRoutes( canaryWeight int, mirrored bool, ) error { - targetName := canary.Spec.TargetRef.Name - primaryName := fmt.Sprintf("%s-primary", targetName) - canaryName := fmt.Sprintf("%s-canary", targetName) + apexName, primaryName, canaryName := canary.GetServiceNames() - vs, err := ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Get(targetName, metav1.GetOptions{}) + vs, err := ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - return fmt.Errorf("VirtualService %s.%s not found", targetName, canary.Namespace) + return fmt.Errorf("VirtualService %s.%s not found", apexName, canary.Namespace) } - return fmt.Errorf("VirtualService %s.%s query error %v", targetName, canary.Namespace, err) + return fmt.Errorf("VirtualService %s.%s query error %v", apexName, canary.Namespace, err) } vsCopy := vs.DeepCopy() @@ -360,7 +355,7 @@ func (ir *IstioRouter) SetRoutes( vs, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Update(vsCopy) if err != nil { - return fmt.Errorf("VirtualService %s.%s update failed: %v", targetName, canary.Namespace, err) + return fmt.Errorf("VirtualService %s.%s update failed: %v", apexName, canary.Namespace, err) } return nil diff --git a/pkg/router/kubernetes_deployment.go b/pkg/router/kubernetes_deployment.go index e028f4d6..38ef4cce 100644 --- a/pkg/router/kubernetes_deployment.go +++ b/pkg/router/kubernetes_deployment.go @@ -29,12 +29,10 @@ type KubernetesDeploymentRouter struct { // Initialize creates the primary and canary services func (c *KubernetesDeploymentRouter) Initialize(canary *flaggerv1.Canary) error { - targetName := canary.Spec.TargetRef.Name - primaryName := fmt.Sprintf("%s-primary", targetName) - canaryName := fmt.Sprintf("%s-canary", targetName) + apexName, primaryName, canaryName := canary.GetServiceNames() // canary svc - err := c.reconcileService(canary, canaryName, targetName) + err := c.reconcileService(canary, canaryName, apexName) if err != nil { return err } @@ -50,11 +48,10 @@ func (c *KubernetesDeploymentRouter) Initialize(canary *flaggerv1.Canary) error // Reconcile creates or updates the main service func (c *KubernetesDeploymentRouter) Reconcile(canary *flaggerv1.Canary) error { - targetName := canary.Spec.TargetRef.Name - primaryName := fmt.Sprintf("%s-primary", targetName) + apexName, primaryName, _ := canary.GetServiceNames() // main svc - err := c.reconcileService(canary, targetName, primaryName) + err := c.reconcileService(canary, apexName, primaryName) if err != nil { return err } diff --git a/pkg/router/smi.go b/pkg/router/smi.go index 6a587179..2da06cc6 100644 --- a/pkg/router/smi.go +++ b/pkg/router/smi.go @@ -28,15 +28,13 @@ type SmiRouter struct { // Reconcile creates or updates the SMI traffic split func (sr *SmiRouter) Reconcile(canary *flaggerv1.Canary) error { - targetName := canary.Spec.TargetRef.Name - canaryName := fmt.Sprintf("%s-canary", targetName) - primaryName := fmt.Sprintf("%s-primary", targetName) + apexName, primaryName, canaryName := canary.GetServiceNames() var host string if len(canary.Spec.Service.Hosts) > 0 { host = canary.Spec.Service.Hosts[0] } else { - host = targetName + host = apexName } tsSpec := smiv1.TrafficSplitSpec{ @@ -53,12 +51,12 @@ func (sr *SmiRouter) Reconcile(canary *flaggerv1.Canary) error { }, } - ts, err := sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Get(targetName, metav1.GetOptions{}) + ts, err := sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Get(apexName, metav1.GetOptions{}) // create traffic split if errors.IsNotFound(err) { t := &smiv1.TrafficSplit{ ObjectMeta: metav1.ObjectMeta{ - Name: targetName, + Name: apexName, Namespace: canary.Namespace, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(canary, schema.GroupVersionKind{ @@ -83,7 +81,7 @@ func (sr *SmiRouter) Reconcile(canary *flaggerv1.Canary) error { } if err != nil { - return fmt.Errorf("traffic split %s query error %v", targetName, err) + return fmt.Errorf("traffic split %s query error %v", apexName, err) } // update traffic split @@ -93,11 +91,11 @@ func (sr *SmiRouter) Reconcile(canary *flaggerv1.Canary) error { _, err := sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Update(tsClone) if err != nil { - return fmt.Errorf("TrafficSplit %s update error %v", targetName, err) + return fmt.Errorf("TrafficSplit %s update error %v", apexName, err) } sr.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). - Infof("TrafficSplit %s.%s updated", targetName, canary.Namespace) + Infof("TrafficSplit %s.%s updated", apexName, canary.Namespace) return nil } @@ -111,16 +109,14 @@ func (sr *SmiRouter) GetRoutes(canary *flaggerv1.Canary) ( mirrored bool, err error, ) { - targetName := canary.Spec.TargetRef.Name - canaryName := fmt.Sprintf("%s-canary", targetName) - primaryName := fmt.Sprintf("%s-primary", targetName) - ts, err := sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Get(targetName, metav1.GetOptions{}) + apexName, primaryName, canaryName := canary.GetServiceNames() + ts, err := sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - err = fmt.Errorf("TrafficSplit %s.%s not found", targetName, canary.Namespace) + err = fmt.Errorf("TrafficSplit %s.%s not found", apexName, canary.Namespace) return } - err = fmt.Errorf("TrafficSplit %s.%s query error %v", targetName, canary.Namespace, err) + err = fmt.Errorf("TrafficSplit %s.%s query error %v", apexName, canary.Namespace, err) return } @@ -136,7 +132,7 @@ func (sr *SmiRouter) GetRoutes(canary *flaggerv1.Canary) ( if primaryWeight == 0 && canaryWeight == 0 { err = fmt.Errorf("TrafficSplit %s.%s does not contain routes for %s and %s", - targetName, canary.Namespace, primaryName, canaryName) + apexName, canary.Namespace, primaryName, canaryName) } mirrored = false @@ -151,16 +147,14 @@ func (sr *SmiRouter) SetRoutes( canaryWeight int, mirrored bool, ) error { - targetName := canary.Spec.TargetRef.Name - canaryName := fmt.Sprintf("%s-canary", targetName) - primaryName := fmt.Sprintf("%s-primary", targetName) - ts, err := sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Get(targetName, metav1.GetOptions{}) + apexName, primaryName, canaryName := canary.GetServiceNames() + ts, err := sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Get(apexName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { - return fmt.Errorf("TrafficSplit %s.%s not found", targetName, canary.Namespace) + return fmt.Errorf("TrafficSplit %s.%s not found", apexName, canary.Namespace) } - return fmt.Errorf("TrafficSplit %s.%s query error %v", targetName, canary.Namespace, err) + return fmt.Errorf("TrafficSplit %s.%s query error %v", apexName, canary.Namespace, err) } backends := []smiv1.TrafficSplitBackend{ @@ -179,7 +173,7 @@ func (sr *SmiRouter) SetRoutes( _, err = sr.smiClient.SplitV1alpha1().TrafficSplits(canary.Namespace).Update(tsClone) if err != nil { - return fmt.Errorf("TrafficSplit %s update error %v", targetName, err) + return fmt.Errorf("TrafficSplit %s update error %v", apexName, err) } return nil