Skip to content

Commit

Permalink
OADP-823 unit test for oadp-1.0 csi plugin cluster version validation (
Browse files Browse the repository at this point in the history
  • Loading branch information
kaovilai authored Oct 8, 2022
1 parent cae07b8 commit c719d9d
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 53 deletions.
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)
}
}

0 comments on commit c719d9d

Please sign in to comment.