Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 30 additions & 34 deletions cmd/machine-config-controller/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"fmt"
"os"

features "github.com/openshift/api/features"
mcfginformersv1 "github.com/openshift/client-go/machineconfiguration/informers/externalversions/machineconfiguration/v1"
"github.com/openshift/machine-config-operator/cmd/common"
"github.com/openshift/machine-config-operator/internal/clients"
bootimagecontroller "github.com/openshift/machine-config-operator/pkg/controller/bootimage"
Expand All @@ -24,7 +22,6 @@ import (
"github.com/openshift/machine-config-operator/pkg/version"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
coreinformersv1 "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/tools/leaderelection"
"k8s.io/klog/v2"
)
Expand Down Expand Up @@ -136,25 +133,23 @@ func runStartCmd(_ *cobra.Command, _ []string) {

close(ctrlctx.InformersStarted)

if ctrlctx.FeatureGatesHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
iriController := internalreleaseimage.New(
ctrlctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages(),
ctrlctx.InformerFactory.Machineconfiguration().V1().ControllerConfigs(),
ctrlctx.InformerFactory.Machineconfiguration().V1().MachineConfigs(),
ctrlctx.ConfigInformerFactory.Config().V1().ClusterVersions(),
ctrlctx.KubeInformerFactory.Core().V1().Secrets(),
ctrlctx.InformerFactory.Machineconfiguration().V1().MachineConfigNodes(),
ctrlctx.KubeInformerFactory.Core().V1().Nodes(),
ctrlctx.ConfigInformerFactory.Config().V1().Infrastructures(),
ctrlctx.ClientBuilder.KubeClientOrDie("internalreleaseimage-controller"),
ctrlctx.ClientBuilder.MachineConfigClientOrDie("internalreleaseimage-controller"))
iriController := internalreleaseimage.New(
ctrlctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages(),
ctrlctx.InformerFactory.Machineconfiguration().V1().ControllerConfigs(),
ctrlctx.InformerFactory.Machineconfiguration().V1().MachineConfigs(),
ctrlctx.ConfigInformerFactory.Config().V1().ClusterVersions(),
ctrlctx.KubeInformerFactory.Core().V1().Secrets(),
ctrlctx.InformerFactory.Machineconfiguration().V1().MachineConfigNodes(),
ctrlctx.KubeInformerFactory.Core().V1().Nodes(),
ctrlctx.ConfigInformerFactory.Config().V1().Infrastructures(),
ctrlctx.ClientBuilder.KubeClientOrDie("internalreleaseimage-controller"),
ctrlctx.ClientBuilder.MachineConfigClientOrDie("internalreleaseimage-controller"))

go iriController.Run(2, ctrlctx.Stop)
// start the informers again to enable feature gated types.
// see comments in SharedInformerFactory interface.
ctrlctx.InformerFactory.Start(ctrlctx.Stop)
ctrlctx.KubeInformerFactory.Start(ctrlctx.Stop)
}
go iriController.Run(2, ctrlctx.Stop)
// start the informers again to enable feature gated types.
// see comments in SharedInformerFactory interface.
ctrlctx.InformerFactory.Start(ctrlctx.Stop)
ctrlctx.KubeInformerFactory.Start(ctrlctx.Stop)

if ctrlcommon.IsBootImageControllerRequired(ctrlctx) {
bootImageController := bootimagecontroller.New(
Expand Down Expand Up @@ -208,16 +203,6 @@ func runStartCmd(_ *cobra.Command, _ []string) {
}

func createControllers(ctx *ctrlcommon.ControllerContext) []ctrlcommon.Controller {
// Only watch IRI informers when the feature gate is enabled. The
// InternalReleaseImages CRD is not installed on clusters where the gate is
// off, so the informer list call would fail and WaitForCacheSync in the
// template controller would block forever.
var iriSecretsInformer coreinformersv1.SecretInformer
var iriInformer mcfginformersv1.InternalReleaseImageInformer
if ctx.FeatureGatesHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
iriSecretsInformer = ctx.KubeInformerFactory.Core().V1().Secrets()
iriInformer = ctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages()
}

var controllers []ctrlcommon.Controller
controllers = append(controllers,
Expand All @@ -226,12 +211,11 @@ func createControllers(ctx *ctrlcommon.ControllerContext) []ctrlcommon.Controlle
rootOpts.templates,
ctx.InformerFactory.Machineconfiguration().V1().ControllerConfigs(),
ctx.OpenShiftConfigKubeNamespacedInformerFactory.Core().V1().Secrets(),
iriSecretsInformer,
iriInformer,
ctx.KubeInformerFactory.Core().V1().Secrets(),
ctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages(),
ctx.ConfigInformerFactory.Config().V1().APIServers(),
ctx.ClientBuilder.KubeClientOrDie("template-controller"),
ctx.ClientBuilder.MachineConfigClientOrDie("template-controller"),
ctx.FeatureGatesHandler,
),
// Add all "sub-renderers here"
kubeletconfig.New(
Expand Down Expand Up @@ -295,6 +279,18 @@ func createControllers(ctx *ctrlcommon.ControllerContext) []ctrlcommon.Controlle
ctx.ClientBuilder.MachineConfigClientOrDie("node-update-controller"),
ctx.FeatureGatesHandler,
),
internalreleaseimage.New(
ctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages(),
ctx.InformerFactory.Machineconfiguration().V1().ControllerConfigs(),
ctx.InformerFactory.Machineconfiguration().V1().MachineConfigs(),
ctx.ConfigInformerFactory.Config().V1().ClusterVersions(),
ctx.KubeInformerFactory.Core().V1().Secrets(),
ctx.InformerFactory.Machineconfiguration().V1().MachineConfigNodes(),
ctx.KubeInformerFactory.Core().V1().Nodes(),
ctx.ConfigInformerFactory.Config().V1().Infrastructures(),
ctx.ClientBuilder.KubeClientOrDie("internalreleaseimage-controller"),
ctx.ClientBuilder.MachineConfigClientOrDie("internalreleaseimage-controller"),
),
)

return controllers
Expand Down
17 changes: 7 additions & 10 deletions cmd/machine-config-daemon/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/client-go/tools/clientcmd"

"github.com/openshift/api/features"
"github.com/openshift/machine-config-operator/internal/clients"
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
"github.com/openshift/machine-config-operator/pkg/daemon"
Expand Down Expand Up @@ -236,15 +235,13 @@ func runStartCmd(_ *cobra.Command, _ []string) {
)
go pinnedImageSetManager.Run(2, stopCh)

if ctrlctx.FeatureGatesHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
internalReleaseImageManager := internalreleaseimage.New(
startOpts.nodeName,
ctrlctx.ClientBuilder.MachineConfigClientOrDie(componentName),
ctrlctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages(),
ctrlctx.InformerFactory.Machineconfiguration().V1().MachineConfigNodes(),
)
go internalReleaseImageManager.Run(1, stopCh)
}
internalReleaseImageManager := internalreleaseimage.New(
startOpts.nodeName,
ctrlctx.ClientBuilder.MachineConfigClientOrDie(componentName),
ctrlctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages(),
ctrlctx.InformerFactory.Machineconfiguration().V1().MachineConfigNodes(),
)
go internalReleaseImageManager.Run(1, stopCh)

ctrlctx.KubeInformerFactory.Start(stopCh)
ctrlctx.KubeNamespacedInformerFactory.Start(stopCh)
Expand Down
10 changes: 1 addition & 9 deletions cmd/machine-config-operator/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"os"

features "github.com/openshift/api/features"
"github.com/openshift/machine-config-operator/cmd/common"
"github.com/openshift/machine-config-operator/internal/clients"
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
Expand Down Expand Up @@ -67,13 +66,6 @@ func runStartCmd(_ *cobra.Command, _ []string) {
klog.Fatal(fmt.Errorf("failed to connect to feature gates %w", fgErr))
}

// Only pass IRI informer when the feature gate is enabled to avoid
// watching for a CRD that may not exist
var iriInformer = ctrlctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages()
if !ctrlctx.FeatureGatesHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
iriInformer = nil
}

controller := operator.New(
ctrlcommon.MCONamespace, componentName,
startOpts.imagesFile,
Expand Down Expand Up @@ -119,7 +111,7 @@ func runStartCmd(_ *cobra.Command, _ []string) {
ctrlctx.NamespacedInformerFactory.Machineconfiguration().V1().MachineOSConfigs(),
ctrlctx.ConfigInformerFactory.Config().V1().ClusterVersions(),
ctrlctx.InformerFactory.Machineconfiguration().V1alpha1().OSImageStreams(),
iriInformer,
ctrlctx.InformerFactory.Machineconfiguration().V1().InternalReleaseImages(),
ctrlctx,
)

Expand Down
18 changes: 8 additions & 10 deletions pkg/controller/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"github.com/opencontainers/go-digest"
apicfgv1 "github.com/openshift/api/config/v1"
apicfgv1alpha1 "github.com/openshift/api/config/v1alpha1"
"github.com/openshift/api/features"

imagev1 "github.com/openshift/api/image/v1"
mcfgv1 "github.com/openshift/api/machineconfiguration/v1"
mcfgv1alpha1 "github.com/openshift/api/machineconfiguration/v1alpha1"
Expand Down Expand Up @@ -271,7 +271,7 @@ func (b *Bootstrap) Run(destDir string) error {
// The template controller has not yet run at this point, so machine-config-daemon-pull.service
// would otherwise fail to authenticate against the IRI registry.
// Merge is a no-op if the feature gate is off or the IRI resource is absent.
merger := ctrlcommon.NewIRISecretMergerFromObjects(iriCredentialsSecret, cconfig, fgHandler, iri)
merger := ctrlcommon.NewIRISecretMergerFromObjects(iriCredentialsSecret, cconfig, iri)
pullSecretBytes, err = merger.Merge(pullSecretBytes)
if err != nil {
return fmt.Errorf("could not merge IRI credentials into pull secret for bootstrap: %w", err)
Expand Down Expand Up @@ -337,15 +337,13 @@ func (b *Bootstrap) Run(destDir string) error {
}
klog.Infof("Successfully generated MachineConfigs from kubelet configs.")

if fgHandler != nil && fgHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
if iri {
iriConfigs, err := internalreleaseimage.RunInternalReleaseImageBootstrap(iriTLSCert, iriCredentialsSecret, cconfig)
if err != nil {
return err
}
configs = append(configs, iriConfigs...)
klog.Infof("Successfully generated MachineConfig from InternalReleaseImage.")
if iri {
iriConfigs, err := internalreleaseimage.RunInternalReleaseImageBootstrap(iriTLSCert, iriCredentialsSecret, cconfig)
if err != nil {
return err
}
configs = append(configs, iriConfigs...)
klog.Infof("Successfully generated MachineConfig from InternalReleaseImage.")
}

// Create component MachineConfigs for pre-built images for hybrid OCL
Expand Down
6 changes: 0 additions & 6 deletions pkg/controller/certrotation/certrotation_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"k8s.io/utils/clock"

configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/api/features"
configclientset "github.com/openshift/client-go/config/clientset/versioned"
machineclientset "github.com/openshift/client-go/machine/clientset/versioned"
mcfgclientset "github.com/openshift/client-go/machineconfiguration/clientset/versioned"
Expand Down Expand Up @@ -488,11 +487,6 @@ func (c *CertRotationController) reconcileSecret(secret corev1.Secret) error {
}

func (c *CertRotationController) reconcileIRICertificate() {
if !c.featureGatesHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
klog.V(4).Infof("Skipping IRI certificate reconciliation: %s feature gate is not enabled", features.FeatureGateNoRegistryClusterInstall)
return
}

// Check that the IRI cluster resource exists to confirm the feature is actually enabled
if _, err := c.mcfgClient.MachineconfigurationV1().InternalReleaseImages().Get(context.TODO(), ctrlcommon.InternalReleaseImageInstanceName, metav1.GetOptions{}); err != nil {
if k8serrors.IsNotFound(err) {
Expand Down
39 changes: 1 addition & 38 deletions pkg/controller/certrotation/certrotation_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import (
"github.com/stretchr/testify/require"

configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/api/features"
configinformers "github.com/openshift/client-go/config/informers/externalversions"
"github.com/openshift/library-go/pkg/controller/factory"
"github.com/openshift/library-go/pkg/crypto"
"github.com/openshift/library-go/pkg/operator/certrotation"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"

Expand Down Expand Up @@ -120,10 +118,7 @@ func (f *fixture) newController() *CertRotationController {
f.infraLister = append(f.infraLister, infra.(*configv1.Infrastructure))
}

fgHandler := ctrlcommon.NewFeatureGatesHardcodedHandler(
[]configv1.FeatureGateName{features.FeatureGateNoRegistryClusterInstall},
nil,
)
fgHandler := ctrlcommon.NewFeatureGatesHardcodedHandler(nil, nil)
c, err := New(f.kubeClient, f.configClient, f.machineClient, f.aroClient, f.k8sI.Core().V1().Secrets(), f.k8sI.Core().V1().Secrets(), f.k8sI.Core().V1().ConfigMaps(), f.infraInformer.Config().V1().Infrastructures(), fgHandler, f.mcfgClient)
require.NoError(f.t, err)

Expand Down Expand Up @@ -443,38 +438,6 @@ func TestIRICertificateRotation(t *testing.T) {
})
}

func TestIRICertificateReconcileSkippedWhenFeatureGateDisabled(t *testing.T) {
f := newFixture(t)
f.mcfgObjects = append(f.mcfgObjects, getIRIClusterResource())
f.machineObjects = append(f.machineObjects, getMachineSet("test-machine"))

// Build a controller with the feature gate disabled.
f.kubeClient = fake.NewSimpleClientset(f.objects...)
f.configClient = fakeconfigv1client.NewSimpleClientset(f.configObjects...)
f.machineClient = fakemachineclientset.NewSimpleClientset(f.machineObjects...)
f.mcfgClient = fakemcfgclientset.NewSimpleClientset(f.mcfgObjects...)
f.aroClient = fakearoclientset.NewSimpleClientset(f.aroObjects...)
f.k8sI = kubeinformers.NewSharedInformerFactory(f.kubeClient, noResyncPeriodFunc())
f.infraInformer = configinformers.NewSharedInformerFactory(f.configClient, noResyncPeriodFunc())

fgHandler := ctrlcommon.NewFeatureGatesHardcodedHandler(
nil,
[]configv1.FeatureGateName{features.FeatureGateNoRegistryClusterInstall},
)
c, err := New(f.kubeClient, f.configClient, f.machineClient, f.aroClient,
f.k8sI.Core().V1().Secrets(), f.k8sI.Core().V1().Secrets(),
f.k8sI.Core().V1().ConfigMaps(), f.infraInformer.Config().V1().Infrastructures(),
fgHandler, f.mcfgClient)
require.NoError(t, err)

// reconcileIRICertificate must be a no-op when the feature gate is disabled.
c.reconcileIRICertificate()

// Verify no IRI TLS secret was created.
_, err = f.kubeClient.CoreV1().Secrets(ctrlcommon.MCONamespace).Get(context.TODO(), ctrlcommon.InternalReleaseImageTLSSecretName, metav1.GetOptions{})
require.Error(t, err, "IRI TLS secret should not exist when feature gate is disabled")
require.True(t, k8serrors.IsNotFound(err))
}

func TestIsIRICertValid(t *testing.T) {
caConfig, err := crypto.MakeSelfSignedCAConfig("test-ca", 24*time.Hour)
Expand Down
29 changes: 9 additions & 20 deletions pkg/controller/common/iri_secret_merger.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"strings"

features "github.com/openshift/api/features"
mcfgv1 "github.com/openshift/api/machineconfiguration/v1"
mcfglistersv1 "github.com/openshift/client-go/machineconfiguration/listers/machineconfiguration/v1"
corev1 "k8s.io/api/core/v1"
Expand All @@ -16,10 +15,9 @@ import (
"k8s.io/klog/v2"
)

// errIRIDisabled is returned by resolve when the NoRegistryClusterInstall
// feature gate is off or the InternalReleaseImage resource is absent.
// Merge treats it as a skip signal rather than an error.
var errIRIDisabled = errors.New("IRI not enabled or not present")
// errIRIDisabled is returned by resolve when the InternalReleaseImage
// resource is absent. Merge treats it as a skip signal rather than an error.
var errIRIDisabled = errors.New("IRI not present")

// IRISecretMerger merges IRI registry credentials into a pull secret.
// Construct via NewIRISecretMerger (controller use) or NewIRISecretMergerFromObjects
Expand All @@ -30,21 +28,16 @@ type IRISecretMerger struct {
resolve func() (password, baseDomain string, err error)
}

// NewIRISecretMerger creates an IRISecretMerger that resolves the feature gate,
// NewIRISecretMerger creates an IRISecretMerger that resolves the
// IRI resource, credentials secret, and ControllerConfig from the informer cache
// at merge time. Use this in controllers where informers are available.
// fgHandler must not be nil.
func NewIRISecretMerger(
secretLister corelistersv1.SecretLister,
ccLister mcfglistersv1.ControllerConfigLister,
iriLister mcfglistersv1.InternalReleaseImageLister,
fgHandler FeatureGatesHandler,
) *IRISecretMerger {
return &IRISecretMerger{
resolve: func() (string, string, error) {
if !fgHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
return "", "", errIRIDisabled
}
_, err := iriLister.Get(InternalReleaseImageInstanceName)
if apierrors.IsNotFound(err) {
return "", "", errIRIDisabled
Expand All @@ -67,19 +60,15 @@ func NewIRISecretMerger(

// NewIRISecretMergerFromObjects creates an IRISecretMerger from pre-fetched objects.
// Use this during bootstrap where informer caches are not yet available.
// The feature gate and iri checks are deferred to Merge time so the constructor
// never returns an error; if either check fails, Merge skips and logs.
// The iri check is deferred to Merge time so the constructor
// never returns an error; if the check fails, Merge skips and logs.
func NewIRISecretMergerFromObjects(
secret *corev1.Secret,
cconfig *mcfgv1.ControllerConfig,
fgHandler FeatureGatesHandler,
iri bool,
) *IRISecretMerger {
return &IRISecretMerger{
resolve: func() (string, string, error) {
if fgHandler == nil || !fgHandler.Enabled(features.FeatureGateNoRegistryClusterInstall) {
return "", "", errIRIDisabled
}
if !iri {
return "", "", errIRIDisabled
}
Expand All @@ -91,12 +80,12 @@ func NewIRISecretMergerFromObjects(
// Merge merges IRI registry credentials into pullSecretRaw, adding auth entries
// for api-int.<baseDomain>:<IRIRegistryPort> (all nodes) and
// localhost:<IRIRegistryPort> (masters, where the registry runs locally).
// If the feature gate is disabled or the InternalReleaseImage resource is absent,
// Merge logs and returns pullSecretRaw unchanged.
// If the InternalReleaseImage resource is absent, Merge logs and returns
// pullSecretRaw unchanged.
func (m *IRISecretMerger) Merge(pullSecretRaw []byte) ([]byte, error) {
password, baseDomain, err := m.resolve()
if errors.Is(err, errIRIDisabled) {
klog.V(4).Info("Skipping IRI registry credential merge: IRI not enabled or not present")
klog.V(4).Info("Skipping IRI registry credential merge: IRI not present")
return pullSecretRaw, nil
}
if err != nil {
Expand Down
Loading