019f44982c
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
113 lines
3.1 KiB
Go
113 lines
3.1 KiB
Go
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package supervisorconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
|
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/klog/v2"
|
|
|
|
configinformers "go.pinniped.dev/generated/1.19/client/informers/externalversions/config/v1alpha1"
|
|
pinnipedcontroller "go.pinniped.dev/internal/controller"
|
|
"go.pinniped.dev/internal/controllerlib"
|
|
)
|
|
|
|
const (
|
|
issuerConfigMapKey = "issuer"
|
|
)
|
|
|
|
// IssuerSetter can be notified of a valid issuer with its SetIssuer function. If there is no
|
|
// longer any valid issuer, then nil can be passed to this interface.
|
|
//
|
|
// If the IssuerSetter doesn't like the provided issuer, it can return an error.
|
|
//
|
|
// Implementations of this type should be thread-safe to support calls from multiple goroutines.
|
|
type IssuerSetter interface {
|
|
SetIssuer(issuer *url.URL) error
|
|
}
|
|
|
|
type dynamicConfigWatcherController struct {
|
|
issuerSetter IssuerSetter
|
|
opcInformer configinformers.OIDCProviderConfigInformer
|
|
}
|
|
|
|
// NewDynamicConfigWatcherController creates a controllerlib.Controller that watches
|
|
// OIDCProviderConfig objects and notifies a callback object of their creation or deletion.
|
|
func NewDynamicConfigWatcherController(
|
|
issuerObserver IssuerSetter,
|
|
opcInformer configinformers.OIDCProviderConfigInformer,
|
|
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
|
) controllerlib.Controller {
|
|
return controllerlib.New(
|
|
controllerlib.Config{
|
|
Name: "DynamicConfigWatcherController",
|
|
Syncer: &dynamicConfigWatcherController{
|
|
issuerSetter: issuerObserver,
|
|
opcInformer: opcInformer,
|
|
},
|
|
},
|
|
withInformer(
|
|
opcInformer,
|
|
pinnipedcontroller.NoOpFilter(),
|
|
controllerlib.InformerOption{},
|
|
),
|
|
)
|
|
}
|
|
|
|
// Sync implements controllerlib.Syncer.
|
|
func (c *dynamicConfigWatcherController) Sync(ctx controllerlib.Context) error {
|
|
// TODO Watch the configmap to find the issuer name, ingress url, etc.
|
|
// TODO Update some kind of in-memory representation of the configuration so the discovery endpoint can use it.
|
|
// TODO The discovery endpoint would return an error until all missing configuration options are
|
|
// filled in.
|
|
|
|
opc, err := c.opcInformer.
|
|
Lister().
|
|
OIDCProviderConfigs(ctx.Key.Namespace).
|
|
Get(ctx.Key.Name)
|
|
notFound := k8serrors.IsNotFound(err)
|
|
if err != nil && !notFound {
|
|
return fmt.Errorf("failed to get %s/%s oidcproviderconfig: %w", ctx.Key.Namespace, ctx.Key.Name, err)
|
|
}
|
|
|
|
if notFound {
|
|
klog.InfoS(
|
|
"dynamicConfigWatcherController Sync found no oidcproviderconfig",
|
|
"oidcproviderconfig",
|
|
klog.KRef(ctx.Key.Namespace, ctx.Key.Name),
|
|
)
|
|
c.issuerSetter.SetIssuer(nil)
|
|
return nil
|
|
}
|
|
|
|
url, err := url.Parse(opc.Spec.Issuer)
|
|
if err != nil {
|
|
klog.InfoS(
|
|
"dynamicConfigWatcherController Sync failed to parse issuer",
|
|
"err",
|
|
err,
|
|
)
|
|
return nil
|
|
}
|
|
|
|
klog.InfoS(
|
|
"dynamicConfigWatcherController Sync issuer",
|
|
"oidcproviderconfig",
|
|
klog.KObj(opc),
|
|
"issuer",
|
|
url,
|
|
)
|
|
if err := c.issuerSetter.SetIssuer(url); err != nil {
|
|
klog.InfoS(
|
|
"dynamicConfigWatcherController Sync failed to set issuer",
|
|
"err",
|
|
err,
|
|
)
|
|
}
|
|
|
|
return nil
|
|
}
|