Skip to content

Commit

Permalink
Add targets selection logic (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
maruina authored Feb 23, 2021
1 parent a13aacf commit 2140815
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 2 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ RUN go mod download
COPY main.go main.go
COPY api/ api/
COPY controllers/ controllers/
COPY internal/ internal/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go
Expand Down
44 changes: 42 additions & 2 deletions controllers/progressiverollout_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,34 @@ func (r *ProgressiveRolloutReconciler) Reconcile(ctx context.Context, req ctrl.R
// Get the ProgressiveRollout object
pr := deploymentskyscannernetv1alpha1.ProgressiveRollout{}
if err := r.Get(ctx, req.NamespacedName, &pr); err != nil {
log.Error(err, "unable to fetch ProgressiveRollout", "object", pr.Name)
log.Error(err, "unable to fetch ProgressiveRollout")
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// Always log the ApplicationSet owner
log = r.Log.WithValues("applicationset", pr.Spec.SourceRef.Name)

for _, stage := range pr.Spec.Stages {
log = r.Log.WithValues("stage", stage.Name)

targets, err := r.GetTargetClusters(stage.Targets.Clusters.Selector)
if err != nil {
log.Error(err, "unable to fetch targets")
return ctrl.Result{}, err
}
r.Log.V(1).Info("targets selected", "targets", targets.Items)
r.Log.Info("stage completed")
}

log.Info("all stages completed")

// Rollout completed
completed := pr.NewStatusCondition(deploymentskyscannernetv1alpha1.CompletedCondition, metav1.ConditionTrue, deploymentskyscannernetv1alpha1.StagesCompleteReason, "All stages completed")
apimeta.SetStatusCondition(pr.GetStatusConditions(), completed)
if err := r.Client.Status().Update(ctx, &pr); err != nil {
r.Log.V(1).Info("failed to update object status", "name", pr.Name, "namespace", pr.Namespace)
r.Log.Error(err, "failed to update object status")
return ctrl.Result{}, err
}
r.Log.Info("rollout completed")
return ctrl.Result{}, nil
}

Expand Down Expand Up @@ -180,3 +197,26 @@ func (r *ProgressiveRolloutReconciler) requestsForSecretChange(o client.Object)

return requests
}

// GetTargetClusters returns a list of ArgoCD clusters matching the provided label selector
func (r *ProgressiveRolloutReconciler) GetTargetClusters(selector metav1.LabelSelector) (corev1.SecretList, error) {
secrets := corev1.SecretList{}
ctx := context.Background()

argoSelector := metav1.AddLabelToSelector(&selector, utils.ArgoCDSecretTypeLabel, utils.ArgoCDSecretTypeCluster)
labels, err := metav1.LabelSelectorAsSelector(argoSelector)
if err != nil {
r.Log.Error(err, "unable to convert selector into labels")
return corev1.SecretList{}, err
}

if err = r.List(ctx, &secrets, client.MatchingLabelsSelector{Selector: labels}); err != nil {
r.Log.Error(err, "failed to select targets using labels selector")
return corev1.SecretList{}, err
}

// https://github.com/Skyscanner/argocd-progressive-rollout/issues/9 will provide a better sorting
utils.SortSecretsByName(&secrets)

return secrets, nil
}
10 changes: 10 additions & 0 deletions internal/utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
package utils

import (
corev1 "k8s.io/api/core/v1"
"sort"
)

// IsArgoCDCluster returns true if one of the labels is the ArgoCD secret label with the secret type cluster as value
func IsArgoCDCluster(labels map[string]string) bool {
val, ok := labels[ArgoCDSecretTypeLabel]
return val == ArgoCDSecretTypeCluster && ok
}

// SortSecretsByName sort the SecretList in place by the secrets name
func SortSecretsByName(secrets *corev1.SecretList) {
sort.SliceStable(secrets.Items, func(i, j int) bool { return secrets.Items[i].Name < secrets.Items[j].Name })
}
27 changes: 27 additions & 0 deletions internal/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package utils

import (
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
)

Expand Down Expand Up @@ -31,3 +33,28 @@ func TestIsArgoCDCluster(t *testing.T) {
g.Expect(got).To(Equal(testCase.expected))
}
}

func TestSortSecretsByName(t *testing.T) {
namespace := "default"
testCase := struct {
secretList *corev1.SecretList
expected *corev1.SecretList
}{
secretList: &corev1.SecretList{Items: []corev1.Secret{{
ObjectMeta: metav1.ObjectMeta{Name: "clusterA", Namespace: namespace},
}, {
ObjectMeta: metav1.ObjectMeta{Name: "clusterC", Namespace: namespace},
}, {
ObjectMeta: metav1.ObjectMeta{Name: "clusterB", Namespace: namespace},
}}},
expected: &corev1.SecretList{Items: []corev1.Secret{{
ObjectMeta: metav1.ObjectMeta{Name: "clusterA", Namespace: namespace},
}, {
ObjectMeta: metav1.ObjectMeta{Name: "clusterB", Namespace: namespace},
}, {
ObjectMeta: metav1.ObjectMeta{Name: "clusterC", Namespace: namespace},
}}}}
g := NewGomegaWithT(t)
SortSecretsByName(testCase.secretList)
g.Expect(testCase.secretList).Should(Equal(testCase.expected))
}

0 comments on commit 2140815

Please sign in to comment.