Skip to content

Commit

Permalink
Unify and make explicit v1 v. v2 scheme registration (#300)
Browse files Browse the repository at this point in the history
* Unify and make explicit v1 v. v2 scheme registration

* Initialize schemes in init function and output a unified scheme in addition to version specific schemes
  • Loading branch information
andrewstucki authored Nov 11, 2024
1 parent 0e52097 commit 3a34a83
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 89 deletions.
52 changes: 14 additions & 38 deletions operator/cmd/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,17 @@ package run

import (
"context"
"errors"
"fmt"
"net/http"
"net/http/pprof"
"strings"
"time"

cmapiv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
helmControllerAPIv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
helmControllerAPIv2beta2 "github.com/fluxcd/helm-controller/api/v2beta2"
"github.com/fluxcd/pkg/runtime/client"
sourceControllerAPIv1 "github.com/fluxcd/source-controller/api/v1"
sourceControllerAPIv1beta2 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/kube"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
Expand All @@ -39,9 +32,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

redpandav1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha1"
redpandav1alpha2 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha2"
vectorizedv1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/vectorized/v1alpha1"
"github.com/redpanda-data/redpanda-operator/operator/internal/controller"
"github.com/redpanda-data/redpanda-operator/operator/internal/controller/flux"
redpandacontrollers "github.com/redpanda-data/redpanda-operator/operator/internal/controller/redpanda"
vectorizedcontrollers "github.com/redpanda-data/redpanda-operator/operator/internal/controller/vectorized"
Expand Down Expand Up @@ -69,7 +62,6 @@ const (

OperatorV1Mode = OperatorState("Clustered-v1")
OperatorV2Mode = OperatorState("Namespaced-v2")
ClusterControllerMode = OperatorState("Clustered-Controllers")
NamespaceControllerMode = OperatorState("Namespaced-Controllers")

controllerName = "redpanda-controller"
Expand All @@ -79,7 +71,6 @@ const (
)

var (
scheme = runtime.NewScheme()
clientOptions client.Options
kubeConfigOpts client.KubeConfigOptions

Expand All @@ -89,20 +80,6 @@ var (
}
)

//nolint:wsl // the init was generated by kubebuilder
func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(cmapiv1.AddToScheme(scheme))
utilruntime.Must(helmControllerAPIv2beta1.AddToScheme(scheme))
utilruntime.Must(helmControllerAPIv2beta2.AddToScheme(scheme))
utilruntime.Must(redpandav1alpha1.AddToScheme(scheme))
utilruntime.Must(redpandav1alpha2.AddToScheme(scheme))
utilruntime.Must(sourceControllerAPIv1.AddToScheme(scheme))
utilruntime.Must(sourceControllerAPIv1beta2.AddToScheme(scheme))
utilruntime.Must(vectorizedv1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}

// +kubebuilder:rbac:groups=coordination.k8s.io,namespace=default,resources=leases,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,namespace=default,resources=configmaps,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,namespace=default,resources=events,verbs=create;patch
Expand Down Expand Up @@ -229,7 +206,6 @@ func Run(
kube.ManagedFieldsManager = controllerName

mgrOptions := ctrl.Options{
Scheme: scheme,
Metrics: metricsserver.Options{BindAddress: metricsAddr},
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
Expand All @@ -240,20 +216,14 @@ func Run(
mgrOptions.Cache.DefaultNamespaces = map[string]cache.Config{namespace: {}}
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), mgrOptions)
if err != nil {
setupLog.Error(err, "Unable to start manager")
return err
}

configurator := resources.ConfiguratorSettings{
ConfiguratorBaseImage: configuratorBaseImage,
ConfiguratorTag: configuratorTag,
ImagePullPolicy: corev1.PullPolicy(configuratorImagePullPolicy),
}

// init running state values if we are not in operator mode
operatorRunningState := ClusterControllerMode
var operatorRunningState OperatorState
if namespace != "" {
operatorRunningState = NamespaceControllerMode
}
Expand All @@ -266,6 +236,15 @@ func Run(
}
}

scheme := controller.UnifiedScheme
mgrOptions.Scheme = scheme

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), mgrOptions)
if err != nil {
setupLog.Error(err, "Unable to start manager")
return err
}

// Now we start different processes depending on state
switch operatorRunningState {
case OperatorV1Mode:
Expand Down Expand Up @@ -448,10 +427,6 @@ func Run(
}
}

case ClusterControllerMode:
ctrl.Log.Info("running as a cluster controller", "mode", ClusterControllerMode)
setupLog.Error(err, "unable to create cluster controllers, not supported")
return err
case NamespaceControllerMode:
ctrl.Log.Info("running as a namespace controller", "mode", NamespaceControllerMode, "namespace", namespace)
if runThisController(NodeController, additionalControllers) {
Expand All @@ -475,7 +450,8 @@ func Run(
}
}
default:
setupLog.Error(err, "unable unknown state, not supported")
err := errors.New("unable to run operator without specifying an operator state")
setupLog.Error(err, "shutting down")
return err
}

Expand Down
22 changes: 2 additions & 20 deletions operator/internal/controller/redpanda/redpanda_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,14 @@ import (
"testing"
"time"

certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
helmcontrollerv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
helmcontrollerv2beta2 "github.com/fluxcd/helm-controller/api/v2beta2"
fluxclient "github.com/fluxcd/pkg/runtime/client"
sourcecontrollerv1 "github.com/fluxcd/source-controller/api/v1"
sourcecontrollerv1beta1 "github.com/fluxcd/source-controller/api/v1beta1"
sourcecontrollerv1beta2 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/go-logr/logr/testr"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
redpandachart "github.com/redpanda-data/helm-charts/charts/redpanda"
"github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette"
"github.com/redpanda-data/helm-charts/pkg/kube"
redpandav1alpha2 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha2"
crds "github.com/redpanda-data/redpanda-operator/operator/config/crd/bases"
"github.com/redpanda-data/redpanda-operator/operator/internal/controller"
"github.com/redpanda-data/redpanda-operator/operator/internal/controller/flux"
"github.com/redpanda-data/redpanda-operator/operator/internal/controller/redpanda"
"github.com/redpanda-data/redpanda-operator/operator/internal/testenv"
Expand All @@ -48,7 +42,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
goclientscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -427,24 +420,13 @@ func (s *RedpandaControllerSuite) TestClusterSettings() {
func (s *RedpandaControllerSuite) SetupSuite() {
t := s.T()

scheme := runtime.NewScheme()
require.NoError(t, certmanagerv1.AddToScheme(scheme))
require.NoError(t, goclientscheme.AddToScheme(scheme))
require.NoError(t, helmcontrollerv2beta1.AddToScheme(scheme))
require.NoError(t, helmcontrollerv2beta2.AddToScheme(scheme))
require.NoError(t, monitoringv1.AddToScheme(scheme))
require.NoError(t, redpandav1alpha2.AddToScheme(scheme))
require.NoError(t, sourcecontrollerv1.AddToScheme(scheme))
require.NoError(t, sourcecontrollerv1beta1.AddToScheme(scheme))
require.NoError(t, sourcecontrollerv1beta2.AddToScheme(scheme))

// TODO SetupManager currently runs with admin permissions on the cluster.
// This will allow the operator's ClusterRole and Role to get out of date.
// Ideally, we should bind the declared permissions of the operator to the
// rest config given to the manager.
s.ctx = context.Background()
s.env = testenv.New(t, testenv.Options{
Scheme: scheme,
Scheme: controller.UnifiedScheme,
CRDs: crds.All(),
Logger: testr.New(t),
})
Expand Down
64 changes: 64 additions & 0 deletions operator/internal/controller/scheme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2024 Redpanda Data, Inc.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.md
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0

package controller

import (
cmapiv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
helmControllerAPIv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
helmControllerAPIv2beta2 "github.com/fluxcd/helm-controller/api/v2beta2"
sourceControllerAPIv1 "github.com/fluxcd/source-controller/api/v1"
sourceControllerAPIv1beta2 "github.com/fluxcd/source-controller/api/v1beta2"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
redpandav1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha1"
redpandav1alpha2 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha2"
vectorizedv1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/vectorized/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
)

var (
v1SchemeFns = []func(s *runtime.Scheme) error{
clientgoscheme.AddToScheme,
cmapiv1.AddToScheme,
vectorizedv1alpha1.AddToScheme,
}
v2SchemeFns = []func(s *runtime.Scheme) error{
clientgoscheme.AddToScheme,
cmapiv1.AddToScheme,
helmControllerAPIv2beta1.AddToScheme,
helmControllerAPIv2beta2.AddToScheme,
redpandav1alpha1.AddToScheme,
redpandav1alpha2.AddToScheme,
sourceControllerAPIv1.AddToScheme,
sourceControllerAPIv1beta2.AddToScheme,
monitoringv1.AddToScheme,
}

V1Scheme *runtime.Scheme
V2Scheme *runtime.Scheme
UnifiedScheme *runtime.Scheme
)

func init() {
V1Scheme = runtime.NewScheme()
V2Scheme = runtime.NewScheme()
UnifiedScheme = runtime.NewScheme()

for _, fn := range v1SchemeFns {
utilruntime.Must(fn(V1Scheme))
utilruntime.Must(fn(UnifiedScheme))
}

for _, fn := range v2SchemeFns {
utilruntime.Must(fn(V2Scheme))
utilruntime.Must(fn(UnifiedScheme))
}
}
9 changes: 2 additions & 7 deletions operator/pkg/client/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ import (
"github.com/redpanda-data/helm-charts/pkg/helm"
"github.com/redpanda-data/helm-charts/pkg/kube"
"github.com/redpanda-data/helm-charts/pkg/testutil"
redpandav1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha1"
redpandav1alpha2 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha2"
"github.com/redpanda-data/redpanda-operator/operator/internal/controller"
"github.com/redpanda-data/redpanda-operator/operator/pkg/k3d"
"github.com/stretchr/testify/require"
"github.com/twmb/franz-go/pkg/kadm"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)
Expand Down Expand Up @@ -101,11 +100,7 @@ func TestClientFactory(t *testing.T) {

restcfg := cluster.RESTConfig()

s := runtime.NewScheme()
require.NoError(t, clientgoscheme.AddToScheme(s))
require.NoError(t, redpandav1alpha2.AddToScheme(s))
require.NoError(t, redpandav1alpha1.AddToScheme(s))
kubeClient, err := client.New(restcfg, client.Options{Scheme: s, WarningHandler: client.WarningHandlerOptions{SuppressWarnings: true}})
kubeClient, err := client.New(restcfg, client.Options{Scheme: controller.UnifiedScheme, WarningHandler: client.WarningHandlerOptions{SuppressWarnings: true}})
require.NoError(t, err)

helmClient, err := helm.New(helm.Options{
Expand Down
30 changes: 6 additions & 24 deletions operator/webhooks/redpanda/validate_enterprise_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,20 @@ import (
"testing"
"time"

cmapiv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
helmControllerAPIV2 "github.com/fluxcd/helm-controller/api/v2beta1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/stretchr/testify/require"
"github.com/twmb/franz-go/pkg/kadm"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

redpandav1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/redpanda/v1alpha1"
vectorizedv1alpha1 "github.com/redpanda-data/redpanda-operator/operator/api/vectorized/v1alpha1"
"github.com/redpanda-data/redpanda-operator/operator/internal/controller"
vectorizedcontrollers "github.com/redpanda-data/redpanda-operator/operator/internal/controller/vectorized"
"github.com/redpanda-data/redpanda-operator/operator/internal/testutils"
adminutils "github.com/redpanda-data/redpanda-operator/operator/pkg/admin"
Expand All @@ -47,20 +41,6 @@ import (

type mockKafkaAdmin struct{}

var scheme = runtime.NewScheme()

//nolint:wsl // the init was generated by kubebuilder
func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(cmapiv1.AddToScheme(scheme))
utilruntime.Must(helmControllerAPIV2.AddToScheme(scheme))
utilruntime.Must(sourcev1.AddToScheme(scheme))

utilruntime.Must(redpandav1alpha1.AddToScheme(scheme))
utilruntime.Must(vectorizedv1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}

func (m *mockKafkaAdmin) CreateACLs(
context.Context, *kadm.ACLBuilder,
) (kadm.CreateACLsResults, error) {
Expand All @@ -75,6 +55,8 @@ func (m *mockKafkaAdmin) DeleteACLs(

//nolint:funlen // Test using testEnv needs to be long
func TestDoNotValidateWhenDeleted(t *testing.T) {
scheme := controller.UnifiedScheme

testEnv := &testutils.RedpandaTestEnv{}

cfg, err := testEnv.StartRedpandaTestEnv(true)
Expand Down Expand Up @@ -141,13 +123,13 @@ func TestDoNotValidateWhenDeleted(t *testing.T) {
hookServer.Register("/mutate-redpanda-vectorized-io-v1alpha1-console", &webhook.Admission{
Handler: &redpanda.ConsoleDefaulter{
Client: mgr.GetClient(),
Decoder: admission.NewDecoder(scheme),
Decoder: admission.NewDecoder(mgr.GetScheme()),
},
})
hookServer.Register("/validate-redpanda-vectorized-io-v1alpha1-console", &webhook.Admission{
Handler: &redpanda.ConsoleValidator{
Client: mgr.GetClient(),
Decoder: admission.NewDecoder(scheme),
Decoder: admission.NewDecoder(mgr.GetScheme()),
},
})

Expand All @@ -174,7 +156,7 @@ func TestDoNotValidateWhenDeleted(t *testing.T) {

conn.Close()

c, err := client.New(testEnv.Config, client.Options{Scheme: scheme})
c, err := client.New(testEnv.Config, client.Options{Scheme: mgr.GetScheme()})
require.NoError(t, err)

one := int32(1)
Expand Down

0 comments on commit 3a34a83

Please sign in to comment.