Повторное согласование триггеров при создании секрета, принадлежащего пользовательскому ресурсу

# #go #kubernetes #kubernetes-custom-resources #reconcile

Вопрос:

Я использовал operator-sdk для создания пользовательского ресурса DatabaseService . Создание DatabaseService CR должно инициировать Reconcile функцию, которая создаст секрет в пространстве имен CR после получения его от третьей стороны.

Я установил CR в качестве владельца секрета, чтобы всякий раз, когда секрет удаляется вручную, функция согласования срабатывала снова и воссоздавала секрет.

Вот код:

 func (r *DatabaseServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    requeueResult := ctrl.Result{Requeue: true, RequeueAfter: time.Minute}
    emptyResult := ctrl.Result{Requeue: false, RequeueAfter: 0}

    ds := amp;operatorsv1alpha1.DatabaseService{}
    if err := r.Client.Get(context.Background(), req.NamespacedName, ds); err != nil {
        if misc.IsNotFound(err) {
            return emptyResult, nil
        })
        return requeueResult, err
    }

    secret, err := getSecretFromThirdParty(ds)
    if err != nil {
        return requeueResult, err
    }

    if err := controllerutil.SetControllerReference(ds, secret, r.Scheme); err != nil {
        logger.Error("failed to set controller reference for the secret", zap.Error(err))
        return requeueResult, err
    }

    if err := r.createOrUpdateSecret(secret, logger); err != nil {
        return requeueResult, err
    }

    return emptyResult, nil
}

func (r *DatabaseServiceReconciler) createOrUpdateSecret(secret *corev1.Secret) error {
    if err := r.createNamespaceIfNotExist(secret.Namespace, logger); err != nil {
        return err
    }
    if err := r.Client.Create(context.TODO(), secret); err == nil {
        return nil
    }
    if !apierrors.IsAlreadyExists(err) {
        return err
    }
    if err := r.Client.Update(context.TODO(), secret); err != nil {
        return err
    }
    return nil
}
 

Я наблюдаю, что, если я назначу CR владельцем секрета перед вызовом createOrUpdateSecret , функция — Согласование будет активирована снова, потому что что-то в принадлежащем объекте (секрете) изменилось.

Моя логика согласования идемпотентна, так что это не большая проблема. Однако мне не нужно Reconcile запускать снова после изменений в принадлежащем объекте, которые произошли изнутри Reconcile . Прямо сейчас, каждый раз, когда согласование создает / обновляет секрет, он будет запускаться снова. Такое поведение кажется немного неуклюжим и приводит к дополнительной работе оператора и дополнительным звонкам третьей стороне.

Есть ли способ обойти повторную активацию создания / обновления принадлежащего объекта изнутри Reconcile ? Или это не рекомендуется, и я должен разрешить повторное выполнение согласования, пока ничего не изменится?