[OOM-K8S-CERT-EXTERNAL-PROVIDER] Add CMPv2IssuerController test 33/114433/9
authorPiotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Fri, 30 Oct 2020 10:02:51 +0000 (11:02 +0100)
committerPiotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Wed, 4 Nov 2020 07:54:32 +0000 (08:54 +0100)
- Add Reconcile test in CMPv2IssuerController

Issue-ID: OOM-2559
Signed-off-by: Piotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Change-Id: I49aff7bc36f7da4df7eeaebaca144ee5a5bb9853

certServiceK8sExternalProvider/main.go
certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go [new file with mode: 0644]
certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go
certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go
certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory.go
certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_mock.go [new file with mode: 0644]
certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_test.go
certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_test.go
certServiceK8sExternalProvider/src/testdata/provider.go [new file with mode: 0644]

index 57058e9..430d402 100644 (file)
@@ -42,6 +42,7 @@ import (
        app "onap.org/oom-certservice/k8s-external-provider/src"
        certserviceapi "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
        controllers "onap.org/oom-certservice/k8s-external-provider/src/cmpv2controller"
+       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner"
 )
 
 var (
@@ -117,6 +118,7 @@ func registerCMPv2IssuerController(manager manager.Manager) {
                Log:      ctrl.Log.WithName("controllers").WithName("CMPv2Issuer"),
                Clock:    clock.RealClock{},
                Recorder: manager.GetEventRecorderFor("cmpv2-issuer-controller"),
+               ProvisionerFactory: &cmpv2provisioner.ProvisionerFactoryImpl{},
        }).SetupWithManager(manager)
 
        if err != nil {
diff --git a/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go
new file mode 100644 (file)
index 0000000..d060a98
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * ============LICENSE_START=======================================================
+ * oom-certservice-k8s-external-provider
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package certserviceclient
+
+type CertServiceClientMock struct {
+       GetCertificatesFunc func(csr []byte, key []byte) (*CertificatesResponse, error)
+}
+
+func (client *CertServiceClientMock) GetCertificates(csr []byte, key []byte) (*CertificatesResponse, error) {
+       return client.GetCertificatesFunc(csr, key)
+}
+
+func (client *CertServiceClientMock) CheckHealth() error {
+       return nil
+}
index c6e0e1d..9bc41e7 100644 (file)
@@ -49,6 +49,7 @@ type CMPv2IssuerController struct {
        Log      logr.Logger
        Clock    clock.Clock
        Recorder record.EventRecorder
+       ProvisionerFactory provisioners.ProvisionerFactory
 }
 
 // Reconcile will read and validate the CMPv2Issuer resources, it will set the
@@ -84,7 +85,7 @@ func (controller *CMPv2IssuerController) Reconcile(req ctrl.Request) (ctrl.Resul
        }
 
        // 4. Create CMPv2 provisioner
-       provisioner, err := provisioners.CreateProvisioner(issuer, secret)
+       provisioner, err := controller.ProvisionerFactory.CreateProvisioner(issuer, secret)
        if err != nil {
                log.Error(err, "failed to initialize provisioner")
                statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, "Error", "Failed to initialize provisioner: %v", err)
index 79c78ed..88aaf5e 100644 (file)
@@ -24,14 +24,47 @@ import (
        "testing"
 
        "github.com/go-logr/logr"
+       certmanager "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
+       apiv1 "k8s.io/api/core/v1"
+       "k8s.io/apimachinery/pkg/runtime"
+       "k8s.io/apimachinery/pkg/types"
+       clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+       "k8s.io/client-go/tools/record"
+       "k8s.io/utils/clock"
+       ctrl "sigs.k8s.io/controller-runtime"
+       "sigs.k8s.io/controller-runtime/pkg/client"
+       "sigs.k8s.io/controller-runtime/pkg/client/fake"
+       "sigs.k8s.io/controller-runtime/pkg/reconcile"
 
        "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+       certserviceapi "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+       provisioners "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner"
+       "onap.org/oom-certservice/k8s-external-provider/src/testdata"
 )
 
+func Test_shouldPrepareAndVerifyCMPv2Issuer_whenRequestReceived(t *testing.T) {
+       scheme := initScheme()
+       issuer, secret := testdata.GetValidIssuerWithSecret()
+       fakeClient := getFakeClient(scheme, issuer, secret)
+       fakeRequest := getFakeRequest()
+       fakeRecorder := record.NewFakeRecorder(3)
+       controller := getController(fakeRecorder, fakeClient)
+
+       res, err := controller.Reconcile(fakeRequest)
+
+       expectedProvisioner, _ := controller.ProvisionerFactory.CreateProvisioner(&issuer, secret)
+       actualProvisioner, _ := provisioners.Load(types.NamespacedName{Name: testdata.IssuerObjectName, Namespace: testdata.Namespace})
+       assert.Nil(t, err)
+       assert.NotNil(t, res)
+       assert.Equal(t, <-fakeRecorder.Events, "Normal Verified CMPv2Issuer verified and ready to sign certificates")
+       assert.NotNil(t, actualProvisioner)
+       assert.ObjectsAreEqual(expectedProvisioner, actualProvisioner)
+}
+
 func Test_shouldBeValidCMPv2IssuerSpec_whenAllFieldsAreSet(t *testing.T) {
-       spec := getValidCMPv2IssuerSpec()
+       spec := testdata.GetValidCMPv2IssuerSpec()
 
        err := validateCMPv2IssuerSpec(spec, &MockLogger{})
        assert.Nil(t, err)
@@ -61,24 +94,46 @@ func Test_shouldBeInvalidCMPv2IssuerSpec_whenNotAllFieldsAreSet(t *testing.T) {
 }
 
 func test_shouldBeInvalidCMPv2IssuerSpec_whenFunctionApplied(t *testing.T, transformSpec func(spec *cmpv2api.CMPv2IssuerSpec)) {
-       spec := getValidCMPv2IssuerSpec()
+       spec := testdata.GetValidCMPv2IssuerSpec()
        transformSpec(&spec)
        err := validateCMPv2IssuerSpec(spec, nil)
        assert.NotNil(t, err)
 }
 
-func getValidCMPv2IssuerSpec() cmpv2api.CMPv2IssuerSpec {
-       issuerSpec := cmpv2api.CMPv2IssuerSpec{
-               URL:    "https://oom-cert-service:8443/v1/certificate/",
-               CaName: "RA",
-               CertSecretRef: cmpv2api.SecretKeySelector{
-                       Name:      "issuer-cert-secret",
-                       KeyRef:    "cmpv2Issuer-key.pem",
-                       CertRef:   "cmpv2Issuer-cert.pem",
-                       CacertRef: "cacert.pem",
+func getController(fakeRecorder *record.FakeRecorder, mockClient client.Client) CMPv2IssuerController {
+       controller := CMPv2IssuerController{
+               Log:                ctrl.Log.WithName("controllers").WithName("CertificateRequest"),
+               Clock:              clock.RealClock{},
+               Recorder:           fakeRecorder,
+               Client:             mockClient,
+               ProvisionerFactory: &provisioners.ProvisionerFactoryMock{},
+       }
+       return controller
+}
+
+func getFakeRequest() reconcile.Request {
+       fakeRequest := reconcile.Request{
+               NamespacedName: types.NamespacedName{
+                       Namespace: testdata.Namespace,
+                       Name:      testdata.IssuerObjectName,
                },
        }
-       return issuerSpec
+       return fakeRequest
+}
+
+func getFakeClient(scheme *runtime.Scheme, issuer cmpv2api.CMPv2Issuer, secret apiv1.Secret) client.Client {
+       fakeClient := func() client.Client {
+               return fake.NewFakeClientWithScheme(scheme, &issuer, &secret)
+       }()
+       return fakeClient
+}
+
+func initScheme() *runtime.Scheme {
+       scheme := runtime.NewScheme()
+       _ = clientgoscheme.AddToScheme(scheme)
+       _ = certmanager.AddToScheme(scheme)
+       _ = certserviceapi.AddToScheme(scheme)
+       return scheme
 }
 
 type MockLogger struct {
index 27f5c10..00abd2e 100644 (file)
@@ -29,7 +29,15 @@ import (
        "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
 )
 
-func CreateProvisioner(issuer *cmpv2api.CMPv2Issuer, secret v1.Secret) (*CertServiceCA, error) {
+
+type ProvisionerFactory interface {
+       CreateProvisioner(issuer *cmpv2api.CMPv2Issuer, secret v1.Secret) (*CertServiceCA, error)
+}
+
+type ProvisionerFactoryImpl struct {
+}
+
+func (f *ProvisionerFactoryImpl) CreateProvisioner(issuer *cmpv2api.CMPv2Issuer, secret v1.Secret) (*CertServiceCA, error) {
        secretKeys := issuer.Spec.CertSecretRef
        keyBase64, err := readValueFromSecret(secret, secretKeys.KeyRef)
        if err != nil {
diff --git a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_mock.go b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_mock.go
new file mode 100644 (file)
index 0000000..f2ffa86
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * ============LICENSE_START=======================================================
+ * oom-certservice-k8s-external-provider
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package cmpv2provisioner
+
+import (
+       v1 "k8s.io/api/core/v1"
+
+       "onap.org/oom-certservice/k8s-external-provider/src/certserviceclient"
+       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner/testdata"
+)
+
+type ProvisionerFactoryMock struct {
+       CreateProvisionerFunc func(issuer *cmpv2api.CMPv2Issuer, secret v1.Secret) (*CertServiceCA, error)
+}
+
+func (f *ProvisionerFactoryMock) CreateProvisioner(issuer *cmpv2api.CMPv2Issuer, secret v1.Secret) (*CertServiceCA, error) {
+       provisioner, err := New(issuer, &certserviceclient.CertServiceClientMock{
+               GetCertificatesFunc: func(csr []byte, pk []byte) (response *certserviceclient.CertificatesResponse, e error) {
+                       return &testdata.SampleCertServiceResponse, nil
+               },
+       })
+
+       return provisioner, err
+}
index be19bde..a7e975a 100644 (file)
@@ -26,105 +26,70 @@ import (
        "testing"
 
        "github.com/stretchr/testify/assert"
-       v1 "k8s.io/api/core/v1"
 
-       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
        "onap.org/oom-certservice/k8s-external-provider/src/testdata"
 )
 
-const (
-       secretName      = "issuer-cert-secret"
-       url             = "https://oom-cert-service:8443/v1/certificate/"
-       healthEndpoint  = "actuator/health"
-       certEndpoint    = "v1/certificate"
-       caName          = "RA"
-       keySecretKey    = "cmpv2Issuer-key.pem"
-       certSecretKey   = "cmpv2Issuer-cert.pem"
-       cacertSecretKey = "cacert.pem"
-)
-
 func Test_shouldCreateProvisioner(t *testing.T) {
-       issuer, secret := getValidIssuerAndSecret()
+       issuer, secret := testdata.GetValidIssuerWithSecret()
+       provisionerFactory := ProvisionerFactoryImpl{}
 
-       provisioner, _ := CreateProvisioner(&issuer, secret)
+       provisioner, _ := provisionerFactory.CreateProvisioner(&issuer, secret)
 
        assert.NotNil(t, provisioner)
-       assert.Equal(t, url, provisioner.url)
-       assert.Equal(t, caName, provisioner.caName)
-       assert.Equal(t, healthEndpoint, provisioner.healthEndpoint)
-       assert.Equal(t, certEndpoint, provisioner.certEndpoint)
+       assert.Equal(t, testdata.Url, provisioner.url)
+       assert.Equal(t, testdata.CaName, provisioner.caName)
+       assert.Equal(t, testdata.HealthEndpoint, provisioner.healthEndpoint)
+       assert.Equal(t, testdata.CertEndpoint, provisioner.certEndpoint)
 }
 
 func Test_shouldReturnError_whenSecretMissingKeyRef(t *testing.T) {
-       issuer, secret := getValidIssuerAndSecret()
-       delete(secret.Data, keySecretKey)
+       issuer, secret := testdata.GetValidIssuerWithSecret()
+       delete(secret.Data, testdata.KeySecretKey)
+       provisionerFactory := ProvisionerFactoryImpl{}
 
-       provisioner, err := CreateProvisioner(&issuer, secret)
+       provisioner, err := provisionerFactory.CreateProvisioner(&issuer, secret)
 
        assert.Nil(t, provisioner)
        if assert.Error(t, err) {
-               assert.Equal(t, fmt.Errorf("secret %s does not contain key %s", secretName, keySecretKey), err)
+               assert.Equal(t, fmt.Errorf("secret %s does not contain key %s", testdata.SecretName, testdata.KeySecretKey), err)
        }
 }
 
 func Test_shouldReturnError_whenSecretMissingCertRef(t *testing.T) {
-       issuer, secret := getValidIssuerAndSecret()
-       delete(secret.Data, certSecretKey)
+       issuer, secret := testdata.GetValidIssuerWithSecret()
+       delete(secret.Data, testdata.CertSecretKey)
+       provisionerFactory := ProvisionerFactoryImpl{}
 
-       provisioner, err := CreateProvisioner(&issuer, secret)
+       provisioner, err := provisionerFactory.CreateProvisioner(&issuer, secret)
 
        assert.Nil(t, provisioner)
        if assert.Error(t, err) {
-               assert.Equal(t, fmt.Errorf("secret %s does not contain key %s", secretName, certSecretKey), err)
+               assert.Equal(t, fmt.Errorf("secret %s does not contain key %s", testdata.SecretName, testdata.CertSecretKey), err)
        }
 }
 
 func Test_shouldReturnError_whenSecretMissingCacertRef(t *testing.T) {
-       issuer, secret := getValidIssuerAndSecret()
-       delete(secret.Data, cacertSecretKey)
+       issuer, secret := testdata.GetValidIssuerWithSecret()
+       delete(secret.Data, testdata.CacertSecretKey)
+       provisionerFactory := ProvisionerFactoryImpl{}
 
-       provisioner, err := CreateProvisioner(&issuer, secret)
+       provisioner, err := provisionerFactory.CreateProvisioner(&issuer, secret)
 
        assert.Nil(t, provisioner)
        if assert.Error(t, err) {
-               assert.Equal(t, fmt.Errorf("secret %s does not contain key %s", secretName, cacertSecretKey), err)
+               assert.Equal(t, fmt.Errorf("secret %s does not contain key %s", testdata.SecretName, testdata.CacertSecretKey), err)
        }
 }
 
 func Test_shouldReturnError_whenCreationOfCertServiceClientReturnsError(t *testing.T) {
-       issuer, secret := getValidIssuerAndSecret()
+       issuer, secret := testdata.GetValidIssuerWithSecret()
        invalidKeySecretValue, _ := base64.StdEncoding.DecodeString("")
-       secret.Data[keySecretKey] = invalidKeySecretValue
+       secret.Data[testdata.KeySecretKey] = invalidKeySecretValue
+       provisionerFactory := ProvisionerFactoryImpl{}
 
-       provisioner, err := CreateProvisioner(&issuer, secret)
+       provisioner, err := provisionerFactory.CreateProvisioner(&issuer, secret)
 
        assert.Nil(t, provisioner)
        assert.Error(t, err)
 }
-
-func getValidIssuerAndSecret() (cmpv2api.CMPv2Issuer, v1.Secret) {
-       issuer := cmpv2api.CMPv2Issuer{
-               Spec: cmpv2api.CMPv2IssuerSpec{
-                       URL:            url,
-                       HealthEndpoint: healthEndpoint,
-                       CertEndpoint:   certEndpoint,
-                       CaName:         caName,
-                       CertSecretRef: cmpv2api.SecretKeySelector{
-                               Name:      secretName,
-                               KeyRef:    keySecretKey,
-                               CertRef:   certSecretKey,
-                               CacertRef: cacertSecretKey,
-                       },
-               },
-       }
-       secret := v1.Secret{
-
-               Data: map[string][]byte{
-                       keySecretKey:    testdata.KeyBytes,
-                       certSecretKey:   testdata.CertBytes,
-                       cacertSecretKey: testdata.CacertBytes,
-               },
-       }
-       secret.Name = secretName
-       return issuer, secret
-}
index 099233c..a483c72 100644 (file)
@@ -30,12 +30,12 @@ import (
 
        cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
        "github.com/stretchr/testify/assert"
+       apiv1 "k8s.io/api/core/v1"
        apimach "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/types"
 
        "onap.org/oom-certservice/k8s-external-provider/src/certserviceclient"
        "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
-       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner/testdata"
 )
 
 const ISSUER_NAME = "cmpv2-issuer"
@@ -72,11 +72,8 @@ func Test_shouldReturnCorrectSignedPemsWhenParametersAreCorrect(t *testing.T) {
        const EXPECTED_TRUSTED_FILENAME = "testdata/expected_trusted.pem"
 
        issuer := createIssuerAndCerts(ISSUER_NAME, ISSUER_URL)
-       provisioner, err := New(&issuer, &certServiceClientMock{
-               getCertificatesFunc: func(csr []byte, pk []byte) (response *certserviceclient.CertificatesResponse, e error) {
-                       return &testdata.SampleCertServiceResponse, nil
-               },
-       })
+       provisionerFactory := ProvisionerFactoryMock{}
+       provisioner, err := provisionerFactory.CreateProvisioner(&issuer, apiv1.Secret{})
 
        issuerNamespaceName := createIssuerNamespaceName(ISSUER_NAMESPACE, ISSUER_NAME)
        Store(issuerNamespaceName, provisioner)
diff --git a/certServiceK8sExternalProvider/src/testdata/provider.go b/certServiceK8sExternalProvider/src/testdata/provider.go
new file mode 100644 (file)
index 0000000..2e352cb
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * ============LICENSE_START=======================================================
+ * oom-certservice-k8s-external-provider
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package testdata
+
+import (
+       "k8s.io/api/core/v1"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+)
+
+const (
+       SecretName       = "issuer-cert-secret"
+       Url              = "https://oom-cert-service:8443/v1/certificate/"
+       HealthEndpoint   = "actuator/health"
+       CertEndpoint     = "v1/certificate"
+       CaName           = "RA"
+       KeySecretKey     = "cmpv2Issuer-key.pem"
+       CertSecretKey    = "cmpv2Issuer-cert.pem"
+       CacertSecretKey  = "cacert.pem"
+       Namespace        = "default"
+       IssuerObjectName = "fakeIssuer"
+       Kind             = "CMPv2Issuer"
+       APIVersion       = "v1"
+)
+
+func GetValidIssuerWithSecret() (cmpv2api.CMPv2Issuer, v1.Secret) {
+       issuer := cmpv2api.CMPv2Issuer{
+
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: APIVersion,
+                       Kind:       Kind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      IssuerObjectName,
+                       Namespace: Namespace,
+               },
+               Spec: GetValidCMPv2IssuerSpec(),
+       }
+       secret := v1.Secret{
+
+               Data: map[string][]byte{
+                       KeySecretKey:    KeyBytes,
+                       CertSecretKey:   CertBytes,
+                       CacertSecretKey: CacertBytes,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      SecretName,
+                       Namespace: Namespace,
+               },
+       }
+       secret.Name = SecretName
+       return issuer, secret
+}
+
+func GetValidCMPv2IssuerSpec() cmpv2api.CMPv2IssuerSpec {
+       issuerSpec := cmpv2api.CMPv2IssuerSpec{
+               URL:            Url,
+               HealthEndpoint: HealthEndpoint,
+               CertEndpoint:   CertEndpoint,
+               CaName:         CaName,
+               CertSecretRef: cmpv2api.SecretKeySelector{
+                       Name:      SecretName,
+                       KeyRef:    KeySecretKey,
+                       CertRef:   CertSecretKey,
+                       CacertRef: CacertSecretKey,
+               },
+       }
+       return issuerSpec
+}
+