Skip to content

Commit

Permalink
Add support for ignoring the current cluster in the list.
Browse files Browse the repository at this point in the history
  • Loading branch information
bigkevmcd committed Oct 24, 2023
1 parent c648821 commit 3080880
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 19 deletions.
4 changes: 3 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Steps before release of the AKS reflector
- [X] Add managed-by labels!
- [ ] Conditions - ready with count of reflected clusters
- [ ] Events - publish when cluster created or removed
- [ ] Suspension
- [X] Suspension
- [ ] Manually triggered reconciliation
- [ ] Provide for authentication via a Secret?
- [ ] CommonLabels support
- [ ] ObservedGeneration support!
26 changes: 20 additions & 6 deletions internal/controller/automatedclusterdiscovery_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,39 @@ func (r *AutomatedClusterDiscoveryReconciler) Reconcile(ctx context.Context, req

// Skip reconciliation if the AutomatedClusterDiscovery is suspended.
if clusterDiscovery.Spec.Suspend {
logger.Info("Reconciliation is suspended for this object")
logger.Info("reconciliation is suspended for this object")
return ctrl.Result{}, nil
}

logger.Info("Reconciling cluster reflector",
logger.Info("reconciling cluster reflector",
"type", clusterDiscovery.Spec.Type,
"name", clusterDiscovery.Spec.Name,
)

if clusterDiscovery.Spec.Type == "aks" {
logger.Info("Reconciling AKS cluster reflector",
logger.Info("reconciling AKS cluster reflector",
"name", clusterDiscovery.Spec.Name,
)

azureProvider := r.AKSProvider(clusterDiscovery.Spec.AKS.SubscriptionID)

// We get the clusters and cluster ID separately so that we can return
// the error from the Reconciler without touching the inventory.
clusters, err := azureProvider.ListClusters(ctx)
if err != nil {
logger.Error(err, "Failed to list AKS clusters")
logger.Error(err, "failed to list AKS clusters")
return ctrl.Result{}, err
}

inventoryRefs, err := r.reconcileClusters(ctx, clusters, clusterDiscovery)
clusterID, err := azureProvider.ClusterID(ctx, r.Client)
if err != nil {
logger.Error(err, "failed to list get Cluster ID from AKS cluster")
return ctrl.Result{}, err
}

// TODO: Fix this so that we record the inventoryRefs even if we get an
// error.
inventoryRefs, err := r.reconcileClusters(ctx, clusters, clusterID, clusterDiscovery)
if err != nil {
return ctrl.Result{}, err
}
Expand Down Expand Up @@ -121,7 +131,7 @@ func (r *AutomatedClusterDiscoveryReconciler) SetupWithManager(mgr ctrl.Manager)
Complete(r)
}

func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Context, clusters []*providers.ProviderCluster, cd *clustersv1alpha1.AutomatedClusterDiscovery) ([]clustersv1alpha1.ResourceRef, error) {
func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Context, clusters []*providers.ProviderCluster, currentClusterID string, cd *clustersv1alpha1.AutomatedClusterDiscovery) ([]clustersv1alpha1.ResourceRef, error) {
logger := log.FromContext(ctx)
logger.Info("reconciling clusters", "count", len(clusters))

Expand All @@ -145,6 +155,10 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Cont
inventoryResources := []clustersv1alpha1.ResourceRef{}

for _, cluster := range clusters {
if currentClusterID != "" && currentClusterID == cluster.ID {
logger.Info("skipping current cluster")
continue
}
secretName := fmt.Sprintf("%s-kubeconfig", cluster.Name)

gitopsCluster := newGitopsCluster(secretName, types.NamespacedName{
Expand Down
89 changes: 77 additions & 12 deletions internal/controller/automatedclusterdiscovery_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestAutomatedClusterDiscoveryReconciler(t *testing.T) {

ctx := context.TODO()
key := types.NamespacedName{Name: aksCluster.Name, Namespace: aksCluster.Namespace}
err = mgr.GetClient().Create(ctx, aksCluster)
err = k8sClient.Create(ctx, aksCluster)
assert.NoError(t, err)
defer deleteClusterDiscoveryAndInventory(t, k8sClient, aksCluster)

Expand Down Expand Up @@ -151,6 +151,70 @@ func TestAutomatedClusterDiscoveryReconciler(t *testing.T) {
assertHasOwnerReference(t, secret, clusterRef)
})

t.Run("Reconcile when executing in cluster and cluster matches reflector cluster", func(t *testing.T) {
aksCluster := &clustersv1alpha1.AutomatedClusterDiscovery{
ObjectMeta: metav1.ObjectMeta{
Name: "test-aks",
Namespace: "default",
},
Spec: clustersv1alpha1.AutomatedClusterDiscoverySpec{
Type: "aks",
AKS: &clustersv1alpha1.AKS{
SubscriptionID: "subscription-123",
},
Interval: metav1.Duration{Duration: time.Minute},
},
}
testClusterID := "/subscriptions/ace37984-aaaa-1234-1234-a1a12c0ae14b/resourcegroups/team-pesto-use1/providers/Microsoft.ContainerService/managedClusters/test-cluster"

testProvider := stubProvider{
clusterID: testClusterID,
response: []*providers.ProviderCluster{
{
Name: "test-cluster",
ID: testClusterID,
KubeConfig: &kubeconfig.Config{
APIVersion: "v1",
Clusters: map[string]*kubeconfig.Cluster{
"test-cluster": {
Server: "https://cluster-prod.example.com/",
CertificateAuthorityData: []uint8(testCAData),
},
},
},
},
},
}

reconciler := &AutomatedClusterDiscoveryReconciler{
Client: k8sClient,
Scheme: scheme,
AKSProvider: func(providerID string) providers.Provider {
return &testProvider
},
}

assert.NoError(t, reconciler.SetupWithManager(mgr))

ctx := context.TODO()
key := types.NamespacedName{Name: aksCluster.Name, Namespace: aksCluster.Namespace}
err = k8sClient.Create(ctx, aksCluster)
assert.NoError(t, err)
defer deleteClusterDiscoveryAndInventory(t, k8sClient, aksCluster)

result, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: key})
assert.NoError(t, err)
assert.Equal(t, ctrl.Result{RequeueAfter: time.Minute}, result)

gitopsCluster := &gitopsv1alpha1.GitopsCluster{}
err = k8sClient.Get(ctx, types.NamespacedName{Name: "test-cluster", Namespace: aksCluster.Namespace}, gitopsCluster)
assert.True(t, apierrors.IsNotFound(err))

secret := &corev1.Secret{}
err = k8sClient.Get(ctx, types.NamespacedName{Name: "test-cluster-kubeconfig", Namespace: aksCluster.Namespace}, secret)
assert.True(t, apierrors.IsNotFound(err))
})

t.Run("Reconcile when cluster has been removed from AKS", func(t *testing.T) {
ctx := context.TODO()
aksCluster := &clustersv1alpha1.AutomatedClusterDiscovery{
Expand Down Expand Up @@ -294,7 +358,7 @@ func TestAutomatedClusterDiscoveryReconciler(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, value, secret.Data["value"])
})
t.Run("test suspend option", func(t *testing.T) {
t.Run("Reconcile suspended cluster discovery resource", func(t *testing.T) {
ctx := context.TODO()
aksCluster := &clustersv1alpha1.AutomatedClusterDiscovery{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -339,7 +403,7 @@ func TestAutomatedClusterDiscoveryReconciler(t *testing.T) {
assert.NoError(t, reconciler.SetupWithManager(mgr))

key := types.NamespacedName{Name: aksCluster.Name, Namespace: aksCluster.Namespace}
err = mgr.GetClient().Create(ctx, aksCluster)
err = k8sClient.Create(ctx, aksCluster)
assert.NoError(t, err)
defer deleteObject(t, k8sClient, aksCluster)

Expand Down Expand Up @@ -417,7 +481,6 @@ func TestAutomatedClusterDiscoveryReconciler(t *testing.T) {
_, err = reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKeyFromObject(aksCluster)})
assert.NoError(t, err)
})

}

type stubProvider struct {
Expand All @@ -444,14 +507,16 @@ func deleteClusterDiscoveryAndInventory(t *testing.T, cl client.Client, cd *clus
t.Helper()
ctx := context.TODO()

for _, v := range cd.Status.Inventory.Entries {
u, err := unstructuredFromResourceRef(v)
if err != nil {
t.Errorf("failed to convert unstructured from %s", v)
continue
}
if err := client.IgnoreNotFound(cl.Delete(ctx, u)); err != nil {
t.Errorf("failed to delete %v: %s", u, err)
if cd.Status.Inventory != nil {
for _, v := range cd.Status.Inventory.Entries {
u, err := unstructuredFromResourceRef(v)
if err != nil {
t.Errorf("failed to convert unstructured from %s", v)
continue
}
if err := client.IgnoreNotFound(cl.Delete(ctx, u)); err != nil {
t.Errorf("failed to delete %v: %s", u, err)
}
}
}

Expand Down

0 comments on commit 3080880

Please sign in to comment.