Skip to content

Commit c719d9d

Browse files
authored
OADP-823 unit test for oadp-1.0 csi plugin cluster version validation (#850)
1 parent cae07b8 commit c719d9d

5 files changed

Lines changed: 212 additions & 53 deletions

File tree

controllers/dpa_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
3333
"k8s.io/apimachinery/pkg/runtime"
3434
"k8s.io/apimachinery/pkg/types"
35+
"k8s.io/client-go/discovery"
3536
"k8s.io/client-go/tools/record"
3637
"k8s.io/client-go/util/workqueue"
3738
ctrl "sigs.k8s.io/controller-runtime"
@@ -45,6 +46,7 @@ import (
4546
// DPAReconciler reconciles a Velero object
4647
type DPAReconciler struct {
4748
client.Client
49+
discovery.DiscoveryInterface
4850
Scheme *runtime.Scheme
4951
Log logr.Logger
5052
Context context.Context

controllers/validator.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ package controllers
33
import (
44
"errors"
55
"fmt"
6-
"k8s.io/apimachinery/pkg/version"
7-
"k8s.io/client-go/kubernetes"
8-
"sigs.k8s.io/controller-runtime/pkg/client/config"
96

107
"github.com/go-logr/logr"
118
oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
@@ -91,7 +88,7 @@ func (r *DPAReconciler) ValidateVeleroPlugins(log logr.Logger) (bool, error) {
9188
// check csi compatibility with cluster version
9289
// 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
9390
if plugin == oadpv1alpha1.DefaultPluginCSI {
94-
clusterVersion, err := getClusterVersion()
91+
clusterVersion, err := r.DiscoveryInterface.ServerVersion()
9592
if err != nil {
9693
return false, err
9794
}
@@ -119,12 +116,3 @@ func (r *DPAReconciler) ValidateVeleroPlugins(log logr.Logger) (bool, error) {
119116
}
120117
return true, nil
121118
}
122-
123-
func getClusterVersion() (*version.Info, error) {
124-
kubeConf := config.GetConfigOrDie()
125-
clientset, err := kubernetes.NewForConfig(kubeConf)
126-
if err != nil {
127-
return nil, err
128-
}
129-
return clientset.Discovery().ServerVersion()
130-
}

controllers/validator_test.go

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
package controllers
22

33
import (
4-
"k8s.io/apimachinery/pkg/api/resource"
4+
"context"
55
"testing"
66

77
"github.com/go-logr/logr"
8+
logrTesting "github.com/go-logr/logr/testing"
89
oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
10+
oadpScheme "github.com/openshift/oadp-operator/pkg/scheme"
911
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
1012
corev1 "k8s.io/api/core/v1"
13+
"k8s.io/apimachinery/pkg/api/resource"
1114
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+
"k8s.io/apimachinery/pkg/runtime"
1216
"k8s.io/apimachinery/pkg/types"
17+
"k8s.io/apimachinery/pkg/version"
18+
discoverFake "k8s.io/client-go/discovery/fake"
19+
clienttesting "k8s.io/client-go/testing"
1320
"k8s.io/client-go/tools/record"
1421
"k8s.io/utils/pointer"
1522
"sigs.k8s.io/controller-runtime/pkg/client"
23+
clientFake "sigs.k8s.io/controller-runtime/pkg/client/fake"
1624
)
1725

1826
func TestDPAReconciler_ValidateDataProtectionCR(t *testing.T) {
@@ -707,3 +715,136 @@ func TestDPAReconciler_ValidateDataProtectionCR(t *testing.T) {
707715
})
708716
}
709717
}
718+
719+
var namespacedName = types.NamespacedName{
720+
Namespace: "test-ns",
721+
Name: "test-DPA-CR",
722+
}
723+
func TestDPAReconciler_ValidateVeleroPlugins(t *testing.T) {
724+
type fields struct {
725+
objects []runtime.Object
726+
FakedServerVersion *version.Info
727+
Scheme *runtime.Scheme
728+
NamespacedName types.NamespacedName
729+
EventRecorder record.EventRecorder
730+
}
731+
tests := []struct {
732+
name string
733+
fields fields
734+
want bool
735+
wantErr bool
736+
}{
737+
{
738+
name: "given valid DPA CR with AWS, CSI Default Plugin and secret",
739+
fields: fields{
740+
objects: []runtime.Object{
741+
&oadpv1alpha1.DataProtectionApplication{
742+
TypeMeta: metav1.TypeMeta{
743+
Kind: "DataProtectionApplication",
744+
APIVersion: "oadp.openshift.io/v1alpha1",
745+
},
746+
ObjectMeta: metav1.ObjectMeta{
747+
Name: "test-DPA-CR",
748+
Namespace: "test-ns",
749+
},
750+
Spec: oadpv1alpha1.DataProtectionApplicationSpec{
751+
Configuration: &oadpv1alpha1.ApplicationConfig{
752+
Velero: &oadpv1alpha1.VeleroConfig{
753+
DefaultPlugins: []oadpv1alpha1.DefaultPlugin{
754+
oadpv1alpha1.DefaultPluginAWS,
755+
oadpv1alpha1.DefaultPluginCSI,
756+
},
757+
},
758+
},
759+
},
760+
},
761+
// secret
762+
&corev1.Secret{
763+
ObjectMeta: metav1.ObjectMeta{
764+
Name: "cloud-credentials",
765+
Namespace: "test-ns",
766+
},
767+
Data: map[string][]byte{
768+
"cloud": []byte("test"),
769+
},
770+
},
771+
},
772+
},
773+
want: true,
774+
wantErr: false,
775+
},
776+
{
777+
name: "Cluster version too high for CSI plugin",
778+
fields: fields{
779+
objects: []runtime.Object{
780+
&oadpv1alpha1.DataProtectionApplication{
781+
TypeMeta: metav1.TypeMeta{
782+
Kind: "DataProtectionApplication",
783+
APIVersion: "oadp.openshift.io/v1alpha1",
784+
},
785+
ObjectMeta: metav1.ObjectMeta{
786+
Name: "test-DPA-CR",
787+
Namespace: "test-ns",
788+
},
789+
Spec: oadpv1alpha1.DataProtectionApplicationSpec{
790+
Configuration: &oadpv1alpha1.ApplicationConfig{
791+
Velero: &oadpv1alpha1.VeleroConfig{
792+
DefaultPlugins: []oadpv1alpha1.DefaultPlugin{
793+
oadpv1alpha1.DefaultPluginAWS,
794+
oadpv1alpha1.DefaultPluginCSI,
795+
},
796+
},
797+
},
798+
},
799+
},
800+
// secret
801+
&corev1.Secret{
802+
ObjectMeta: metav1.ObjectMeta{
803+
Name: "cloud-credentials",
804+
Namespace: "test-ns",
805+
},
806+
Data: map[string][]byte{
807+
"cloud": []byte("test"),
808+
},
809+
},
810+
},
811+
FakedServerVersion: &version.Info{
812+
Major: "1",
813+
Minor: "24",
814+
},
815+
},
816+
want: false,
817+
wantErr: true,
818+
},
819+
}
820+
for _, tt := range tests {
821+
t.Run(tt.name, func(t *testing.T) {
822+
if tt.fields.FakedServerVersion == nil {
823+
tt.fields.FakedServerVersion = &version.Info{
824+
Major: "1",
825+
Minor: "23",
826+
}
827+
}
828+
log := logrTesting.TestLogger{T: t}
829+
scheme := runtime.NewScheme()
830+
oadpScheme.AddToScheme(scheme, log)
831+
r := &DPAReconciler{
832+
Client: clientFake.NewFakeClientWithScheme(scheme, tt.fields.objects...),
833+
DiscoveryInterface: &discoverFake.FakeDiscovery{
834+
Fake: &clienttesting.Fake{},
835+
FakedServerVersion: tt.fields.FakedServerVersion},
836+
Log: log,
837+
NamespacedName: namespacedName,
838+
Context: context.Background(),
839+
}
840+
got, err := r.ValidateVeleroPlugins(r.Log)
841+
if (err != nil) != tt.wantErr {
842+
t.Errorf("DPAReconciler.ValidateVeleroPlugins() error = %v, wantErr %v", err, tt.wantErr)
843+
return
844+
}
845+
if got != tt.want {
846+
t.Errorf("DPAReconciler.ValidateVeleroPlugins() = %v, want %v", got, tt.want)
847+
}
848+
})
849+
}
850+
}

main.go

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,16 @@ package main
1919
import (
2020
"flag"
2121
"fmt"
22-
monitor "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
2322
"os"
2423

24+
oadpScheme "github.com/openshift/oadp-operator/pkg/scheme"
25+
2526
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2627
// to ensure that exec-entrypoint and run can make use of them.
28+
"k8s.io/client-go/discovery"
2729
_ "k8s.io/client-go/plugin/pkg/client/auth"
2830

29-
routev1 "github.com/openshift/api/route/v1"
30-
security "github.com/openshift/api/security/v1"
3131
"github.com/openshift/oadp-operator/controllers"
32-
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
33-
appsv1 "k8s.io/api/apps/v1"
34-
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3532
"k8s.io/apimachinery/pkg/runtime"
3633
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
3734
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
@@ -92,41 +89,13 @@ func main() {
9289
os.Exit(1)
9390
}
9491

95-
// Setup scheme for OCP resources
96-
if err := monitor.AddToScheme(mgr.GetScheme()); err != nil {
97-
setupLog.Error(err, "unable to add OpenShift monitoring APIs to scheme")
98-
os.Exit(1)
99-
}
100-
101-
if err := security.AddToScheme(mgr.GetScheme()); err != nil {
102-
setupLog.Error(err, "unable to add OpenShift security APIs to scheme")
103-
os.Exit(1)
104-
}
105-
106-
if err := routev1.AddToScheme(mgr.GetScheme()); err != nil {
107-
setupLog.Error(err, "unable to add OpenShift route API to scheme")
108-
os.Exit(1)
109-
}
110-
111-
if err := velerov1.AddToScheme(mgr.GetScheme()); err != nil {
112-
setupLog.Error(err, "unable to add Velero APIs to scheme")
113-
os.Exit(1)
114-
}
115-
116-
if err := appsv1.AddToScheme(mgr.GetScheme()); err != nil {
117-
setupLog.Error(err, "unable to add Kubernetes APIs to scheme")
118-
os.Exit(1)
119-
}
120-
121-
if err := v1.AddToScheme(mgr.GetScheme()); err != nil {
122-
setupLog.Error(err, "unable to add Kubernetes API extensions to scheme")
123-
os.Exit(1)
124-
}
92+
oadpScheme.AddToScheme(mgr.GetScheme(), setupLog)
12593

12694
if err = (&controllers.DPAReconciler{
127-
Client: mgr.GetClient(),
128-
Scheme: mgr.GetScheme(),
129-
EventRecorder: mgr.GetEventRecorderFor("DPA-controller"),
95+
Client: mgr.GetClient(),
96+
DiscoveryInterface: discovery.NewDiscoveryClientForConfigOrDie(mgr.GetConfig()),
97+
Scheme: mgr.GetScheme(),
98+
EventRecorder: mgr.GetEventRecorderFor("DPA-controller"),
13099
}).SetupWithManager(mgr); err != nil {
131100
setupLog.Error(err, "unable to create controller", "controller", "DataProtectionApplication")
132101
os.Exit(1)

pkg/scheme/scheme.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package scheme
2+
3+
import (
4+
"os"
5+
6+
"k8s.io/apimachinery/pkg/runtime"
7+
8+
"github.com/go-logr/logr"
9+
monitor "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
10+
11+
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
12+
// to ensure that exec-entrypoint and run can make use of them.
13+
14+
_ "k8s.io/client-go/plugin/pkg/client/auth"
15+
16+
routev1 "github.com/openshift/api/route/v1"
17+
security "github.com/openshift/api/security/v1"
18+
"github.com/openshift/oadp-operator/api/v1alpha1"
19+
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
20+
appsv1 "k8s.io/api/apps/v1"
21+
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
22+
)
23+
func AddToScheme(scheme *runtime.Scheme, setupLog logr.Logger) {
24+
// Setup scheme for OCP resources
25+
if err := monitor.AddToScheme(scheme); err != nil {
26+
setupLog.Error(err, "unable to add OpenShift monitoring APIs to scheme")
27+
os.Exit(1)
28+
}
29+
30+
if err := security.AddToScheme(scheme); err != nil {
31+
setupLog.Error(err, "unable to add OpenShift security APIs to scheme")
32+
os.Exit(1)
33+
}
34+
35+
if err := routev1.AddToScheme(scheme); err != nil {
36+
setupLog.Error(err, "unable to add OpenShift route API to scheme")
37+
os.Exit(1)
38+
}
39+
40+
if err := velerov1.AddToScheme(scheme); err != nil {
41+
setupLog.Error(err, "unable to add Velero APIs to scheme")
42+
os.Exit(1)
43+
}
44+
45+
if err := appsv1.AddToScheme(scheme); err != nil {
46+
setupLog.Error(err, "unable to add Kubernetes APIs to scheme")
47+
os.Exit(1)
48+
}
49+
50+
if err := v1.AddToScheme(scheme); err != nil {
51+
setupLog.Error(err, "unable to add Kubernetes API extensions to scheme")
52+
os.Exit(1)
53+
}
54+
55+
if err := v1alpha1.AddToScheme(scheme); err != nil {
56+
setupLog.Error(err, "unable to add Kubernetes API extensions to scheme")
57+
os.Exit(1)
58+
}
59+
}

0 commit comments

Comments
 (0)