Skip to content
Merged
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
2 changes: 2 additions & 0 deletions controllers/dpa_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
ctrl "sigs.k8s.io/controller-runtime"
Expand All @@ -45,6 +46,7 @@ import (
// DPAReconciler reconciles a Velero object
type DPAReconciler struct {
client.Client
discovery.DiscoveryInterface
Scheme *runtime.Scheme
Log logr.Logger
Context context.Context
Expand Down
14 changes: 1 addition & 13 deletions controllers/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ package controllers
import (
"errors"
"fmt"
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client/config"

"github.com/go-logr/logr"
oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
Expand Down Expand Up @@ -91,7 +88,7 @@ func (r *DPAReconciler) ValidateVeleroPlugins(log logr.Logger) (bool, error) {
// check csi compatibility with cluster version
// velero version <1.9 expects API group snapshot.storage.k8s.io/v1beta1, while OCP 4.11 (k8s 1.24) has only snapshot.storage.k8s.io/v1
if plugin == oadpv1alpha1.DefaultPluginCSI {
clusterVersion, err := getClusterVersion()
clusterVersion, err := r.DiscoveryInterface.ServerVersion()
if err != nil {
return false, err
}
Expand Down Expand Up @@ -119,12 +116,3 @@ func (r *DPAReconciler) ValidateVeleroPlugins(log logr.Logger) (bool, error) {
}
return true, nil
}

func getClusterVersion() (*version.Info, error) {
kubeConf := config.GetConfigOrDie()
clientset, err := kubernetes.NewForConfig(kubeConf)
if err != nil {
return nil, err
}
return clientset.Discovery().ServerVersion()
}
143 changes: 142 additions & 1 deletion controllers/validator_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
package controllers

import (
"k8s.io/apimachinery/pkg/api/resource"
"context"
"testing"

"github.com/go-logr/logr"
logrTesting "github.com/go-logr/logr/testing"
oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
oadpScheme "github.com/openshift/oadp-operator/pkg/scheme"
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/version"
discoverFake "k8s.io/client-go/discovery/fake"
clienttesting "k8s.io/client-go/testing"
"k8s.io/client-go/tools/record"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
clientFake "sigs.k8s.io/controller-runtime/pkg/client/fake"
)

func TestDPAReconciler_ValidateDataProtectionCR(t *testing.T) {
Expand Down Expand Up @@ -707,3 +715,136 @@ func TestDPAReconciler_ValidateDataProtectionCR(t *testing.T) {
})
}
}

var namespacedName = types.NamespacedName{
Namespace: "test-ns",
Name: "test-DPA-CR",
}
func TestDPAReconciler_ValidateVeleroPlugins(t *testing.T) {
type fields struct {
objects []runtime.Object
FakedServerVersion *version.Info
Scheme *runtime.Scheme
NamespacedName types.NamespacedName
EventRecorder record.EventRecorder
}
tests := []struct {
name string
fields fields
want bool
wantErr bool
}{
{
name: "given valid DPA CR with AWS, CSI Default Plugin and secret",
fields: fields{
objects: []runtime.Object{
&oadpv1alpha1.DataProtectionApplication{
TypeMeta: metav1.TypeMeta{
Kind: "DataProtectionApplication",
APIVersion: "oadp.openshift.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-DPA-CR",
Namespace: "test-ns",
},
Spec: oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{
DefaultPlugins: []oadpv1alpha1.DefaultPlugin{
oadpv1alpha1.DefaultPluginAWS,
oadpv1alpha1.DefaultPluginCSI,
},
},
},
},
},
// secret
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "cloud-credentials",
Namespace: "test-ns",
},
Data: map[string][]byte{
"cloud": []byte("test"),
},
},
},
},
want: true,
wantErr: false,
},
{
name: "Cluster version too high for CSI plugin",
fields: fields{
objects: []runtime.Object{
&oadpv1alpha1.DataProtectionApplication{
TypeMeta: metav1.TypeMeta{
Kind: "DataProtectionApplication",
APIVersion: "oadp.openshift.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-DPA-CR",
Namespace: "test-ns",
},
Spec: oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{
DefaultPlugins: []oadpv1alpha1.DefaultPlugin{
oadpv1alpha1.DefaultPluginAWS,
oadpv1alpha1.DefaultPluginCSI,
},
},
},
},
},
// secret
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "cloud-credentials",
Namespace: "test-ns",
},
Data: map[string][]byte{
"cloud": []byte("test"),
},
},
},
FakedServerVersion: &version.Info{
Major: "1",
Minor: "24",
},
},
want: false,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.fields.FakedServerVersion == nil {
tt.fields.FakedServerVersion = &version.Info{
Major: "1",
Minor: "23",
}
}
log := logrTesting.TestLogger{T: t}
scheme := runtime.NewScheme()
oadpScheme.AddToScheme(scheme, log)
r := &DPAReconciler{
Client: clientFake.NewFakeClientWithScheme(scheme, tt.fields.objects...),
DiscoveryInterface: &discoverFake.FakeDiscovery{
Fake: &clienttesting.Fake{},
FakedServerVersion: tt.fields.FakedServerVersion},
Log: log,
NamespacedName: namespacedName,
Context: context.Background(),
}
got, err := r.ValidateVeleroPlugins(r.Log)
if (err != nil) != tt.wantErr {
t.Errorf("DPAReconciler.ValidateVeleroPlugins() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("DPAReconciler.ValidateVeleroPlugins() = %v, want %v", got, tt.want)
}
})
}
}
47 changes: 8 additions & 39 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,16 @@ package main
import (
"flag"
"fmt"
monitor "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"os"

oadpScheme "github.com/openshift/oadp-operator/pkg/scheme"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
"k8s.io/client-go/discovery"
_ "k8s.io/client-go/plugin/pkg/client/auth"

routev1 "github.com/openshift/api/route/v1"
security "github.com/openshift/api/security/v1"
"github.com/openshift/oadp-operator/controllers"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
Expand Down Expand Up @@ -92,41 +89,13 @@ func main() {
os.Exit(1)
}

// Setup scheme for OCP resources
if err := monitor.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "unable to add OpenShift monitoring APIs to scheme")
os.Exit(1)
}

if err := security.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "unable to add OpenShift security APIs to scheme")
os.Exit(1)
}

if err := routev1.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "unable to add OpenShift route API to scheme")
os.Exit(1)
}

if err := velerov1.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "unable to add Velero APIs to scheme")
os.Exit(1)
}

if err := appsv1.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "unable to add Kubernetes APIs to scheme")
os.Exit(1)
}

if err := v1.AddToScheme(mgr.GetScheme()); err != nil {
setupLog.Error(err, "unable to add Kubernetes API extensions to scheme")
os.Exit(1)
}
oadpScheme.AddToScheme(mgr.GetScheme(), setupLog)

if err = (&controllers.DPAReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
EventRecorder: mgr.GetEventRecorderFor("DPA-controller"),
Client: mgr.GetClient(),
DiscoveryInterface: discovery.NewDiscoveryClientForConfigOrDie(mgr.GetConfig()),
Scheme: mgr.GetScheme(),
EventRecorder: mgr.GetEventRecorderFor("DPA-controller"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "DataProtectionApplication")
os.Exit(1)
Expand Down
59 changes: 59 additions & 0 deletions pkg/scheme/scheme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package scheme

import (
"os"

"k8s.io/apimachinery/pkg/runtime"

"github.com/go-logr/logr"
monitor "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.

_ "k8s.io/client-go/plugin/pkg/client/auth"

routev1 "github.com/openshift/api/route/v1"
security "github.com/openshift/api/security/v1"
"github.com/openshift/oadp-operator/api/v1alpha1"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
)
func AddToScheme(scheme *runtime.Scheme, setupLog logr.Logger) {
// Setup scheme for OCP resources
if err := monitor.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add OpenShift monitoring APIs to scheme")
os.Exit(1)
}

if err := security.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add OpenShift security APIs to scheme")
os.Exit(1)
}

if err := routev1.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add OpenShift route API to scheme")
os.Exit(1)
}

if err := velerov1.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add Velero APIs to scheme")
os.Exit(1)
}

if err := appsv1.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add Kubernetes APIs to scheme")
os.Exit(1)
}

if err := v1.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add Kubernetes API extensions to scheme")
os.Exit(1)
}

if err := v1alpha1.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add Kubernetes API extensions to scheme")
os.Exit(1)
}
}