Monis Khan 7e21b9b78d
apicerts: return error on missing pre-requirements
This change updates the apicerts controllers to return an error when
they cannot successfully complete their Sync func.  i.e. `return nil`
is reserved for cases where the controller has fully completed its
job with no errors.  This makes it clear when a controller has
wedged - i.e. it is waiting on some other controller or process to
perform some action before it can complete.  The controller lib's
queue will exponentially back off and thus there is no need to be
concerned with returning an error indefinitely or infinite log spam.
Even when the kubelet throws away container logs, it will be clear
what controllers are wedged based on the last hour or so of logs.

Signed-off-by: Monis Khan <mok@vmware.com>
2020-10-16 14:47:03 -04:00

71 lines
2.4 KiB
Go

// Copyright 2020 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package apicerts
import (
"fmt"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/klog/v2"
pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/dynamiccert"
)
type certsObserverController struct {
namespace string
certsSecretResourceName string
dynamicCertProvider dynamiccert.Provider
secretInformer corev1informers.SecretInformer
}
func NewCertsObserverController(
namespace string,
certsSecretResourceName string,
dynamicCertProvider dynamiccert.Provider,
secretInformer corev1informers.SecretInformer,
withInformer pinnipedcontroller.WithInformerOptionFunc,
) controllerlib.Controller {
return controllerlib.New(
controllerlib.Config{
Name: "certs-observer-controller",
Syncer: &certsObserverController{
namespace: namespace,
certsSecretResourceName: certsSecretResourceName,
dynamicCertProvider: dynamicCertProvider,
secretInformer: secretInformer,
},
},
withInformer(
secretInformer,
pinnipedcontroller.NameAndNamespaceExactMatchFilterFactory(certsSecretResourceName, namespace),
controllerlib.InformerOption{},
),
)
}
func (c *certsObserverController) Sync(_ controllerlib.Context) error {
// Try to get the secret from the informer cache.
certSecret, err := c.secretInformer.Lister().Secrets(c.namespace).Get(c.certsSecretResourceName)
notFound := k8serrors.IsNotFound(err)
if err != nil && !notFound {
return fmt.Errorf("failed to get %s/%s secret: %w", c.namespace, c.certsSecretResourceName, err)
}
if notFound {
klog.Info("certsObserverController Sync found that the secret does not exist yet or was deleted")
// The secret does not exist yet or was deleted.
c.dynamicCertProvider.Set(nil, nil)
//nolint: goerr113
return fmt.Errorf("certsObserverController missing pre-requirements, secret %s/%s does not exist: %w",
c.namespace, c.certsSecretResourceName, controllerlib.ErrSyntheticRequeue)
}
// Mutate the in-memory cert provider to update with the latest cert values.
c.dynamicCertProvider.Set(certSecret.Data[tlsCertificateChainSecretKey], certSecret.Data[tlsPrivateKeySecretKey])
klog.Info("certsObserverController Sync updated certs in the dynamic cert provider")
return nil
}