Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ukff committed Dec 16, 2024
1 parent 1ad623d commit ce2b485
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 58 deletions.
11 changes: 0 additions & 11 deletions controllers/btpoperator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import (
"github.com/kyma-project/btp-manager/internal/manifest"
"github.com/kyma-project/btp-manager/internal/metrics"
"github.com/kyma-project/btp-manager/internal/ymlutils"
. "github.com/onsi/ginkgo/v2"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -139,10 +138,6 @@ type InstanceBindingSerivce interface {
EnableSISBController()
}

type SecretWatchedData struct {
clusterId []byte
}

// BtpOperatorReconciler reconciles a BtpOperator object
type BtpOperatorReconciler struct {
client.Client
Expand Down Expand Up @@ -184,12 +179,7 @@ func NewBtpOperatorReconciler(client client.Client, scheme *runtime.Scheme, inst
//+kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources="rolebindings",verbs="*"
//+kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources="roles",verbs="*"

func LOG(data any) {
GinkgoWriter.Println(fmt.Sprintf("==> %v <==", data))
}

func (r *BtpOperatorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
LOG("RECONCILE")
r.workqueueSize += 1
defer func() { r.workqueueSize -= 1 }()

Expand Down Expand Up @@ -241,7 +231,6 @@ func (r *BtpOperatorReconciler) Reconcile(ctx context.Context, req ctrl.Request)
case "":
return ctrl.Result{}, r.HandleInitialState(ctx, reconcileCr)
case v1alpha1.StateProcessing:
LOG("PROCESSING")
return ctrl.Result{RequeueAfter: ProcessingStateRequeueInterval}, r.HandleProcessingState(ctx, reconcileCr)
case v1alpha1.StateWarning:
return r.HandleWarningState(ctx, reconcileCr)
Expand Down
170 changes: 124 additions & 46 deletions controllers/btpoperator_controller_secret_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package controllers

import (
"encoding/json"
"context"

Check failure on line 4 in controllers/btpoperator_controller_secret_test.go

View workflow job for this annotation

GitHub Actions / run-go-linter

File is not `goimports`-ed (goimports)
"github.com/kyma-project/btp-manager/api/v1alpha1"
"github.com/kyma-project/btp-manager/internal/conditions"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand All @@ -17,60 +20,143 @@ const (
clusterIdNew = "new-cluster-id"
)

var w bool

var _ = Describe("BTP Operator controller - sap btp manager secret changes", Label("secret"), func() {
When("sap btp secret is updated with new clust id", func() {
cr := &v1alpha1.BtpOperator{}
sapBtpSecret := &corev1.Secret{}
configMap := &corev1.ConfigMap{}
btpServiceOperatorDeployment := &appsv1.Deployment{}
clusterSecret := &corev1.Secret{}

BeforeEach(func() {
var err error
sapBtpSecret, err = createCorrectSecretFromYaml()
Expect(err).To(BeNil())
Eventually(func() error {
return k8sClient.Create(ctx, sapBtpSecret)
}).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())
cr := &v1alpha1.BtpOperator{}
sapBtpSecret := &corev1.Secret{}
configMap := &corev1.ConfigMap{}
btpServiceOperatorDeployment := &appsv1.Deployment{}

BeforeEach(func() {
go SimulateSapBtpServiceOperatorSecret(ctx)

var err error
sapBtpSecret, err = createCorrectSecretFromYaml()
Expect(err).To(BeNil())
Eventually(func() error {
return k8sClient.Create(ctx, sapBtpSecret)
}).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())

cr = createDefaultBtpOperator()
Expect(k8sClient.Create(ctx, cr)).To(Succeed())
Eventually(updateCh).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Receive(matchReadyCondition(v1alpha1.StateProcessing, metav1.ConditionFalse, conditions.Initialized)))

Eventually(func() error {
return k8sClient.Get(ctx, client.ObjectKey{Name: DeploymentName, Namespace: kymaNamespace}, btpServiceOperatorDeployment)
}).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())

cr = createDefaultBtpOperator()
Expect(k8sClient.Create(ctx, cr)).To(Succeed())
Eventually(updateCh).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Receive(matchReadyCondition(v1alpha1.StateProcessing, metav1.ConditionFalse, conditions.Initialized)))
Eventually(func() error {
return k8sClient.Get(ctx, client.ObjectKey{Namespace: kymaNamespace, Name: btpServiceOperatorConfigMap}, configMap)
}).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())
})

AfterEach(func() {
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: defaultNamespace, Name: btpOperatorName}, cr)).Should(Succeed())
Expect(k8sClient.Delete(ctx, cr)).Should(Succeed())
Eventually(updateCh).Should(Receive(matchDeleted()))
Expect(isCrNotFound()).To(BeTrue())
Eventually(func() error { return k8sClient.Delete(ctx, sapBtpSecret) }).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())
})

Context("sap btp secret is updated with new clust id", func() {
It("should restart and update secret", func() {
GinkgoWriter.Println("==> Change cluster id in sap btp secret")
sapBtpSecret.Data[sapBtpManagerSecretClusterIdKey] = []byte(clusterIdNew)
Expect(k8sClient.Update(ctx, sapBtpSecret)).To(Succeed())
Eventually(updateCh).Should(Receive(matchReadyCondition(v1alpha1.StateReady, metav1.ConditionTrue, conditions.ReconcileSucceeded)))

_, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: client.ObjectKey{Name: btpOperatorName, Namespace: kymaNamespace}})
Expect(err).To(BeNil())

Eventually(func() error {
return k8sClient.Get(ctx, client.ObjectKey{Name: DeploymentName, Namespace: kymaNamespace}, btpServiceOperatorDeployment)
return k8sClient.Get(ctx, client.ObjectKey{Namespace: kymaNamespace, Name: SecretName}, sapBtpSecret)
}).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())

clusterSecret = generateClusterIDSecret(clusterIdInit)
Eventually(func() error {
return k8sClient.Create(ctx, clusterSecret)
return k8sClient.Get(ctx, client.ObjectKey{Namespace: kymaNamespace, Name: btpServiceOperatorConfigMap}, configMap)
}).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())

clusterIdSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: clusterIdSecretName,
Namespace: kymaNamespace,
},
}
Eventually(func() error {
return k8sClient.Get(ctx, client.ObjectKey{Namespace: kymaNamespace, Name: btpServiceOperatorConfigMap}, configMap)
return k8sClient.Get(ctx, client.ObjectKey{Namespace: kymaNamespace, Name: clusterIdSecretName}, clusterIdSecret)
}).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())
})

AfterEach(func() {
Expect(k8sClient.Get(ctx, client.ObjectKey{Namespace: defaultNamespace, Name: btpOperatorName}, cr)).Should(Succeed())
Expect(k8sClient.Delete(ctx, cr)).Should(Succeed())
Eventually(updateCh).Should(Receive(matchDeleted()))
Expect(isCrNotFound()).To(BeTrue())
Eventually(func() error { return k8sClient.Delete(ctx, sapBtpSecret) }).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())
Eventually(func() error { return k8sClient.Delete(ctx, clusterSecret) }).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())
})
s, err := k8sClientset.CoreV1().Secrets(kymaNamespace).Get(ctx, clusterIdSecretName, metav1.GetOptions{})
Expect(err).To(BeNil())
Expect(s.Data[clusterIdSecretKey]).To(Equal([]byte(clusterIdNew)))

When("change cluster id in sap btp secret", func() {
It("should restart and update secret", func() {
sapBtpSecret.Data[sapBtpManagerSecretClusterIdKey] = []byte(clusterIdNew)
Eventually(func() error { return k8sClient.Update(ctx, sapBtpSecret) }).WithTimeout(k8sOpsTimeout).WithPolling(k8sOpsPollingInterval).Should(Succeed())
Eventually(updateCh).Should(Receive(matchState(v1alpha1.StateProcessing)))
Eventually(updateCh).Should(Receive(matchReadyCondition(v1alpha1.StateReady, metav1.ConditionTrue, conditions.ReconcileSucceeded)))
})
base := string(sapBtpSecret.Data[sapBtpManagerSecretClusterIdKey])
synced := base == clusterIdNew
synced = synced && base == string(clusterIdSecret.Data[clusterIdSecretKey])
synced = synced && base == configMap.Data[clusterIdKeyConfigMap]
GinkgoWriter.Println("==> Secret: %s", string(sapBtpSecret.Data[sapBtpManagerSecretClusterIdKey]))
GinkgoWriter.Println("==> Cluster ID Secret: %s", string(clusterIdSecret.Data[clusterIdSecretKey]))
GinkgoWriter.Println("==> ConfigMap: %s", configMap.Data[clusterIdKeyConfigMap])
Expect(synced).To(BeTrue())
})
})
})

func SimulateSapBtpServiceOperatorSecret(ctx context.Context) {
timeOut := int64(1)
var err error
w, err := k8sClientset.CoreV1().Secrets(kymaNamespace).Watch(ctx, metav1.ListOptions{TimeoutSeconds: &timeOut})
if err != nil {
GinkgoWriter.Println("==> Watch secret error: %s ", err)
panic(err)
}

for event := range w.ResultChan() {
GinkgoWriter.Println("==> Watch secret event type: %s ", event.Type)
item := event.Object.(*corev1.Secret)
if item.Name == clusterIdSecretName {
GinkgoWriter.Println("==> Watch secret event for : %s ", item.Name)
switch event.Type {
case watch.Modified:
case watch.Bookmark:
case watch.Error:
case watch.Deleted:
GinkgoWriter.Println("==> Delete cluster id secret")
clusterSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: clusterIdSecretName,
Namespace: kymaNamespace,
},
}
err := k8sClient.Get(ctx, client.ObjectKey{Namespace: kymaNamespace, Name: clusterIdSecretName}, clusterSecret)
if errors.IsNotFound(err) {
return
}
err = k8sClient.Delete(ctx, generateClusterIDSecret(""))
if err != nil {
return
}
case watch.Added:
GinkgoWriter.Println("==> Add cluster id secret")
clusterSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: clusterIdSecretName,
Namespace: kymaNamespace,
},
}
err := k8sClient.Get(ctx, client.ObjectKey{Namespace: kymaNamespace, Name: clusterIdSecretName}, clusterSecret)
if errors.IsNotFound(err) {
err = k8sClient.Create(ctx, generateClusterIDSecret(clusterIdInit))
if err != nil {
return
}
}
}
}
}
}

func generateClusterIDSecret(key string) *corev1.Secret {
clusterSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -83,11 +169,3 @@ func generateClusterIDSecret(key string) *corev1.Secret {
}
return clusterSecret
}

func f(data any) string {
s, err := json.MarshalIndent(data, "", " ")
if err != nil {
panic(err)
}
return string(s)
}
8 changes: 7 additions & 1 deletion controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controllers
import (
"context"
"fmt"
"k8s.io/client-go/kubernetes"

Check failure on line 22 in controllers/suite_test.go

View workflow job for this annotation

GitHub Actions / run-go-linter

File is not `goimports`-ed (goimports)
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -71,6 +72,7 @@ const (
var (
cfg *rest.Config
k8sClient client.Client
k8sClientset *kubernetes.Clientset
k8sClientFromManager client.Client
k8sManager manager.Manager
testEnv *envtest.Environment
Expand Down Expand Up @@ -156,14 +158,17 @@ var _ = SynchronizedBeforeSuite(func() {
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())

k8sClientset, err = kubernetes.NewForConfig(cfg)
Expect(err).NotTo(HaveOccurred())
Expect(k8sClientset).NotTo(BeNil())

k8sManager, err = ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme.Scheme,
Metrics: server.Options{BindAddress: "0"},
HealthProbeBindAddress: "0",
NewCache: CacheCreator,
})
Expect(err).ToNot(HaveOccurred())

ctx, cancel = context.WithCancel(ctrl.SetupSignalHandler())

metrics := btpmanagermetrics.NewMetrics()
Expand Down Expand Up @@ -245,6 +250,7 @@ var _ = SynchronizedAfterSuite(func() {
cancelDeploymentController()
cancel()
By("tearing down the test environment")
time.Sleep(5)
Expect(testEnv.Stop()).To(Succeed())
}, func() {
// runs only on process #1
Expand Down

0 comments on commit ce2b485

Please sign in to comment.