diff options
author | Piotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com> | 2020-10-30 11:02:51 +0100 |
---|---|---|
committer | Piotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com> | 2020-11-04 08:54:32 +0100 |
commit | a7a7e91bb5ea9363272697c39eee0b62d21585ec (patch) | |
tree | 3e297d8ae81cafb8eb775844cfeb26c3f710a55f /certServiceK8sExternalProvider | |
parent | 9879e0147fc076114c7226bd6130d25c14770639 (diff) |
[OOM-K8S-CERT-EXTERNAL-PROVIDER] Add CMPv2IssuerController test
- Add Reconcile test in CMPv2IssuerController
Issue-ID: OOM-2559
Signed-off-by: Piotr Marcinkiewicz <piotr.marcinkiewicz@nokia.com>
Change-Id: I49aff7bc36f7da4df7eeaebaca144ee5a5bb9853
Diffstat (limited to 'certServiceK8sExternalProvider')
9 files changed, 274 insertions, 81 deletions
diff --git a/certServiceK8sExternalProvider/main.go b/certServiceK8sExternalProvider/main.go index 57058e9e..430d4020 100644 --- a/certServiceK8sExternalProvider/main.go +++ b/certServiceK8sExternalProvider/main.go @@ -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 index 00000000..d060a980 --- /dev/null +++ b/certServiceK8sExternalProvider/src/certserviceclient/cert_service_client_mock.go @@ -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 +} diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go index c6e0e1da..9bc41e7f 100644 --- a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go +++ b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go @@ -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) diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go index 79c78ed5..88aaf5ec 100644 --- a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go +++ b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go @@ -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 { diff --git a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory.go b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory.go index 27f5c108..00abd2ea 100644 --- a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory.go +++ b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory.go @@ -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 index 00000000..f2ffa860 --- /dev/null +++ b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_mock.go @@ -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 +} diff --git a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_test.go b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_test.go index be19bde9..a7e975a4 100644 --- a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_test.go +++ b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_factory_test.go @@ -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 -} diff --git a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_test.go b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_test.go index 099233c4..a483c72c 100644 --- a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_test.go +++ b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner_test.go @@ -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 index 00000000..2e352cbf --- /dev/null +++ b/certServiceK8sExternalProvider/src/testdata/provider.go @@ -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 +} + |