sigs.k8s.io/cluster-api-provider-azure@v1.17.0/azure/services/managedclusters/managedclusters_test.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package managedclusters
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"testing"
    23  
    24  	asocontainerservicev1 "github.com/Azure/azure-service-operator/v2/api/containerservice/v1api20231001"
    25  	asocontainerservicev1preview "github.com/Azure/azure-service-operator/v2/api/containerservice/v1api20231102preview"
    26  	. "github.com/onsi/gomega"
    27  	"go.uber.org/mock/gomock"
    28  	corev1 "k8s.io/api/core/v1"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  	"k8s.io/utils/ptr"
    31  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    32  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/managedclusters/mock_managedclusters"
    33  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    34  	"sigs.k8s.io/cluster-api/util/secret"
    35  	fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
    36  )
    37  
    38  func TestPostCreateOrUpdateResourceHook(t *testing.T) {
    39  	t.Run("error creating or updating", func(t *testing.T) {
    40  		g := NewGomegaWithT(t)
    41  		mockCtrl := gomock.NewController(t)
    42  		scope := mock_managedclusters.NewMockManagedClusterScope(mockCtrl)
    43  
    44  		err := postCreateOrUpdateResourceHook(context.Background(), scope, nil, errors.New("an error"))
    45  		g.Expect(err).To(HaveOccurred())
    46  	})
    47  
    48  	t.Run("successful create or update", func(t *testing.T) {
    49  		g := NewGomegaWithT(t)
    50  		namespace := "default"
    51  		scope := setupMockScope(t)
    52  
    53  		managedCluster := &asocontainerservicev1.ManagedCluster{
    54  			ObjectMeta: metav1.ObjectMeta{
    55  				Namespace: namespace,
    56  			},
    57  			Spec: asocontainerservicev1.ManagedCluster_Spec{
    58  				KubernetesVersion: ptr.To("1.19.0"),
    59  				AutoUpgradeProfile: &asocontainerservicev1.ManagedClusterAutoUpgradeProfile{
    60  					UpgradeChannel: ptr.To(asocontainerservicev1.ManagedClusterAutoUpgradeProfile_UpgradeChannel_Stable),
    61  				},
    62  			},
    63  			Status: asocontainerservicev1.ManagedCluster_STATUS{
    64  				Fqdn:        ptr.To("fdqn"),
    65  				PrivateFQDN: ptr.To("private fqdn"),
    66  				OidcIssuerProfile: &asocontainerservicev1.ManagedClusterOIDCIssuerProfile_STATUS{
    67  					IssuerURL: ptr.To("oidc"),
    68  				},
    69  				CurrentKubernetesVersion: ptr.To("1.19.0"),
    70  			},
    71  		}
    72  
    73  		err := postCreateOrUpdateResourceHook(context.Background(), scope, managedCluster, nil)
    74  		g.Expect(err).NotTo(HaveOccurred())
    75  	})
    76  
    77  	t.Run("successful create or update, preview enabled", func(t *testing.T) {
    78  		g := NewGomegaWithT(t)
    79  		namespace := "default"
    80  		scope := setupMockScope(t)
    81  
    82  		managedCluster := &asocontainerservicev1preview.ManagedCluster{
    83  			ObjectMeta: metav1.ObjectMeta{
    84  				Namespace: namespace,
    85  			},
    86  			Spec: asocontainerservicev1preview.ManagedCluster_Spec{
    87  				KubernetesVersion: ptr.To("1.19.0"),
    88  				AutoUpgradeProfile: &asocontainerservicev1preview.ManagedClusterAutoUpgradeProfile{
    89  					UpgradeChannel: ptr.To(asocontainerservicev1preview.ManagedClusterAutoUpgradeProfile_UpgradeChannel_Stable),
    90  				},
    91  			},
    92  			Status: asocontainerservicev1preview.ManagedCluster_STATUS{
    93  				Fqdn:        ptr.To("fdqn"),
    94  				PrivateFQDN: ptr.To("private fqdn"),
    95  				OidcIssuerProfile: &asocontainerservicev1preview.ManagedClusterOIDCIssuerProfile_STATUS{
    96  					IssuerURL: ptr.To("oidc"),
    97  				},
    98  				CurrentKubernetesVersion: ptr.To("1.19.0"),
    99  			},
   100  		}
   101  
   102  		err := postCreateOrUpdateResourceHook(context.Background(), scope, managedCluster, nil)
   103  		g.Expect(err).NotTo(HaveOccurred())
   104  	})
   105  
   106  	t.Run("private cluster fqdn", func(t *testing.T) {
   107  		g := NewGomegaWithT(t)
   108  		mockCtrl := gomock.NewController(t)
   109  		scope := mock_managedclusters.NewMockManagedClusterScope(mockCtrl)
   110  		namespace := "default"
   111  		clusterName := "cluster"
   112  
   113  		kclient := fakeclient.NewClientBuilder().
   114  			Build()
   115  		scope.EXPECT().GetClient().Return(kclient).AnyTimes()
   116  
   117  		scope.EXPECT().SetControlPlaneEndpoint(clusterv1.APIEndpoint{
   118  			Host: "private fqdn",
   119  			Port: 443,
   120  		})
   121  		scope.EXPECT().ClusterName().Return(clusterName).AnyTimes()
   122  		scope.EXPECT().IsAADEnabled().Return(true)
   123  
   124  		managedCluster := &asocontainerservicev1.ManagedCluster{
   125  			ObjectMeta: metav1.ObjectMeta{
   126  				Namespace: namespace,
   127  			},
   128  			Status: asocontainerservicev1.ManagedCluster_STATUS{
   129  				Fqdn:        ptr.To("fdqn"),
   130  				PrivateFQDN: ptr.To("private fqdn"),
   131  				ApiServerAccessProfile: &asocontainerservicev1.ManagedClusterAPIServerAccessProfile_STATUS{
   132  					EnablePrivateCluster:           ptr.To(true),
   133  					EnablePrivateClusterPublicFQDN: ptr.To(false),
   134  				},
   135  			},
   136  		}
   137  
   138  		err := postCreateOrUpdateResourceHook(context.Background(), scope, managedCluster, nil)
   139  		g.Expect(err).To(HaveOccurred())
   140  	})
   141  }
   142  
   143  func setupMockScope(t *testing.T) *mock_managedclusters.MockManagedClusterScope {
   144  	t.Helper()
   145  	mockCtrl := gomock.NewController(t)
   146  	scope := mock_managedclusters.NewMockManagedClusterScope(mockCtrl)
   147  	namespace := "default"
   148  	clusterName := "cluster"
   149  
   150  	adminASOKubeconfig := &corev1.Secret{
   151  		ObjectMeta: metav1.ObjectMeta{
   152  			Namespace: namespace,
   153  			Name:      adminKubeconfigSecretName(clusterName),
   154  		},
   155  		Data: map[string][]byte{
   156  			secret.KubeconfigDataName: []byte("admin credentials"),
   157  		},
   158  	}
   159  	userASOKubeconfig := &corev1.Secret{
   160  		ObjectMeta: metav1.ObjectMeta{
   161  			Namespace: namespace,
   162  			Name:      userKubeconfigSecretName(clusterName),
   163  		},
   164  		Data: map[string][]byte{
   165  			secret.KubeconfigDataName: []byte("user credentials"),
   166  		},
   167  	}
   168  	kclient := fakeclient.NewClientBuilder().
   169  		WithObjects(adminASOKubeconfig, userASOKubeconfig).
   170  		Build()
   171  	scope.EXPECT().GetClient().Return(kclient).AnyTimes()
   172  
   173  	scope.EXPECT().SetControlPlaneEndpoint(clusterv1.APIEndpoint{
   174  		Host: "fdqn",
   175  		Port: 443,
   176  	})
   177  	scope.EXPECT().ClusterName().Return(clusterName).AnyTimes()
   178  	scope.EXPECT().IsAADEnabled().Return(true)
   179  	scope.EXPECT().AreLocalAccountsDisabled().Return(false)
   180  	scope.EXPECT().SetAdminKubeconfigData([]byte("admin credentials"))
   181  	scope.EXPECT().SetUserKubeconfigData([]byte("user credentials"))
   182  	scope.EXPECT().SetOIDCIssuerProfileStatus(gomock.Nil())
   183  	scope.EXPECT().SetOIDCIssuerProfileStatus(&infrav1.OIDCIssuerProfileStatus{
   184  		IssuerURL: ptr.To("oidc"),
   185  	})
   186  	scope.EXPECT().SetVersionStatus("v1.19.0")
   187  	scope.EXPECT().IsManagedVersionUpgrade().Return(true)
   188  	scope.EXPECT().SetAutoUpgradeVersionStatus("v1.19.0")
   189  
   190  	return scope
   191  }