diff --git a/pkg/canary/controller.go b/pkg/canary/controller.go index 98836991..1edf97ef 100644 --- a/pkg/canary/controller.go +++ b/pkg/canary/controller.go @@ -7,7 +7,7 @@ import ( type Controller interface { IsPrimaryReady(canary *flaggerv1.Canary) error IsCanaryReady(canary *flaggerv1.Canary) (bool, error) - GetMetadata(canary *flaggerv1.Canary) (string, map[string]int32, error) + GetMetadata(canary *flaggerv1.Canary) (string, string, map[string]int32, error) SyncStatus(canary *flaggerv1.Canary, status flaggerv1.CanaryStatus) error SetStatusFailedChecks(canary *flaggerv1.Canary, val int) error SetStatusWeight(canary *flaggerv1.Canary, val int) error diff --git a/pkg/canary/daemonset_controller.go b/pkg/canary/daemonset_controller.go index 7e0972cd..44833388 100644 --- a/pkg/canary/daemonset_controller.go +++ b/pkg/canary/daemonset_controller.go @@ -107,7 +107,7 @@ func (c *DaemonSetController) Promote(cd *flaggerv1.Canary) error { return fmt.Errorf("damonset %s.%s get query error: %v", targetName, cd.Namespace, err) } - label, err := c.getSelectorLabel(canary) + label, labelValue, err := c.getSelectorLabel(canary) if err != nil { return fmt.Errorf("getSelectorLabel failed: %w", err) } @@ -146,7 +146,7 @@ func (c *DaemonSetController) Promote(cd *flaggerv1.Canary) error { } primaryCopy.Spec.Template.Annotations = annotations - primaryCopy.Spec.Template.Labels = makePrimaryLabels(canary.Spec.Template.Labels, primaryName, label) + primaryCopy.Spec.Template.Labels = makePrimaryLabels(canary.Spec.Template.Labels, labelValue, label) // apply update _, err = c.kubeClient.AppsV1().DaemonSets(cd.Namespace).Update(context.TODO(), primaryCopy, metav1.UpdateOptions{}) @@ -179,24 +179,24 @@ func (c *DaemonSetController) HasTargetChanged(cd *flaggerv1.Canary) (bool, erro } // GetMetadata returns the pod label selector and svc ports -func (c *DaemonSetController) GetMetadata(cd *flaggerv1.Canary) (string, map[string]int32, error) { +func (c *DaemonSetController) GetMetadata(cd *flaggerv1.Canary) (string, string, map[string]int32, error) { targetName := cd.Spec.TargetRef.Name canaryDae, err := c.kubeClient.AppsV1().DaemonSets(cd.Namespace).Get(context.TODO(), targetName, metav1.GetOptions{}) if err != nil { - return "", nil, fmt.Errorf("daemonset %s.%s get query error: %w", targetName, cd.Namespace, err) + return "", "", nil, fmt.Errorf("daemonset %s.%s get query error: %w", targetName, cd.Namespace, err) } - label, err := c.getSelectorLabel(canaryDae) + label, labelValue, err := c.getSelectorLabel(canaryDae) if err != nil { - return "", nil, fmt.Errorf("getSelectorLabel failed: %w", err) + return "", "", nil, fmt.Errorf("getSelectorLabel failed: %w", err) } var ports map[string]int32 if cd.Spec.Service.PortDiscovery { ports = getPorts(cd, canaryDae.Spec.Template.Spec.Containers) } - return label, ports, nil + return label, labelValue, ports, nil } func (c *DaemonSetController) createPrimaryDaemonSet(cd *flaggerv1.Canary) error { @@ -214,7 +214,7 @@ func (c *DaemonSetController) createPrimaryDaemonSet(cd *flaggerv1.Canary) error targetName, cd.Namespace, canaryDae.Spec.UpdateStrategy.Type) } - label, err := c.getSelectorLabel(canaryDae) + label, labelValue, err := c.getSelectorLabel(canaryDae) if err != nil { return fmt.Errorf("getSelectorLabel failed: %w", err) } @@ -240,7 +240,7 @@ func (c *DaemonSetController) createPrimaryDaemonSet(cd *flaggerv1.Canary) error Name: primaryName, Namespace: cd.Namespace, Labels: map[string]string{ - label: primaryName, + label: labelValue, }, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(cd, schema.GroupVersionKind{ @@ -256,12 +256,12 @@ func (c *DaemonSetController) createPrimaryDaemonSet(cd *flaggerv1.Canary) error UpdateStrategy: canaryDae.Spec.UpdateStrategy, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - label: primaryName, + label: labelValue, }, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: makePrimaryLabels(canaryDae.Spec.Template.Labels, primaryName, label), + Labels: makePrimaryLabels(canaryDae.Spec.Template.Labels, labelValue, label), Annotations: annotations, }, // update spec with the primary secrets and config maps @@ -281,14 +281,14 @@ func (c *DaemonSetController) createPrimaryDaemonSet(cd *flaggerv1.Canary) error } // getSelectorLabel returns the selector match label -func (c *DaemonSetController) getSelectorLabel(daemonSet *appsv1.DaemonSet) (string, error) { +func (c *DaemonSetController) getSelectorLabel(daemonSet *appsv1.DaemonSet) (string, string, error) { for _, l := range c.labels { if _, ok := daemonSet.Spec.Selector.MatchLabels[l]; ok { - return l, nil + return l, daemonSet.Spec.Selector.MatchLabels[l], nil } } - return "", fmt.Errorf( + return "", "", fmt.Errorf( "daemonset %s.%s spec.selector.matchLabels must contain one of %v'", daemonSet.Name, daemonSet.Namespace, c.labels, ) diff --git a/pkg/canary/deployment_controller.go b/pkg/canary/deployment_controller.go index a9d0cd5f..72584d9d 100644 --- a/pkg/canary/deployment_controller.go +++ b/pkg/canary/deployment_controller.go @@ -72,7 +72,7 @@ func (c *DeploymentController) Promote(cd *flaggerv1.Canary) error { return fmt.Errorf("deployment %s.%s get query error: %w", targetName, cd.Namespace, err) } - label, err := c.getSelectorLabel(canary) + label, labelValue, err := c.getSelectorLabel(canary) if err != nil { return fmt.Errorf("getSelectorLabel failed: %w", err) } @@ -107,7 +107,7 @@ func (c *DeploymentController) Promote(cd *flaggerv1.Canary) error { } primaryCopy.Spec.Template.Annotations = annotations - primaryCopy.Spec.Template.Labels = makePrimaryLabels(canary.Spec.Template.Labels, primaryName, label) + primaryCopy.Spec.Template.Labels = makePrimaryLabels(canary.Spec.Template.Labels, labelValue, label) // apply update _, err = c.kubeClient.AppsV1().Deployments(cd.Namespace).Update(context.TODO(), primaryCopy, metav1.UpdateOptions{}) @@ -181,17 +181,17 @@ func (c *DeploymentController) ScaleFromZero(cd *flaggerv1.Canary) error { } // GetMetadata returns the pod label selector and svc ports -func (c *DeploymentController) GetMetadata(cd *flaggerv1.Canary) (string, map[string]int32, error) { +func (c *DeploymentController) GetMetadata(cd *flaggerv1.Canary) (string, string, map[string]int32, error) { targetName := cd.Spec.TargetRef.Name canaryDep, err := c.kubeClient.AppsV1().Deployments(cd.Namespace).Get(context.TODO(), targetName, metav1.GetOptions{}) if err != nil { - return "", nil, fmt.Errorf("deployment %s.%s get query error: %w", targetName, cd.Namespace, err) + return "", "", nil, fmt.Errorf("deployment %s.%s get query error: %w", targetName, cd.Namespace, err) } - label, err := c.getSelectorLabel(canaryDep) + label, labelValue, err := c.getSelectorLabel(canaryDep) if err != nil { - return "", nil, fmt.Errorf("getSelectorLabel failed: %w", err) + return "", "", nil, fmt.Errorf("getSelectorLabel failed: %w", err) } var ports map[string]int32 @@ -199,7 +199,7 @@ func (c *DeploymentController) GetMetadata(cd *flaggerv1.Canary) (string, map[st ports = getPorts(cd, canaryDep.Spec.Template.Spec.Containers) } - return label, ports, nil + return label, labelValue, ports, nil } func (c *DeploymentController) createPrimaryDeployment(cd *flaggerv1.Canary) error { targetName := cd.Spec.TargetRef.Name @@ -210,7 +210,7 @@ func (c *DeploymentController) createPrimaryDeployment(cd *flaggerv1.Canary) err return fmt.Errorf("deplyoment %s.%s get query error: %w", targetName, cd.Namespace, err) } - label, err := c.getSelectorLabel(canaryDep) + label, labelValue, err := c.getSelectorLabel(canaryDep) if err != nil { return fmt.Errorf("getSelectorLabel failed: %w", err) } @@ -241,7 +241,7 @@ func (c *DeploymentController) createPrimaryDeployment(cd *flaggerv1.Canary) err Name: primaryName, Namespace: cd.Namespace, Labels: map[string]string{ - label: primaryName, + label: labelValue, }, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(cd, schema.GroupVersionKind{ @@ -259,7 +259,7 @@ func (c *DeploymentController) createPrimaryDeployment(cd *flaggerv1.Canary) err Strategy: canaryDep.Spec.Strategy, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - label: primaryName, + label: labelValue, }, }, Template: corev1.PodTemplateSpec{ @@ -361,14 +361,14 @@ func (c *DeploymentController) reconcilePrimaryHpa(cd *flaggerv1.Canary, init bo } // getSelectorLabel returns the selector match label -func (c *DeploymentController) getSelectorLabel(deployment *appsv1.Deployment) (string, error) { +func (c *DeploymentController) getSelectorLabel(deployment *appsv1.Deployment) (string, string, error) { for _, l := range c.labels { if _, ok := deployment.Spec.Selector.MatchLabels[l]; ok { - return l, nil + return l, deployment.Spec.Selector.MatchLabels[l], nil } } - return "", fmt.Errorf( + return "", "", fmt.Errorf( "deployment %s.%s spec.selector.matchLabels must contain one of %v", deployment.Name, deployment.Namespace, c.labels, ) diff --git a/pkg/canary/service_controller.go b/pkg/canary/service_controller.go index 1961b6cb..f63131da 100644 --- a/pkg/canary/service_controller.go +++ b/pkg/canary/service_controller.go @@ -42,9 +42,9 @@ func (c *ServiceController) SetStatusPhase(cd *flaggerv1.Canary, phase flaggerv1 return setStatusPhase(c.flaggerClient, cd, phase) } -// GetMetadata returns the pod label selector and svc ports -func (c *ServiceController) GetMetadata(_ *flaggerv1.Canary) (string, map[string]int32, error) { - return "", nil, nil +// GetMetadata returns the pod label selector, label value and svc ports +func (c *ServiceController) GetMetadata(_ *flaggerv1.Canary) (string, string, map[string]int32, error) { + return "", "", nil, nil } // Initialize creates or updates the primary and canary services to prepare for the canary release process targeted on the K8s service diff --git a/pkg/canary/util.go b/pkg/canary/util.go index f4f58304..254cd38a 100644 --- a/pkg/canary/util.go +++ b/pkg/canary/util.go @@ -75,14 +75,14 @@ func makeAnnotations(annotations map[string]string) (map[string]string, error) { return res, nil } -func makePrimaryLabels(labels map[string]string, primaryName string, label string) map[string]string { +func makePrimaryLabels(labels map[string]string, labelValue string, label string) map[string]string { res := make(map[string]string) for k, v := range labels { if k != label { res[k] = v } } - res[label] = primaryName + res[label] = labelValue return res } diff --git a/pkg/controller/finalizer.go b/pkg/controller/finalizer.go index 34633342..b1a6fbec 100644 --- a/pkg/controller/finalizer.go +++ b/pkg/controller/finalizer.go @@ -50,13 +50,13 @@ func (c *Controller) finalize(old interface{}) error { return fmt.Errorf("canary not ready during finalizing: %w", err) } - labelSelector, ports, err := canaryController.GetMetadata(canary) + labelSelector, labelValue, ports, err := canaryController.GetMetadata(canary) if err != nil { return fmt.Errorf("failed to get metadata for router finalizing: %w", err) } // Revert the Kubernetes service - router := c.routerFactory.KubernetesRouter(canary.Spec.TargetRef.Kind, labelSelector, ports) + router := c.routerFactory.KubernetesRouter(canary.Spec.TargetRef.Kind, labelSelector, labelValue, ports) if err := router.Finalize(canary); err != nil { return fmt.Errorf("failed revert router: %w", err) } diff --git a/pkg/controller/scheduler.go b/pkg/controller/scheduler.go index 11fac989..df4c4f6a 100644 --- a/pkg/controller/scheduler.go +++ b/pkg/controller/scheduler.go @@ -100,14 +100,14 @@ func (c *Controller) advanceCanary(name string, namespace string) { // init controller based on target kind canaryController := c.canaryFactory.Controller(cd.Spec.TargetRef.Kind) - labelSelector, ports, err := canaryController.GetMetadata(cd) + labelSelector, labelValue, ports, err := canaryController.GetMetadata(cd) if err != nil { c.recordEventWarningf(cd, "%v", err) return } // init Kubernetes router - kubeRouter := c.routerFactory.KubernetesRouter(cd.Spec.TargetRef.Kind, labelSelector, ports) + kubeRouter := c.routerFactory.KubernetesRouter(cd.Spec.TargetRef.Kind, labelSelector, labelValue, ports) // reconcile the canary/primary services if err := kubeRouter.Initialize(cd); err != nil { diff --git a/pkg/router/factory.go b/pkg/router/factory.go index 2a970c90..cd1835b3 100644 --- a/pkg/router/factory.go +++ b/pkg/router/factory.go @@ -39,7 +39,7 @@ func NewFactory(kubeConfig *restclient.Config, kubeClient kubernetes.Interface, } // KubernetesRouter returns a KubernetesRouter interface implementation -func (factory *Factory) KubernetesRouter(kind string, labelSelector string, ports map[string]int32) KubernetesRouter { +func (factory *Factory) KubernetesRouter(kind string, labelSelector string, labelValue string, ports map[string]int32) KubernetesRouter { switch kind { case "Service": return &KubernetesNoopRouter{} @@ -49,6 +49,7 @@ func (factory *Factory) KubernetesRouter(kind string, labelSelector string, port flaggerClient: factory.flaggerClient, kubeClient: factory.kubeClient, labelSelector: labelSelector, + labelValue: labelValue, ports: ports, } } diff --git a/pkg/router/kubernetes_default.go b/pkg/router/kubernetes_default.go index 739dc4c7..45eb5f3f 100644 --- a/pkg/router/kubernetes_default.go +++ b/pkg/router/kubernetes_default.go @@ -25,6 +25,7 @@ type KubernetesDefaultRouter struct { flaggerClient clientset.Interface logger *zap.SugaredLogger labelSelector string + labelValue string ports map[string]int32 } @@ -33,13 +34,13 @@ func (c *KubernetesDefaultRouter) Initialize(canary *flaggerv1.Canary) error { _, primaryName, canaryName := canary.GetServiceNames() // canary svc - err := c.reconcileService(canary, canaryName, canary.Spec.TargetRef.Name, canary.Spec.Service.Canary) + err := c.reconcileService(canary, canaryName, c.labelValue, canary.Spec.Service.Canary) if err != nil { return fmt.Errorf("reconcileService failed: %w", err) } // primary svc - err = c.reconcileService(canary, primaryName, fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name), canary.Spec.Service.Primary) + err = c.reconcileService(canary, primaryName, fmt.Sprintf("%s-primary", c.labelValue), canary.Spec.Service.Primary) if err != nil { return fmt.Errorf("reconcileService failed: %w", err) } @@ -52,7 +53,7 @@ func (c *KubernetesDefaultRouter) Reconcile(canary *flaggerv1.Canary) error { apexName, _, _ := canary.GetServiceNames() // main svc - err := c.reconcileService(canary, apexName, fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name), canary.Spec.Service.Apex) + err := c.reconcileService(canary, apexName, fmt.Sprintf("%s-primary", c.labelValue), canary.Spec.Service.Apex) if err != nil { return fmt.Errorf("reconcileService failed: %w", err) }