func()

in pkg/controller/keyvault/nginx_secret_provider_class.go [57:152]


func (i *NginxSecretProviderClassReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) {
	// do metrics
	defer func() {
		//placing this call inside a closure allows for result and err to be bound after Reconcile executes
		//this makes sure they have the proper value
		//just calling defer metrics.HandleControllerReconcileMetrics(controllerName, result, err) would bind
		//the values of result and err to their zero values, since they were just instantiated
		metrics.HandleControllerReconcileMetrics(nginxSecretProviderControllerName, result, retErr)
	}()

	logger, err := logr.FromContext(ctx)
	if err != nil {
		return ctrl.Result{}, fmt.Errorf("initializing logger: %w", err)
	}
	logger = nginxSecretProviderControllerName.AddToLogger(logger).WithValues("name", req.Name, "namespace", req.Namespace)

	logger.Info("getting Nginx Ingress")
	nic := &approutingv1alpha1.NginxIngressController{}
	err = i.client.Get(ctx, req.NamespacedName, nic)
	if err != nil {
		return ctrl.Result{}, client.IgnoreNotFound(err)
	}
	logger = logger.WithValues("name", nic.Name, "generation", nic.Generation)

	spc := &secv1.SecretProviderClass{
		TypeMeta: metav1.TypeMeta{
			APIVersion: "secrets-store.csi.x-k8s.io/v1",
			Kind:       "SecretProviderClass",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      DefaultNginxCertName(nic),
			Namespace: i.config.NS,
			Labels:    manifests.GetTopLevelLabels(),
			OwnerReferences: []metav1.OwnerReference{{
				APIVersion: nic.APIVersion,
				Controller: util.ToPtr(true),
				Kind:       nic.Kind,
				Name:       nic.Name,
				UID:        nic.UID,
			}},
		},
	}
	logger = logger.WithValues("spc", spc.Name)
	logger.Info("building spc and upserting if managed with labels")

	if shouldDeploySpc(nic) {
		spcConf := spcConfig{
			ClientId:        i.config.MSIClientID,
			TenantId:        i.config.TenantID,
			KeyvaultCertUri: *nic.Spec.DefaultSSLCertificate.KeyVaultURI,
			Name:            DefaultNginxCertName(nic),
			Cloud:           i.config.Cloud,
		}
		err = buildSPC(spc, spcConf)
		if err != nil {
			var userErr util.UserError
			if errors.As(err, &userErr) {
				logger.Info(fmt.Sprintf("failed to build secret provider class for nginx ingress controller with error: %s. sending warning event", userErr.Error()))
				i.events.Eventf(nic, corev1.EventTypeWarning, "InvalidInput", "error while processing Keyvault reference: %s", userErr.UserError())
				return ctrl.Result{}, nil
			}

			logger.Error(err, fmt.Sprintf("failed to build secret provider class for nginx ingress controller with error: %s.", err.Error()))
			return ctrl.Result{}, err
		}

		logger.Info("reconciling secret provider class for ingress")
		err = util.Upsert(ctx, i.client, spc)
		if err != nil {
			i.events.Eventf(nic, corev1.EventTypeWarning, "FailedUpdateOrCreateSPC", "error while creating or updating SecretProviderClass needed to pull Keyvault reference: %s", err.Error())
			logger.Error(err, fmt.Sprintf("failed to upsert secret provider class for nginx ingress class with error: %s.", err.Error()))
		}
		return ctrl.Result{}, err
	}

	logger.Info("spc is either not managed or key vault uri was removed")
	logger.Info("getting and cleaning unused spc if ingress is managed")

	toCleanSPC := &secv1.SecretProviderClass{}

	err = i.client.Get(ctx, client.ObjectKeyFromObject(spc), toCleanSPC)
	if err != nil {
		logger.Error(err, "failed to fetch existing spc")
		return ctrl.Result{}, client.IgnoreNotFound(err)
	}

	if manifests.HasTopLevelLabels(toCleanSPC.Labels) {
		logger.Info("removing secret provider class for ingress")
		err = i.client.Delete(ctx, toCleanSPC)
		return ctrl.Result{}, client.IgnoreNotFound(err)
	} else {
		logger.Info("spc was not managed so spc was not removed")
	}

	return ctrl.Result{}, nil
}