kube_config_info_publisher.go no longer watches cic's with an informer
Simplifies the implementation, makes it more consistent with other updaters of the cic (CredentialIssuerConfig), and also retries on update conflicts Signed-off-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
parent
253d3bb36f
commit
69137fb6b9
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/equality"
|
"k8s.io/apimachinery/pkg/api/equality"
|
||||||
|
|
||||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/util/retry"
|
"k8s.io/client-go/util/retry"
|
||||||
@ -34,36 +35,11 @@ func CreateOrUpdateCredentialIssuerConfig(
|
|||||||
return fmt.Errorf("get failed: %w", err)
|
return fmt.Errorf("get failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return createOrUpdateCredentialIssuerConfig(
|
|
||||||
ctx,
|
|
||||||
existingCredentialIssuerConfig,
|
|
||||||
notFound,
|
|
||||||
credentialIssuerConfigResourceName,
|
|
||||||
credentialIssuerConfigNamespace,
|
|
||||||
pinnipedClient,
|
|
||||||
applyUpdatesToCredentialIssuerConfigFunc)
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not create or update credentialissuerconfig: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createOrUpdateCredentialIssuerConfig(
|
|
||||||
ctx context.Context,
|
|
||||||
existingCredentialIssuerConfig *configv1alpha1.CredentialIssuerConfig,
|
|
||||||
notFound bool,
|
|
||||||
credentialIssuerConfigName string,
|
|
||||||
credentialIssuerConfigNamespace string,
|
|
||||||
pinnipedClient pinnipedclientset.Interface,
|
|
||||||
applyUpdatesToCredentialIssuerConfigFunc func(configToUpdate *configv1alpha1.CredentialIssuerConfig),
|
|
||||||
) error {
|
|
||||||
credentialIssuerConfigsClient := pinnipedClient.ConfigV1alpha1().CredentialIssuerConfigs(credentialIssuerConfigNamespace)
|
credentialIssuerConfigsClient := pinnipedClient.ConfigV1alpha1().CredentialIssuerConfigs(credentialIssuerConfigNamespace)
|
||||||
|
|
||||||
if notFound {
|
if notFound {
|
||||||
// Create it
|
// Create it
|
||||||
credentialIssuerConfig := minimalValidCredentialIssuerConfig(credentialIssuerConfigName, credentialIssuerConfigNamespace)
|
credentialIssuerConfig := minimalValidCredentialIssuerConfig(credentialIssuerConfigResourceName, credentialIssuerConfigNamespace)
|
||||||
applyUpdatesToCredentialIssuerConfigFunc(credentialIssuerConfig)
|
applyUpdatesToCredentialIssuerConfigFunc(credentialIssuerConfig)
|
||||||
|
|
||||||
if _, err := credentialIssuerConfigsClient.Create(ctx, credentialIssuerConfig, metav1.CreateOptions{}); err != nil {
|
if _, err := credentialIssuerConfigsClient.Create(ctx, credentialIssuerConfig, metav1.CreateOptions{}); err != nil {
|
||||||
@ -83,7 +59,12 @@ func createOrUpdateCredentialIssuerConfig(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not create or update credentialissuerconfig: %w", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
|
|
||||||
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
||||||
pinnipedclientset "go.pinniped.dev/generated/1.19/client/clientset/versioned"
|
pinnipedclientset "go.pinniped.dev/generated/1.19/client/clientset/versioned"
|
||||||
configv1alpha1informers "go.pinniped.dev/generated/1.19/client/informers/externalversions/config/v1alpha1"
|
|
||||||
pinnipedcontroller "go.pinniped.dev/internal/controller"
|
pinnipedcontroller "go.pinniped.dev/internal/controller"
|
||||||
"go.pinniped.dev/internal/controllerlib"
|
"go.pinniped.dev/internal/controllerlib"
|
||||||
)
|
)
|
||||||
@ -31,7 +30,6 @@ type kubeConigInfoPublisherController struct {
|
|||||||
serverOverride *string
|
serverOverride *string
|
||||||
pinnipedClient pinnipedclientset.Interface
|
pinnipedClient pinnipedclientset.Interface
|
||||||
configMapInformer corev1informers.ConfigMapInformer
|
configMapInformer corev1informers.ConfigMapInformer
|
||||||
credentialIssuerConfigInformer configv1alpha1informers.CredentialIssuerConfigInformer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKubeConfigInfoPublisherController returns a controller that syncs the
|
// NewKubeConfigInfoPublisherController returns a controller that syncs the
|
||||||
@ -43,7 +41,6 @@ func NewKubeConfigInfoPublisherController(
|
|||||||
serverOverride *string,
|
serverOverride *string,
|
||||||
pinnipedClient pinnipedclientset.Interface,
|
pinnipedClient pinnipedclientset.Interface,
|
||||||
configMapInformer corev1informers.ConfigMapInformer,
|
configMapInformer corev1informers.ConfigMapInformer,
|
||||||
credentialIssuerConfigInformer configv1alpha1informers.CredentialIssuerConfigInformer, // TODO don't have this informer here
|
|
||||||
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
||||||
) controllerlib.Controller {
|
) controllerlib.Controller {
|
||||||
return controllerlib.New(
|
return controllerlib.New(
|
||||||
@ -55,7 +52,6 @@ func NewKubeConfigInfoPublisherController(
|
|||||||
serverOverride: serverOverride,
|
serverOverride: serverOverride,
|
||||||
pinnipedClient: pinnipedClient,
|
pinnipedClient: pinnipedClient,
|
||||||
configMapInformer: configMapInformer,
|
configMapInformer: configMapInformer,
|
||||||
credentialIssuerConfigInformer: credentialIssuerConfigInformer,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
withInformer(
|
withInformer(
|
||||||
@ -63,11 +59,6 @@ func NewKubeConfigInfoPublisherController(
|
|||||||
pinnipedcontroller.NameAndNamespaceExactMatchFilterFactory(clusterInfoName, ClusterInfoNamespace),
|
pinnipedcontroller.NameAndNamespaceExactMatchFilterFactory(clusterInfoName, ClusterInfoNamespace),
|
||||||
controllerlib.InformerOption{},
|
controllerlib.InformerOption{},
|
||||||
),
|
),
|
||||||
withInformer(
|
|
||||||
credentialIssuerConfigInformer,
|
|
||||||
pinnipedcontroller.NameAndNamespaceExactMatchFilterFactory(credentialIssuerConfigResourceName, credentialIssuerConfigNamespaceName),
|
|
||||||
controllerlib.InformerOption{},
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,15 +103,6 @@ func (c *kubeConigInfoPublisherController) Sync(ctx controllerlib.Context) error
|
|||||||
server = *c.serverOverride
|
server = *c.serverOverride
|
||||||
}
|
}
|
||||||
|
|
||||||
existingCredentialIssuerConfigFromInformerCache, err := c.credentialIssuerConfigInformer.
|
|
||||||
Lister().
|
|
||||||
CredentialIssuerConfigs(c.credentialIssuerConfigNamespaceName).
|
|
||||||
Get(c.credentialIssuerConfigResourceName)
|
|
||||||
notFound = k8serrors.IsNotFound(err)
|
|
||||||
if err != nil && !notFound {
|
|
||||||
return fmt.Errorf("could not get credentialissuerconfig: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
updateServerAndCAFunc := func(c *configv1alpha1.CredentialIssuerConfig) {
|
updateServerAndCAFunc := func(c *configv1alpha1.CredentialIssuerConfig) {
|
||||||
c.Status.KubeConfigInfo = &configv1alpha1.CredentialIssuerConfigKubeConfigInfo{
|
c.Status.KubeConfigInfo = &configv1alpha1.CredentialIssuerConfigKubeConfigInfo{
|
||||||
Server: server,
|
Server: server,
|
||||||
@ -128,17 +110,11 @@ func (c *kubeConigInfoPublisherController) Sync(ctx controllerlib.Context) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = createOrUpdateCredentialIssuerConfig(
|
return CreateOrUpdateCredentialIssuerConfig(
|
||||||
ctx.Context,
|
ctx.Context,
|
||||||
existingCredentialIssuerConfigFromInformerCache,
|
|
||||||
notFound,
|
|
||||||
c.credentialIssuerConfigResourceName,
|
|
||||||
c.credentialIssuerConfigNamespaceName,
|
c.credentialIssuerConfigNamespaceName,
|
||||||
|
c.credentialIssuerConfigResourceName,
|
||||||
c.pinnipedClient,
|
c.pinnipedClient,
|
||||||
updateServerAndCAFunc)
|
updateServerAndCAFunc,
|
||||||
|
)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not create or update credentialissuerconfig: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import (
|
|||||||
|
|
||||||
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
||||||
pinnipedfake "go.pinniped.dev/generated/1.19/client/clientset/versioned/fake"
|
pinnipedfake "go.pinniped.dev/generated/1.19/client/clientset/versioned/fake"
|
||||||
pinnipedinformers "go.pinniped.dev/generated/1.19/client/informers/externalversions"
|
|
||||||
"go.pinniped.dev/internal/controllerlib"
|
"go.pinniped.dev/internal/controllerlib"
|
||||||
"go.pinniped.dev/internal/here"
|
"go.pinniped.dev/internal/here"
|
||||||
"go.pinniped.dev/internal/testutil"
|
"go.pinniped.dev/internal/testutil"
|
||||||
@ -36,24 +35,20 @@ func TestInformerFilters(t *testing.T) {
|
|||||||
var r *require.Assertions
|
var r *require.Assertions
|
||||||
var observableWithInformerOption *testutil.ObservableWithInformerOption
|
var observableWithInformerOption *testutil.ObservableWithInformerOption
|
||||||
var configMapInformerFilter controllerlib.Filter
|
var configMapInformerFilter controllerlib.Filter
|
||||||
var credentialIssuerConfigInformerFilter controllerlib.Filter
|
|
||||||
|
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
r = require.New(t)
|
r = require.New(t)
|
||||||
observableWithInformerOption = testutil.NewObservableWithInformerOption()
|
observableWithInformerOption = testutil.NewObservableWithInformerOption()
|
||||||
configMapInformer := kubeinformers.NewSharedInformerFactory(nil, 0).Core().V1().ConfigMaps()
|
configMapInformer := kubeinformers.NewSharedInformerFactory(nil, 0).Core().V1().ConfigMaps()
|
||||||
credentialIssuerConfigInformer := pinnipedinformers.NewSharedInformerFactory(nil, 0).Config().V1alpha1().CredentialIssuerConfigs()
|
|
||||||
_ = NewKubeConfigInfoPublisherController(
|
_ = NewKubeConfigInfoPublisherController(
|
||||||
installedInNamespace,
|
installedInNamespace,
|
||||||
credentialIssuerConfigResourceName,
|
credentialIssuerConfigResourceName,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
configMapInformer,
|
configMapInformer,
|
||||||
credentialIssuerConfigInformer,
|
|
||||||
observableWithInformerOption.WithInformer, // make it possible to observe the behavior of the Filters
|
observableWithInformerOption.WithInformer, // make it possible to observe the behavior of the Filters
|
||||||
)
|
)
|
||||||
configMapInformerFilter = observableWithInformerOption.GetFilterForInformer(configMapInformer)
|
configMapInformerFilter = observableWithInformerOption.GetFilterForInformer(configMapInformer)
|
||||||
credentialIssuerConfigInformerFilter = observableWithInformerOption.GetFilterForInformer(credentialIssuerConfigInformer)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
when("watching ConfigMap objects", func() {
|
when("watching ConfigMap objects", func() {
|
||||||
@ -103,62 +98,6 @@ func TestInformerFilters(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
when("watching CredentialIssuerConfig objects", func() {
|
|
||||||
var subject controllerlib.Filter
|
|
||||||
var target, wrongNamespace, wrongName, unrelated *configv1alpha1.CredentialIssuerConfig
|
|
||||||
|
|
||||||
it.Before(func() {
|
|
||||||
subject = credentialIssuerConfigInformerFilter
|
|
||||||
target = &configv1alpha1.CredentialIssuerConfig{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: credentialIssuerConfigResourceName, Namespace: installedInNamespace},
|
|
||||||
}
|
|
||||||
wrongNamespace = &configv1alpha1.CredentialIssuerConfig{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: credentialIssuerConfigResourceName, Namespace: "wrong-namespace"},
|
|
||||||
}
|
|
||||||
wrongName = &configv1alpha1.CredentialIssuerConfig{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "wrong-name", Namespace: installedInNamespace},
|
|
||||||
}
|
|
||||||
unrelated = &configv1alpha1.CredentialIssuerConfig{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "wrong-name", Namespace: "wrong-namespace"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
when("the target CredentialIssuerConfig changes", func() {
|
|
||||||
it("returns true to trigger the sync method", func() {
|
|
||||||
r.True(subject.Add(target))
|
|
||||||
r.True(subject.Update(target, unrelated))
|
|
||||||
r.True(subject.Update(unrelated, target))
|
|
||||||
r.True(subject.Delete(target))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
when("a CredentialIssuerConfig from another namespace changes", func() {
|
|
||||||
it("returns false to avoid triggering the sync method", func() {
|
|
||||||
r.False(subject.Add(wrongNamespace))
|
|
||||||
r.False(subject.Update(wrongNamespace, unrelated))
|
|
||||||
r.False(subject.Update(unrelated, wrongNamespace))
|
|
||||||
r.False(subject.Delete(wrongNamespace))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
when("a CredentialIssuerConfig with a different name changes", func() {
|
|
||||||
it("returns false to avoid triggering the sync method", func() {
|
|
||||||
r.False(subject.Add(wrongName))
|
|
||||||
r.False(subject.Update(wrongName, unrelated))
|
|
||||||
r.False(subject.Update(unrelated, wrongName))
|
|
||||||
r.False(subject.Delete(wrongName))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
when("a CredentialIssuerConfig with a different name and a different namespace changes", func() {
|
|
||||||
it("returns false to avoid triggering the sync method", func() {
|
|
||||||
r.False(subject.Add(unrelated))
|
|
||||||
r.False(subject.Update(unrelated, unrelated))
|
|
||||||
r.False(subject.Delete(unrelated))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}, spec.Parallel(), spec.Report(report.Terminal{}))
|
}, spec.Parallel(), spec.Report(report.Terminal{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,9 +111,7 @@ func TestSync(t *testing.T) {
|
|||||||
var subject controllerlib.Controller
|
var subject controllerlib.Controller
|
||||||
var serverOverride *string
|
var serverOverride *string
|
||||||
var kubeInformerClient *kubernetesfake.Clientset
|
var kubeInformerClient *kubernetesfake.Clientset
|
||||||
var pinnipedInformerClient *pinnipedfake.Clientset
|
|
||||||
var kubeInformers kubeinformers.SharedInformerFactory
|
var kubeInformers kubeinformers.SharedInformerFactory
|
||||||
var pinnipedInformers pinnipedinformers.SharedInformerFactory
|
|
||||||
var pinnipedAPIClient *pinnipedfake.Clientset
|
var pinnipedAPIClient *pinnipedfake.Clientset
|
||||||
var timeoutContext context.Context
|
var timeoutContext context.Context
|
||||||
var timeoutContextCancel context.CancelFunc
|
var timeoutContextCancel context.CancelFunc
|
||||||
@ -212,7 +149,6 @@ func TestSync(t *testing.T) {
|
|||||||
serverOverride,
|
serverOverride,
|
||||||
pinnipedAPIClient,
|
pinnipedAPIClient,
|
||||||
kubeInformers.Core().V1().ConfigMaps(),
|
kubeInformers.Core().V1().ConfigMaps(),
|
||||||
pinnipedInformers.Config().V1alpha1().CredentialIssuerConfigs(),
|
|
||||||
controllerlib.WithInformer,
|
controllerlib.WithInformer,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -228,7 +164,6 @@ func TestSync(t *testing.T) {
|
|||||||
|
|
||||||
// Must start informers before calling TestRunSynchronously()
|
// Must start informers before calling TestRunSynchronously()
|
||||||
kubeInformers.Start(timeoutContext.Done())
|
kubeInformers.Start(timeoutContext.Done())
|
||||||
pinnipedInformers.Start(timeoutContext.Done())
|
|
||||||
controllerlib.TestRunSynchronously(t, subject)
|
controllerlib.TestRunSynchronously(t, subject)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,8 +175,6 @@ func TestSync(t *testing.T) {
|
|||||||
kubeInformerClient = kubernetesfake.NewSimpleClientset()
|
kubeInformerClient = kubernetesfake.NewSimpleClientset()
|
||||||
kubeInformers = kubeinformers.NewSharedInformerFactory(kubeInformerClient, 0)
|
kubeInformers = kubeinformers.NewSharedInformerFactory(kubeInformerClient, 0)
|
||||||
pinnipedAPIClient = pinnipedfake.NewSimpleClientset()
|
pinnipedAPIClient = pinnipedfake.NewSimpleClientset()
|
||||||
pinnipedInformerClient = pinnipedfake.NewSimpleClientset()
|
|
||||||
pinnipedInformers = pinnipedinformers.NewSharedInformerFactory(pinnipedInformerClient, 0)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it.After(func() {
|
it.After(func() {
|
||||||
@ -288,6 +221,7 @@ func TestSync(t *testing.T) {
|
|||||||
|
|
||||||
r.Equal(
|
r.Equal(
|
||||||
[]coretesting.Action{
|
[]coretesting.Action{
|
||||||
|
coretesting.NewGetAction(expectedCredentialIssuerConfigGVR, installedInNamespace, expectedCredentialIssuerConfig.Name),
|
||||||
coretesting.NewCreateAction(
|
coretesting.NewCreateAction(
|
||||||
expectedCredentialIssuerConfigGVR,
|
expectedCredentialIssuerConfigGVR,
|
||||||
installedInNamespace,
|
installedInNamespace,
|
||||||
@ -334,6 +268,7 @@ func TestSync(t *testing.T) {
|
|||||||
|
|
||||||
r.Equal(
|
r.Equal(
|
||||||
[]coretesting.Action{
|
[]coretesting.Action{
|
||||||
|
coretesting.NewGetAction(expectedCredentialIssuerConfigGVR, installedInNamespace, expectedCredentialIssuerConfig.Name),
|
||||||
coretesting.NewCreateAction(
|
coretesting.NewCreateAction(
|
||||||
expectedCredentialIssuerConfigGVR,
|
expectedCredentialIssuerConfigGVR,
|
||||||
installedInNamespace,
|
installedInNamespace,
|
||||||
@ -348,13 +283,16 @@ func TestSync(t *testing.T) {
|
|||||||
|
|
||||||
when("the CredentialIssuerConfig already exists", func() {
|
when("the CredentialIssuerConfig already exists", func() {
|
||||||
when("the CredentialIssuerConfig is already up to date according to the data in the ConfigMap", func() {
|
when("the CredentialIssuerConfig is already up to date according to the data in the ConfigMap", func() {
|
||||||
|
var credentialIssuerConfigGVR schema.GroupVersionResource
|
||||||
|
var credentialIssuerConfig *configv1alpha1.CredentialIssuerConfig
|
||||||
|
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
_, expectedCredentialIssuerConfig := expectedCredentialIssuerConfig(
|
credentialIssuerConfigGVR, credentialIssuerConfig = expectedCredentialIssuerConfig(
|
||||||
installedInNamespace,
|
installedInNamespace,
|
||||||
kubeServerURL,
|
kubeServerURL,
|
||||||
caData,
|
caData,
|
||||||
)
|
)
|
||||||
err := pinnipedInformerClient.Tracker().Add(expectedCredentialIssuerConfig)
|
err := pinnipedAPIClient.Tracker().Add(credentialIssuerConfig)
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -363,7 +301,12 @@ func TestSync(t *testing.T) {
|
|||||||
err := controllerlib.TestSync(t, subject, *syncContext)
|
err := controllerlib.TestSync(t, subject, *syncContext)
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
|
||||||
r.Empty(pinnipedAPIClient.Actions())
|
r.Equal(
|
||||||
|
[]coretesting.Action{
|
||||||
|
coretesting.NewGetAction(credentialIssuerConfigGVR, installedInNamespace, credentialIssuerConfig.Name),
|
||||||
|
},
|
||||||
|
pinnipedAPIClient.Actions(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -375,7 +318,6 @@ func TestSync(t *testing.T) {
|
|||||||
caData,
|
caData,
|
||||||
)
|
)
|
||||||
expectedCredentialIssuerConfig.Status.KubeConfigInfo.Server = "https://some-other-server"
|
expectedCredentialIssuerConfig.Status.KubeConfigInfo.Server = "https://some-other-server"
|
||||||
r.NoError(pinnipedInformerClient.Tracker().Add(expectedCredentialIssuerConfig))
|
|
||||||
r.NoError(pinnipedAPIClient.Tracker().Add(expectedCredentialIssuerConfig))
|
r.NoError(pinnipedAPIClient.Tracker().Add(expectedCredentialIssuerConfig))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -390,6 +332,7 @@ func TestSync(t *testing.T) {
|
|||||||
caData,
|
caData,
|
||||||
)
|
)
|
||||||
expectedActions := []coretesting.Action{
|
expectedActions := []coretesting.Action{
|
||||||
|
coretesting.NewGetAction(expectedCredentialIssuerConfigGVR, installedInNamespace, expectedCredentialIssuerConfig.Name),
|
||||||
coretesting.NewUpdateAction(
|
coretesting.NewUpdateAction(
|
||||||
expectedCredentialIssuerConfigGVR,
|
expectedCredentialIssuerConfigGVR,
|
||||||
installedInNamespace,
|
installedInNamespace,
|
||||||
|
@ -114,7 +114,6 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
|
|||||||
c.DiscoveryURLOverride,
|
c.DiscoveryURLOverride,
|
||||||
pinnipedClient,
|
pinnipedClient,
|
||||||
informers.kubePublicNamespaceK8s.Core().V1().ConfigMaps(),
|
informers.kubePublicNamespaceK8s.Core().V1().ConfigMaps(),
|
||||||
informers.installationNamespacePinniped.Config().V1alpha1().CredentialIssuerConfigs(),
|
|
||||||
controllerlib.WithInformer,
|
controllerlib.WithInformer,
|
||||||
),
|
),
|
||||||
singletonWorker,
|
singletonWorker,
|
||||||
|
@ -9,10 +9,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/rest"
|
|
||||||
|
|
||||||
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/config/v1alpha1"
|
||||||
"go.pinniped.dev/test/library"
|
"go.pinniped.dev/test/library"
|
||||||
@ -50,7 +48,14 @@ func TestCredentialIssuerConfig(t *testing.T) {
|
|||||||
require.Equal(t, configv1alpha1.FetchedKeyStrategyReason, actualStatusStrategy.Reason)
|
require.Equal(t, configv1alpha1.FetchedKeyStrategyReason, actualStatusStrategy.Reason)
|
||||||
require.Equal(t, "Key was fetched successfully", actualStatusStrategy.Message)
|
require.Equal(t, "Key was fetched successfully", actualStatusStrategy.Message)
|
||||||
// Verify the published kube config info.
|
// Verify the published kube config info.
|
||||||
require.Equal(t, expectedStatusKubeConfigInfo(config), actualStatusKubeConfigInfo)
|
require.Equal(
|
||||||
|
t,
|
||||||
|
&configv1alpha1.CredentialIssuerConfigKubeConfigInfo{
|
||||||
|
Server: config.Host,
|
||||||
|
CertificateAuthorityData: base64.StdEncoding.EncodeToString(config.TLSClientConfig.CAData),
|
||||||
|
},
|
||||||
|
actualStatusKubeConfigInfo,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
require.Equal(t, configv1alpha1.ErrorStrategyStatus, actualStatusStrategy.Status)
|
require.Equal(t, configv1alpha1.ErrorStrategyStatus, actualStatusStrategy.Status)
|
||||||
require.Equal(t, configv1alpha1.CouldNotFetchKeyStrategyReason, actualStatusStrategy.Reason)
|
require.Equal(t, configv1alpha1.CouldNotFetchKeyStrategyReason, actualStatusStrategy.Reason)
|
||||||
@ -63,53 +68,4 @@ func TestCredentialIssuerConfig(t *testing.T) {
|
|||||||
|
|
||||||
require.WithinDuration(t, time.Now(), actualStatusStrategy.LastUpdateTime.Local(), 10*time.Minute)
|
require.WithinDuration(t, time.Now(), actualStatusStrategy.LastUpdateTime.Local(), 10*time.Minute)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("reconciling CredentialIssuerConfig", func(t *testing.T) {
|
|
||||||
library.SkipUnlessClusterHasCapability(t, library.ClusterSigningKeyIsAvailable)
|
|
||||||
|
|
||||||
existingConfig, err := client.
|
|
||||||
ConfigV1alpha1().
|
|
||||||
CredentialIssuerConfigs(namespaceName).
|
|
||||||
Get(ctx, "pinniped-config", metav1.GetOptions{})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Len(t, existingConfig.Status.Strategies, 1)
|
|
||||||
initialStrategy := existingConfig.Status.Strategies[0]
|
|
||||||
|
|
||||||
// Mutate the existing object. Don't delete it because that would mess up its `Status.Strategies` array,
|
|
||||||
// since the reconciling controller is not currently responsible for that field.
|
|
||||||
updatedServerValue := "https://junk"
|
|
||||||
// TODO maybe mutate the kube-info configmap's CA value instead, because that's the object that we care to check that the controller is watching
|
|
||||||
existingConfig.Status.KubeConfigInfo.Server = updatedServerValue
|
|
||||||
updatedConfig, err := client.
|
|
||||||
ConfigV1alpha1().
|
|
||||||
CredentialIssuerConfigs(namespaceName).
|
|
||||||
Update(ctx, existingConfig, metav1.UpdateOptions{})
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, updatedServerValue, updatedConfig.Status.KubeConfigInfo.Server)
|
|
||||||
|
|
||||||
// Expect that the object's mutated field is set back to what matches its source of truth by the controller.
|
|
||||||
var actualCredentialIssuerConfig *configv1alpha1.CredentialIssuerConfig
|
|
||||||
var configChangesServerField = func() bool {
|
|
||||||
actualCredentialIssuerConfig, err = client.
|
|
||||||
ConfigV1alpha1().
|
|
||||||
CredentialIssuerConfigs(namespaceName).
|
|
||||||
Get(ctx, "pinniped-config", metav1.GetOptions{})
|
|
||||||
return err == nil && actualCredentialIssuerConfig.Status.KubeConfigInfo.Server != updatedServerValue
|
|
||||||
}
|
|
||||||
assert.Eventually(t, configChangesServerField, 10*time.Second, 100*time.Millisecond)
|
|
||||||
require.NoError(t, err) // prints out the error and stops the test in case of failure
|
|
||||||
actualStatusKubeConfigInfo := actualCredentialIssuerConfig.Status.KubeConfigInfo
|
|
||||||
require.Equal(t, expectedStatusKubeConfigInfo(config), actualStatusKubeConfigInfo)
|
|
||||||
|
|
||||||
// The strategies should not have changed during reconciliation.
|
|
||||||
require.Len(t, actualCredentialIssuerConfig.Status.Strategies, 1)
|
|
||||||
require.Equal(t, initialStrategy, actualCredentialIssuerConfig.Status.Strategies[0])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func expectedStatusKubeConfigInfo(config *rest.Config) *configv1alpha1.CredentialIssuerConfigKubeConfigInfo {
|
|
||||||
return &configv1alpha1.CredentialIssuerConfigKubeConfigInfo{
|
|
||||||
Server: config.Host,
|
|
||||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString(config.TLSClientConfig.CAData),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user