[OOM-K8S-CERT-EXTERNAL-PROVIDER] Change logger implementation provider 50/114450/14
authorJoanna Jeremicz <joanna.jeremicz@nokia.com>
Fri, 30 Oct 2020 16:06:04 +0000 (17:06 +0100)
committerJoanna Jeremicz <joanna.jeremicz@nokia.com>
Thu, 5 Nov 2020 12:53:05 +0000 (13:53 +0100)
Issue-ID: OOM-2559
Signed-off-by: Joanna Jeremicz <joanna.jeremicz@nokia.com>
Change-Id: I717dfcfd74a01ccb81b2eb03c52be2c90fc3a9c5

20 files changed:
certServiceK8sExternalProvider/deploy/deployment.yaml
certServiceK8sExternalProvider/go.mod
certServiceK8sExternalProvider/main.go
certServiceK8sExternalProvider/main_test.go
certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller.go
certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller_test.go
certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go
certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go
certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_status_updater.go
certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger.go
certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger_test.go
certServiceK8sExternalProvider/src/cmpv2controller/logger/testdata/test_logger_config.json [new file with mode: 0644]
certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner.go
certServiceK8sExternalProvider/src/leveledlogger/logger.go [new file with mode: 0644]
certServiceK8sExternalProvider/src/leveledlogger/logger_config.json [new file with mode: 0644]
certServiceK8sExternalProvider/src/leveledlogger/logger_test.go [new file with mode: 0644]
certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_debug.log [new file with mode: 0644]
certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_warn.log [new file with mode: 0644]
certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_debug.json [new file with mode: 0644]
certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_warn.json [new file with mode: 0644]

index 20dd65a..e7073cf 100644 (file)
@@ -72,6 +72,7 @@ spec:
           name: https
       - args:
         - --metrics-addr=127.0.0.1:8080
+        - --log-level=debug
         command:
         - /oom-certservice-cmpv2issuer
         image: onap/oom-certservice-cmpv2issuer:1.0.0
index f4626d8..6930590 100644 (file)
@@ -28,9 +28,10 @@ go 1.15
 
 require (
        github.com/go-logr/logr v0.2.1
-       github.com/go-logr/zapr v0.2.0 // indirect
+       github.com/go-logr/zapr v0.2.0
        github.com/jetstack/cert-manager v1.0.3
        github.com/stretchr/testify v1.6.1
+       go.uber.org/zap v1.10.0
        gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e // indirect
        k8s.io/api v0.19.0
        k8s.io/apimachinery v0.19.0
index 430d402..c649e3f 100644 (file)
@@ -36,32 +36,35 @@ import (
        _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
        "k8s.io/utils/clock"
        ctrl "sigs.k8s.io/controller-runtime"
-       "sigs.k8s.io/controller-runtime/pkg/log/zap"
        "sigs.k8s.io/controller-runtime/pkg/manager"
 
        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"
+       "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
 )
 
 var (
        scheme   = runtime.NewScheme()
-       setupLog = ctrl.Log.WithName("setup")
+       setupLog leveledlogger.Logger
 )
 
 func init() {
        _ = clientgoscheme.AddToScheme(scheme)
        _ = certmanager.AddToScheme(scheme)
        _ = certserviceapi.AddToScheme(scheme)
+       setupLog = leveledlogger.GetLogger()
 
-       ctrl.SetLogger(zap.New(zap.UseDevMode(true)))
+       ctrl.SetLogger(setupLog.Log)
 }
 
 func main() {
        printVersionInfo()
 
-       metricsAddr, enableLeaderElection := parseInputArguments()
+       metricsAddr, logLevel, enableLeaderElection := parseInputArguments()
+
+       leveledlogger.SetLogLevel(logLevel)
 
        manager := createControllerManager(metricsAddr, enableLeaderElection)
 
@@ -79,15 +82,17 @@ func printVersionInfo() {
        fmt.Println()
 }
 
-func parseInputArguments() (string, bool) {
+func parseInputArguments() (string, string, bool) {
        setupLog.Info("Parsing input arguments...")
        var metricsAddr string
+       var logLevel string
        var enableLeaderElection bool
        flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
+       flag.StringVar(&logLevel, "log-level", "debug", "Min. level for logs visibility. One of: debug, info, warn, error")
        flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
                "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
        flag.Parse()
-       return metricsAddr, enableLeaderElection
+       return metricsAddr, logLevel, enableLeaderElection
 }
 
 func startControllerManager(manager manager.Manager) {
@@ -115,7 +120,7 @@ func registerCMPv2IssuerController(manager manager.Manager) {
 
        err := (&controllers.CMPv2IssuerController{
                Client:   manager.GetClient(),
-               Log:      ctrl.Log.WithName("controllers").WithName("CMPv2Issuer"),
+               Log:      leveledlogger.GetLoggerWithValues("controllers", "CMPv2Issuer"),
                Clock:    clock.RealClock{},
                Recorder: manager.GetEventRecorderFor("cmpv2-issuer-controller"),
                ProvisionerFactory: &cmpv2provisioner.ProvisionerFactoryImpl{},
@@ -131,7 +136,7 @@ func registerCertificateRequestController(manager manager.Manager) {
 
        err := (&controllers.CertificateRequestController{
                Client:   manager.GetClient(),
-               Log:      ctrl.Log.WithName("controllers").WithName("CertificateRequest"),
+               Log:      leveledlogger.GetLoggerWithValues("controllers", "CertificateRequest"),
                Recorder: manager.GetEventRecorderFor("certificate-requests-controller"),
        }).SetupWithManager(manager)
 
index 0ad7024..83420d6 100644 (file)
@@ -33,9 +33,10 @@ func Test_shouldParseArguments_defaultValues(t *testing.T) {
                "first-arg-is-omitted-by-method-parse-arguments-so-this-only-a-placeholder"}
        flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
 
-       metricsAddr, enableLeaderElection := parseInputArguments()
+       metricsAddr, logLevel, enableLeaderElection := parseInputArguments()
 
        assert.Equal(t, ":8080", metricsAddr)
+       assert.Equal(t, "debug", logLevel)
        assert.False(t, enableLeaderElection)
 }
 
@@ -43,12 +44,13 @@ func Test_shouldParseArguments_valuesFromCLI(t *testing.T) {
        os.Args = []string{
                "first-arg-is-omitted-by-method-parse-arguments-so-this-only-a-placeholder",
                "--metrics-addr=127.0.0.1:555",
+               "--log-level=error",
                "--enable-leader-election=true"}
        flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
 
-       metricsAddr, enableLeaderElection := parseInputArguments()
+       metricsAddr, logLevel, enableLeaderElection := parseInputArguments()
 
        assert.Equal(t, "127.0.0.1:555", metricsAddr)
+       assert.Equal(t, "error", logLevel)
        assert.True(t, enableLeaderElection)
-
 }
index e5dc4d1..2933b49 100644 (file)
@@ -29,7 +29,6 @@ import (
        "context"
        "fmt"
 
-       "github.com/go-logr/logr"
        apiutil "github.com/jetstack/cert-manager/pkg/api/util"
        cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
        cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
@@ -40,6 +39,7 @@ import (
        ctrl "sigs.k8s.io/controller-runtime"
        "sigs.k8s.io/controller-runtime/pkg/client"
 
+       "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
        "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
        "onap.org/oom-certservice/k8s-external-provider/src/cmpv2controller/logger"
        provisioners "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner"
@@ -48,13 +48,13 @@ import (
 
 const (
        privateKeySecretNameAnnotation = "cert-manager.io/private-key-secret-name"
-       privateKeySecretKey = "tls.key"
+       privateKeySecretKey            = "tls.key"
 )
 
 // CertificateRequestController reconciles a CMPv2Issuer object.
 type CertificateRequestController struct {
        client.Client
-       Log      logr.Logger
+       Log      leveledlogger.Logger
        Recorder record.EventRecorder
 }
 
@@ -63,7 +63,7 @@ type CertificateRequestController struct {
 // provisioner in the CMPv2Issuer.
 func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Request) (ctrl.Result, error) {
        ctx := context.Background()
-       log := controller.Log.WithValues("certificate-request-controller", k8sRequest.NamespacedName)
+       log := leveledlogger.GetLoggerWithValues("certificate-request-controller", k8sRequest.NamespacedName)
 
        // 1. Fetch the CertificateRequest resource being reconciled.
        certificateRequest := new(cmapi.CertificateRequest)
@@ -134,7 +134,7 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
        }
 
        // 9. Log Certificate Request properties not supported or overridden by CertService API
-       logger.LogCertRequestProperties(ctrl.Log.WithName("CSR details"), certificateRequest, csr)
+       logger.LogCertRequestProperties(leveledlogger.GetLoggerWithName("CSR details"), certificateRequest, csr)
 
        // 10. Sign CertificateRequest
        signedPEM, trustedCAs, err := provisioner.Sign(ctx, certificateRequest, privateKeyBytes)
@@ -201,42 +201,41 @@ func isCMPv2CertificateRequest(certificateRequest *cmapi.CertificateRequest) boo
 
 // Error handling
 
-func (controller *CertificateRequestController) handleErrorCouldNotLoadCMPv2Provisioner(ctx context.Context, log logr.Logger, issuerNamespaceName types.NamespacedName, certificateRequest *cmapi.CertificateRequest) error {
+func (controller *CertificateRequestController) handleErrorCouldNotLoadCMPv2Provisioner(ctx context.Context, log leveledlogger.Logger, issuerNamespaceName types.NamespacedName, certificateRequest *cmapi.CertificateRequest) error {
        err := fmt.Errorf("provisioner %s not found", issuerNamespaceName)
        log.Error(err, "Failed to load CMPv2 Provisioner resource")
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to load provisioner for CMPv2Issuer resource %s", issuerNamespaceName)
        return err
 }
 
-func (controller *CertificateRequestController) handleErrorCMPv2IssuerIsNotReady(ctx context.Context, log logr.Logger, issuerNamespaceName types.NamespacedName, certificateRequest *cmapi.CertificateRequest, req ctrl.Request) error {
+func (controller *CertificateRequestController) handleErrorCMPv2IssuerIsNotReady(ctx context.Context, log leveledlogger.Logger, issuerNamespaceName types.NamespacedName, certificateRequest *cmapi.CertificateRequest, req ctrl.Request) error {
        err := fmt.Errorf("resource %s is not ready", issuerNamespaceName)
        log.Error(err, "CMPv2Issuer not ready", "namespace", req.Namespace, "name", certificateRequest.Spec.IssuerRef.Name)
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "CMPv2Issuer resource %s is not Ready", issuerNamespaceName)
        return err
 }
 
-func (controller *CertificateRequestController) handleErrorGettingCMPv2Issuer(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest, issuerNamespaceName types.NamespacedName, req ctrl.Request) {
+func (controller *CertificateRequestController) handleErrorGettingCMPv2Issuer(ctx context.Context, log leveledlogger.Logger, err error, certificateRequest *cmapi.CertificateRequest, issuerNamespaceName types.NamespacedName, req ctrl.Request) {
        log.Error(err, "Failed to retrieve CMPv2Issuer resource", "namespace", req.Namespace, "name", certificateRequest.Spec.IssuerRef.Name)
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to retrieve CMPv2Issuer resource %s: %v", issuerNamespaceName, err)
 }
 
-func (controller *CertificateRequestController) handleErrorGettingPrivateKey(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest, pkSecretNamespacedName types.NamespacedName) {
+func (controller *CertificateRequestController) handleErrorGettingPrivateKey(ctx context.Context, log leveledlogger.Logger, err error, certificateRequest *cmapi.CertificateRequest, pkSecretNamespacedName types.NamespacedName) {
        log.Error(err, "Failed to retrieve private key secret for certificate request", "namespace", pkSecretNamespacedName.Namespace, "name", pkSecretNamespacedName.Name)
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to retrieve private key secret: %v", err)
 }
 
-func (controller *CertificateRequestController) handleErrorFailedToSignCertificate(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest) {
+func (controller *CertificateRequestController) handleErrorFailedToSignCertificate(ctx context.Context, log leveledlogger.Logger, err error, certificateRequest *cmapi.CertificateRequest) {
        log.Error(err, "Failed to sign certificate request")
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to sign certificate request: %v", err)
 }
 
-func (controller *CertificateRequestController) handleErrorFailedToDecodeCSR(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest) {
+func (controller *CertificateRequestController) handleErrorFailedToDecodeCSR(ctx context.Context, log leveledlogger.Logger, err error, certificateRequest *cmapi.CertificateRequest) {
        log.Error(err, "Failed to decode certificate sign request")
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to decode CSR: %v", err)
 }
 
-
-func handleErrorResourceNotFound(log logr.Logger, err error) error {
+func handleErrorResourceNotFound(log leveledlogger.Logger, err error) error {
        if apierrors.IsNotFound(err) {
                log.Error(err, "CertificateRequest resource not found")
        } else {
index f5869ea..24b6b89 100644 (file)
@@ -31,13 +31,13 @@ import (
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/types"
        "k8s.io/client-go/tools/record"
-       ctrl "sigs.k8s.io/controller-runtime"
        "sigs.k8s.io/controller-runtime/pkg/client"
        "sigs.k8s.io/controller-runtime/pkg/client/fake"
 
        "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
        provisioners "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner"
        provisionersdata "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner/csr/testdata"
+       "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
        "onap.org/oom-certservice/k8s-external-provider/src/testdata"
        x509 "onap.org/oom-certservice/k8s-external-provider/src/x509/testdata"
 )
@@ -141,7 +141,7 @@ func getValidCertificateRequest() *cmapi.CertificateRequest {
 func getCertRequestController(fakeRecorder *record.FakeRecorder, fakeClient client.Client) CertificateRequestController {
        controller := CertificateRequestController{
                Client:   fakeClient,
-               Log:      ctrl.Log.WithName("controllers").WithName("CertificateRequest"),
+               Log:      leveledlogger.GetLoggerWithValues("controllers", "CertificateRequest"),
                Recorder: fakeRecorder,
        }
        return controller
index 9bc41e7..32403c8 100644 (file)
@@ -29,7 +29,6 @@ import (
        "context"
        "fmt"
 
-       "github.com/go-logr/logr"
        core "k8s.io/api/core/v1"
        apierrors "k8s.io/apimachinery/pkg/api/errors"
        "k8s.io/apimachinery/pkg/runtime"
@@ -41,12 +40,13 @@ import (
 
        "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/leveledlogger"
 )
 
 // CMPv2IssuerController reconciles a CMPv2Issuer object
 type CMPv2IssuerController struct {
        client.Client
-       Log      logr.Logger
+       Log      leveledlogger.Logger
        Clock    clock.Clock
        Recorder record.EventRecorder
        ProvisionerFactory provisioners.ProvisionerFactory
@@ -56,7 +56,7 @@ type CMPv2IssuerController struct {
 // status condition ready to true if everything is right.
 func (controller *CMPv2IssuerController) Reconcile(req ctrl.Request) (ctrl.Result, error) {
        ctx := context.Background()
-       log := controller.Log.WithValues("cmpv2-issuer-controller", req.NamespacedName)
+       log := leveledlogger.GetLoggerWithValues("cmpv2-issuer-controller", req.NamespacedName)
 
        // 1. Load CMPv2Issuer
        issuer := new(cmpv2api.CMPv2Issuer)
@@ -68,7 +68,7 @@ func (controller *CMPv2IssuerController) Reconcile(req ctrl.Request) (ctrl.Resul
 
        // 2. Validate CMPv2Issuer
        statusUpdater := newStatusUpdater(controller, issuer, log)
-       if err := validateCMPv2IssuerSpec(issuer.Spec, log); err != nil {
+       if err := validateCMPv2IssuerSpec(issuer.Spec); err != nil {
                handleErrorCMPv2IssuerValidation(ctx, log, err, statusUpdater)
                return ctrl.Result{}, err
        }
@@ -118,7 +118,7 @@ func (controller *CMPv2IssuerController) loadResource(ctx context.Context, key c
        return controller.Client.Get(ctx, key, obj)
 }
 
-func validateCMPv2IssuerSpec(issuerSpec cmpv2api.CMPv2IssuerSpec, log logr.Logger) error {
+func validateCMPv2IssuerSpec(issuerSpec cmpv2api.CMPv2IssuerSpec) error {
        switch {
        case issuerSpec.URL == "":
                return fmt.Errorf("spec.url cannot be empty")
@@ -137,32 +137,32 @@ func validateCMPv2IssuerSpec(issuerSpec cmpv2api.CMPv2IssuerSpec, log logr.Logge
        }
 }
 
-func updateCMPv2IssuerStatusToVerified(statusUpdater *CMPv2IssuerStatusUpdater, ctx context.Context, log logr.Logger) error {
+func updateCMPv2IssuerStatusToVerified(statusUpdater *CMPv2IssuerStatusUpdater, ctx context.Context, log leveledlogger.Logger) error {
        log.Info("CMPv2 provisioner created -> updating status to of CMPv2Issuer resource to: Verified")
        return statusUpdater.Update(ctx, cmpv2api.ConditionTrue, Verified, "CMPv2Issuer verified and ready to sign certificates")
 }
 
 // Error handling
 
-func handleErrorUpdatingCMPv2IssuerStatus(log logr.Logger, err error) {
+func handleErrorUpdatingCMPv2IssuerStatus(log leveledlogger.Logger, err error) {
        log.Error(err, "Failed to update CMPv2Issuer status")
 }
 
-func handleErrorLoadingCMPv2Issuer(log logr.Logger, err error) {
+func handleErrorLoadingCMPv2Issuer(log leveledlogger.Logger, err error) {
        log.Error(err, "Failed to retrieve CMPv2Issuer resource")
 }
 
-func handleErrorProvisionerInitialization(ctx context.Context, log logr.Logger, err error, statusUpdater *CMPv2IssuerStatusUpdater) {
+func handleErrorProvisionerInitialization(ctx context.Context, log leveledlogger.Logger, err error, statusUpdater *CMPv2IssuerStatusUpdater) {
        log.Error(err, "Failed to initialize provisioner")
        statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, Error, "Failed to initialize provisioner: %v", err)
 }
 
-func handleErrorCMPv2IssuerValidation(ctx context.Context, log logr.Logger, err error, statusUpdater *CMPv2IssuerStatusUpdater) {
+func handleErrorCMPv2IssuerValidation(ctx context.Context, log leveledlogger.Logger, err error, statusUpdater *CMPv2IssuerStatusUpdater) {
        log.Error(err, "Failed to validate CMPv2Issuer resource")
        statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, ValidationFailed, "Failed to validate resource: %v", err)
 }
 
-func handleErrorInvalidSecret(ctx context.Context, log logr.Logger, err error, statusUpdater *CMPv2IssuerStatusUpdater, secretNamespaceName types.NamespacedName) {
+func handleErrorInvalidSecret(ctx context.Context, log leveledlogger.Logger, err error, statusUpdater *CMPv2IssuerStatusUpdater, secretNamespaceName types.NamespacedName) {
        log.Error(err, "Failed to retrieve CMPv2Issuer provisioner secret", "namespace", secretNamespaceName.Namespace, "name", secretNamespaceName.Name)
        if apierrors.IsNotFound(err) {
                statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, NotFound, "Failed to retrieve provisioner secret: %v", err)
index f4cb694..cc3ba9f 100644 (file)
@@ -23,17 +23,15 @@ package cmpv2controller
 import (
        "testing"
 
-       "github.com/go-logr/logr"
        "github.com/stretchr/testify/assert"
-       "github.com/stretchr/testify/mock"
        "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"
 
        "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/leveledlogger"
        "onap.org/oom-certservice/k8s-external-provider/src/testdata"
 )
 
@@ -60,13 +58,13 @@ func Test_shouldPrepareAndVerifyCMPv2Issuer_whenRequestReceived(t *testing.T) {
 func Test_shouldBeValidCMPv2IssuerSpec_whenAllFieldsAreSet(t *testing.T) {
        spec := testdata.GetValidCMPv2IssuerSpec()
 
-       err := validateCMPv2IssuerSpec(spec, &MockLogger{})
+       err := validateCMPv2IssuerSpec(spec)
        assert.Nil(t, err)
 }
 
 func Test_shouldBeInvalidCMPv2IssuerSpec_whenSpecIsEmpty(t *testing.T) {
        spec := cmpv2api.CMPv2IssuerSpec{}
-       err := validateCMPv2IssuerSpec(spec, nil)
+       err := validateCMPv2IssuerSpec(spec)
        assert.NotNil(t, err)
 }
 
@@ -90,13 +88,13 @@ func Test_shouldBeInvalidCMPv2IssuerSpec_whenNotAllFieldsAreSet(t *testing.T) {
 func test_shouldBeInvalidCMPv2IssuerSpec_whenFunctionApplied(t *testing.T, transformSpec func(spec *cmpv2api.CMPv2IssuerSpec)) {
        spec := testdata.GetValidCMPv2IssuerSpec()
        transformSpec(&spec)
-       err := validateCMPv2IssuerSpec(spec, nil)
+       err := validateCMPv2IssuerSpec(spec)
        assert.NotNil(t, err)
 }
 
 func getCMPv2IssuerController(fakeRecorder *record.FakeRecorder, mockClient client.Client) CMPv2IssuerController {
        controller := CMPv2IssuerController{
-               Log:                ctrl.Log.WithName("controllers").WithName("CertificateRequest"),
+               Log:                leveledlogger.GetLoggerWithValues("controllers", "CMPv2Issuer"),
                Clock:              clock.RealClock{},
                Recorder:           fakeRecorder,
                Client:             mockClient,
@@ -104,14 +102,3 @@ func getCMPv2IssuerController(fakeRecorder *record.FakeRecorder, mockClient clie
        }
        return controller
 }
-
-type MockLogger struct {
-       mock.Mock
-}
-
-func (m *MockLogger) Info(msg string, keysAndValues ...interface{})             {}
-func (m *MockLogger) Error(err error, msg string, keysAndValues ...interface{}) {}
-func (m *MockLogger) Enabled() bool                                             { return false }
-func (m *MockLogger) V(level int) logr.Logger                                   { return m }
-func (m *MockLogger) WithValues(keysAndValues ...interface{}) logr.Logger       { return m }
-func (m *MockLogger) WithName(name string) logr.Logger                          { return m }
index f07101d..400d1f0 100644 (file)
@@ -29,20 +29,20 @@ import (
        "context"
        "fmt"
 
-       "github.com/go-logr/logr"
        core "k8s.io/api/core/v1"
        meta "k8s.io/apimachinery/pkg/apis/meta/v1"
 
        "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+       "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
 )
 
 type CMPv2IssuerStatusUpdater struct {
        *CMPv2IssuerController
        issuer *cmpv2api.CMPv2Issuer
-       logger logr.Logger
+       logger leveledlogger.Logger
 }
 
-func newStatusUpdater(controller *CMPv2IssuerController, issuer *cmpv2api.CMPv2Issuer, log logr.Logger) *CMPv2IssuerStatusUpdater {
+func newStatusUpdater(controller *CMPv2IssuerController, issuer *cmpv2api.CMPv2Issuer, log leveledlogger.Logger) *CMPv2IssuerStatusUpdater {
        return &CMPv2IssuerStatusUpdater{
                CMPv2IssuerController: controller,
                issuer:                issuer,
index 0aaf48d..786557c 100644 (file)
@@ -26,8 +26,8 @@ import (
        "net/url"
        "strconv"
 
-       "github.com/go-logr/logr"
        cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
+       "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
 )
 
 const (
@@ -35,13 +35,13 @@ const (
        CMPv2ServerName = "CMPv2 Server"
 )
 
-func LogCertRequestProperties(log logr.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
+func LogCertRequestProperties(log leveledlogger.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
        logSupportedProperties(log, request, csr)
        logPropertiesNotSupportedByCertService(log, request, csr)
        logPropertiesOverriddenByCMPv2Server(log, request)
 }
 
-func logSupportedProperties(log logr.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
+func logSupportedProperties(log leveledlogger.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
        logSupportedProperty(log, csr.Subject.Organization, "organization")
        logSupportedProperty(log, csr.Subject.OrganizationalUnit, "organization unit")
        logSupportedProperty(log, csr.Subject.Country, "country")
@@ -50,13 +50,13 @@ func logSupportedProperties(log logr.Logger, request *cmapi.CertificateRequest,
        logSupportedProperty(log, csr.DNSNames, "dns names")
 }
 
-func logSupportedProperty(log logr.Logger, values []string, propertyName string) {
+func logSupportedProperty(log leveledlogger.Logger, values []string, propertyName string) {
        if len(values) > 0 {
                log.Info(getSupportedMessage(propertyName, extractStringArray(values)))
        }
 }
 
-func logPropertiesOverriddenByCMPv2Server(log logr.Logger, request *cmapi.CertificateRequest) {
+func logPropertiesOverriddenByCMPv2Server(log leveledlogger.Logger, request *cmapi.CertificateRequest) {
        if request.Spec.Duration != nil && len(request.Spec.Duration.String()) > 0 {
                log.Info(getOverriddenMessage("duration", request.Spec.Duration.Duration.String()))
        }
@@ -73,36 +73,36 @@ func extractUsages(usages []cmapi.KeyUsage) string {
        return values
 }
 
-func logPropertiesNotSupportedByCertService(log logr.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
+func logPropertiesNotSupportedByCertService(log leveledlogger.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
 
        //IP addresses in SANs
        if len(csr.IPAddresses) > 0 {
-               log.Info(getNotSupportedMessage("ipAddresses", extractIPAddresses(csr.IPAddresses)))
+               log.Warning(getNotSupportedMessage("ipAddresses", extractIPAddresses(csr.IPAddresses)))
        }
        //URIs in SANs
        if len(csr.URIs) > 0 {
-               log.Info(getNotSupportedMessage("uris", extractURIs(csr.URIs)))
+               log.Warning(getNotSupportedMessage("uris", extractURIs(csr.URIs)))
        }
 
        //Email addresses in SANs
        if len(csr.EmailAddresses) > 0 {
-               log.Info(getNotSupportedMessage("emailAddresses", extractStringArray(csr.EmailAddresses)))
+               log.Warning(getNotSupportedMessage("emailAddresses", extractStringArray(csr.EmailAddresses)))
        }
 
        if request.Spec.IsCA == true {
-               log.Info(getNotSupportedMessage("isCA", strconv.FormatBool(request.Spec.IsCA)))
+               log.Warning(getNotSupportedMessage("isCA", strconv.FormatBool(request.Spec.IsCA)))
        }
 
        if len(csr.Subject.StreetAddress) > 0 {
-               log.Info(getNotSupportedMessage("subject.streetAddress", extractStringArray(csr.Subject.StreetAddress)))
+               log.Warning(getNotSupportedMessage("subject.streetAddress", extractStringArray(csr.Subject.StreetAddress)))
        }
 
        if len(csr.Subject.PostalCode) > 0 {
-               log.Info(getNotSupportedMessage("subject.postalCodes", extractStringArray(csr.Subject.PostalCode)))
+               log.Warning(getNotSupportedMessage("subject.postalCodes", extractStringArray(csr.Subject.PostalCode)))
        }
 
        if len(csr.Subject.SerialNumber) > 0 {
-               log.Info(getNotSupportedMessage("subject.serialNumber", csr.Subject.SerialNumber))
+               log.Warning(getNotSupportedMessage("subject.serialNumber", csr.Subject.SerialNumber))
        }
 
 }
index ea1076d..e6a4d0e 100644 (file)
@@ -22,7 +22,9 @@ package logger
 
 import (
        "bytes"
-       "flag"
+
+       "io/ioutil"
+       "log"
        "os"
        "strings"
        "testing"
@@ -31,10 +33,9 @@ import (
        cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
        "github.com/stretchr/testify/assert"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-       "k8s.io/klog/v2"
-       "k8s.io/klog/v2/klogr"
 
        x509utils "onap.org/oom-certservice/k8s-external-provider/src/x509"
+       "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
 )
 
 var checkedLogMessages = [7]string{"Property 'duration'", "Property 'usages'", "Property 'ipAddresses'",
@@ -44,22 +45,17 @@ var checkedLogMessages = [7]string{"Property 'duration'", "Property 'usages'", "
 var supportedProperties = [7]string{"Property 'organization'", "Property 'organization unit'", "Property 'country'",
        "Property 'state'", "Property 'location'", "Property 'dns names'"}
 
+const RESULT_LOG = "testdata/test_result.log"
 
 func TestMain(m *testing.M) {
-       klog.InitFlags(nil)
-       flag.CommandLine.Set("v", "10")
-       flag.CommandLine.Set("skip_headers", "true")
-       flag.CommandLine.Set("logtostderr", "false")
-       flag.CommandLine.Set("alsologtostderr", "false")
-       flag.Parse()
+       leveledlogger.SetConfigFileName("testdata/test_logger_config.json")
        os.Exit(m.Run())
 }
 
 func TestLogShouldNotProvideInformationAboutSkippedPropertiesIfNotExistInCSR(t *testing.T) {
        //given
-       logger := klogr.New()
+       logger := leveledlogger.GetLoggerWithName("test")
        request := getCertificateRequestWithoutSkippedProperties()
-       tmpWriteBuffer := getLogBuffer()
 
        csr, err := x509utils.DecodeCSR(request.Spec.Request)
        if err != nil {
@@ -68,19 +64,19 @@ func TestLogShouldNotProvideInformationAboutSkippedPropertiesIfNotExistInCSR(t *
 
        //when
        LogCertRequestProperties(logger, request, csr)
-       closeLogBuffer()
-       logsArray := convertBufferToStringArray(tmpWriteBuffer)
+       logsArray := convertLogFileToStringArray(RESULT_LOG)
+
        //then
        for _, logMsg := range checkedLogMessages {
                assert.False(t, logsContainExpectedMessage(logsArray, logMsg), "Logs contain: "+logMsg+", but should not")
        }
+       removeTemporaryFile(RESULT_LOG)
 }
 
 func TestLogShouldProvideInformationAboutSkippedPropertiesIfExistInCSR(t *testing.T) {
        //given
-       logger := klogr.New()
+       logger := leveledlogger.GetLoggerWithName("test")
        request := getCertificateRequestWithSkippedProperties()
-       tmpWriteBuffer := getLogBuffer()
 
        csr, err := x509utils.DecodeCSR(request.Spec.Request)
        if err != nil {
@@ -89,20 +85,19 @@ func TestLogShouldProvideInformationAboutSkippedPropertiesIfExistInCSR(t *testin
 
        //when
        LogCertRequestProperties(logger, request, csr)
-       closeLogBuffer()
-       logsArray := convertBufferToStringArray(tmpWriteBuffer)
+       logsArray := convertLogFileToStringArray(RESULT_LOG)
 
        //then
        for _, logMsg := range checkedLogMessages {
                assert.True(t, logsContainExpectedMessage(logsArray, logMsg), "Logs not contain: "+logMsg)
        }
+       removeTemporaryFile(RESULT_LOG)
 }
 
 func TestLogShouldListSupportedProperties(t *testing.T) {
        //given
-       logger := klogr.New()
+       logger := leveledlogger.GetLoggerWithName("test")
        request := getCertificateRequestWithoutSkippedProperties()
-       tmpWriteBuffer := getLogBuffer()
 
        csr, err := x509utils.DecodeCSR(request.Spec.Request)
        if err != nil {
@@ -111,13 +106,13 @@ func TestLogShouldListSupportedProperties(t *testing.T) {
 
        //when
        LogCertRequestProperties(logger, request, csr)
-       closeLogBuffer()
-       logsArray := convertBufferToStringArray(tmpWriteBuffer)
+       logsArray := convertLogFileToStringArray(RESULT_LOG)
 
        //then
        for _, logMsg := range supportedProperties {
                assert.True(t, logsContainExpectedMessage(logsArray, logMsg), "Logs not contain: "+logMsg)
        }
+       removeTemporaryFile(RESULT_LOG)
 }
 
 func getCertificateRequestWithoutSkippedProperties() *cmapi.CertificateRequest {
@@ -135,18 +130,31 @@ func getCertificateRequestWithSkippedProperties() *cmapi.CertificateRequest {
        return request
 }
 
-func getLogBuffer() *bytes.Buffer {
-       tmpWriteBuffer := bytes.NewBuffer(nil)
-       klog.SetOutput(tmpWriteBuffer)
-       return tmpWriteBuffer
+func convertBufferToStringArray(buffer *bytes.Buffer) []string {
+       return strings.Split(buffer.String(), "\n")
 }
 
-func closeLogBuffer() {
-       klog.Flush()
+func convertLogFileToStringArray(filename string) []string {
+       buffer := bytes.NewBuffer(make([]byte, 0))
+       buffer.Write(readFile(filename))
+       return convertBufferToStringArray(buffer)
 }
 
-func convertBufferToStringArray(buffer *bytes.Buffer) []string {
-       return strings.Split(buffer.String(), "\n")
+func readFile(filename string) []byte {
+       certRequest, err := ioutil.ReadFile(filename)
+       if err != nil {
+               log.Fatal(err)
+       }
+       return certRequest
+}
+
+func removeTemporaryFile(fileName string) {
+       if _, err := os.Stat(fileName); err == nil {
+               e := os.Remove(fileName)
+               if e != nil {
+                       log.Fatal(e)
+               }
+       }
 }
 
 func logsContainExpectedMessage(array []string, expectedMsg string) bool {
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/logger/testdata/test_logger_config.json b/certServiceK8sExternalProvider/src/cmpv2controller/logger/testdata/test_logger_config.json
new file mode 100644 (file)
index 0000000..02030b6
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "level": "debug",
+  "encoding": "json",
+  "outputPaths": ["stdout", "testdata/test_result.log"],
+  "encoderConfig": {
+    "messageKey": "message",
+    "levelKey": "level",
+    "nameKey": "name",
+    "levelEncoder": "capital"
+  }
+}
index 14cb228..dc5532a 100644 (file)
@@ -31,8 +31,8 @@ import (
 
        certmanager "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
        "k8s.io/apimachinery/pkg/types"
-       ctrl "sigs.k8s.io/controller-runtime"
 
+       "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
        "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/csr"
@@ -59,14 +59,14 @@ func New(cmpv2Issuer *cmpv2api.CMPv2Issuer, certServiceClient certserviceclient.
        ca.certEndpoint = cmpv2Issuer.Spec.CertEndpoint
        ca.certServiceClient = certServiceClient
 
-       log := ctrl.Log.WithName("cmpv2-provisioner")
+       log := leveledlogger.GetLoggerWithName("cmpv2-provisioner")
        log.Info("Configuring CA: ", "name", ca.name, "url", ca.url, "caName", ca.caName, "healthEndpoint", ca.healthEndpoint, "certEndpoint", ca.certEndpoint)
 
        return &ca, nil
 }
 
 func (ca *CertServiceCA) CheckHealth() error {
-       log := ctrl.Log.WithName("cmpv2-provisioner")
+       log := leveledlogger.GetLoggerWithName("cmpv2-provisioner")
        log.Info("Checking health of CMPv2 issuer: ", "name", ca.name)
        return ca.certServiceClient.CheckHealth()
 }
@@ -89,13 +89,13 @@ func (ca *CertServiceCA) Sign(
        certificateRequest *certmanager.CertificateRequest,
        privateKeyBytes []byte,
 ) (signedCertificateChain []byte, trustedCertificates []byte, err error) {
-       log := ctrl.Log.WithName("certservice-provisioner")
+       log := leveledlogger.GetLoggerWithName("certservice-provisioner")
        log.Info("Signing certificate: ", "cert-name", certificateRequest.Name)
 
        log.Info("CA: ", "name", ca.name, "url", ca.url)
 
        csrBytes := certificateRequest.Spec.Request
-       log.Info("Csr PEM: ", "bytes", csrBytes)
+       log.Debug("Csr PEM: ", "bytes", csrBytes)
 
        filteredCsrBytes, err := csr.FilterFieldsFromCSR(csrBytes, privateKeyBytes)
        if err != nil {
@@ -107,8 +107,8 @@ func (ca *CertServiceCA) Sign(
                return nil, nil, err
        }
        log.Info("Successfully received response from CertService API")
-       log.Info("Certificate Chain", "cert-chain", response.CertificateChain)
-       log.Info("Trusted Certificates", "trust-certs", response.TrustedCertificates)
+       log.Debug("Certificate Chain", "cert-chain", response.CertificateChain)
+       log.Debug("Trusted Certificates", "trust-certs", response.TrustedCertificates)
 
        log.Info("Start parsing response")
        signedCertificateChain, trustedCertificates, signErr := parseResponseToBytes(response)
@@ -120,9 +120,8 @@ func (ca *CertServiceCA) Sign(
 
        log.Info("Successfully signed: ", "cert-name", certificateRequest.Name)
 
-       //TODO Debug level or skip
-       log.Info("Signed cert PEM: ", "bytes", signedCertificateChain)
-       log.Info("Trusted CA  PEM: ", "bytes", trustedCertificates)
+       log.Debug("Signed cert PEM: ", "bytes", signedCertificateChain)
+       log.Debug("Trusted CA  PEM: ", "bytes", trustedCertificates)
 
        return signedCertificateChain, trustedCertificates, nil
 }
diff --git a/certServiceK8sExternalProvider/src/leveledlogger/logger.go b/certServiceK8sExternalProvider/src/leveledlogger/logger.go
new file mode 100644 (file)
index 0000000..ee839cb
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * ============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 leveledlogger
+
+import (
+       "encoding/json"
+       "fmt"
+       "io/ioutil"
+       "log"
+
+       "github.com/go-logr/logr"
+       "go.uber.org/zap/zapcore"
+       "github.com/go-logr/zapr"
+       "go.uber.org/zap"
+)
+
+const (
+       WARNING = int(zapcore.WarnLevel) * -1
+       INFO    = int(zapcore.InfoLevel) * -1
+       DEBUG   = int(zapcore.DebugLevel) * -1
+)
+
+type Logger struct {
+       Log logr.Logger
+       ConfigFile string
+}
+
+var configFileName = "default"
+var logLevel = "warn"
+
+func SetConfigFileName(newName string) {
+       configFileName = newName
+}
+
+func SetLogLevel(level string) {
+       logLevel = level
+}
+
+func GetLogger() Logger {
+       var cfg zap.Config
+
+       if err := json.Unmarshal(getConfig(), &cfg); err != nil {
+               panic(err)
+       }
+       logger, err := cfg.Build()
+       if err != nil {
+               panic(err)
+       }
+
+       leveledLogger := Logger{
+               Log: zapr.NewLogger(logger),
+       }
+       return leveledLogger
+}
+
+func GetLoggerWithValues(keysAndValues ...interface{}) Logger {
+       leveledLogger := GetLogger()
+       leveledLogger.Log = leveledLogger.Log.WithValues(keysAndValues...)
+       return leveledLogger
+}
+
+func GetLoggerWithName(name string) Logger {
+       leveledLogger := GetLogger()
+       leveledLogger.Log = leveledLogger.Log.WithName(name)
+       return leveledLogger
+}
+
+func (logger *Logger) Error(err error, message string, keysAndValues ...interface{}) {
+       logger.Log.Error(err, message, keysAndValues...)
+}
+
+func (logger *Logger) Warning(message string, keysAndValues ...interface{}) {
+       logger.log(message, WARNING, keysAndValues...)
+}
+
+func (logger *Logger) Info(message string, keysAndValues ...interface{}) {
+       logger.log(message, INFO, keysAndValues...)
+}
+
+func (logger *Logger) Debug(message string, keysAndValues ...interface{}) {
+       logger.log(message, DEBUG, keysAndValues...)
+}
+
+func (logger *Logger) log(message string, lvl int, keysAndValues ...interface{}) {
+       logger.Log.V(lvl).Info(message, keysAndValues...)
+}
+
+func getDefaultConfig() []byte {
+       return []byte(fmt.Sprintf(`{
+               "level": "%s",
+               "encoding": "console",
+               "outputPaths": ["stdout"],
+               "encoderConfig": {
+               "timeKey": "timeKey",
+               "messageKey": "message",
+               "levelKey": "level",
+               "nameKey": "name",
+               "levelEncoder": "capital",
+               "timeEncoder": "iso8601"
+               }
+               }`, logLevel))
+}
+
+func getConfig() []byte {
+       var config = []byte{}
+       if configFileName == "default" {
+               config = getDefaultConfig()
+       } else {
+               config = readFile(configFileName)
+       }
+       return config
+}
+
+func readFile(filename string) []byte {
+       certRequest, err := ioutil.ReadFile(filename)
+       if err != nil {
+               log.Fatal(err)
+       }
+       return certRequest
+}
diff --git a/certServiceK8sExternalProvider/src/leveledlogger/logger_config.json b/certServiceK8sExternalProvider/src/leveledlogger/logger_config.json
new file mode 100644 (file)
index 0000000..96ba702
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "level": "debug",
+  "encoding": "console",
+  "outputPaths": ["stdout"],
+  "encoderConfig": {
+    "timeKey": "timeKey",
+    "messageKey": "message",
+    "levelKey": "level",
+    "nameKey": "name",
+    "levelEncoder": "capital",
+    "timeEncoder": "iso8601"
+  }
+}
diff --git a/certServiceK8sExternalProvider/src/leveledlogger/logger_test.go b/certServiceK8sExternalProvider/src/leveledlogger/logger_test.go
new file mode 100644 (file)
index 0000000..84aa590
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * ============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 leveledlogger
+
+import (
+       "bytes"
+       "fmt"
+       "log"
+       "os"
+       "testing"
+)
+
+func TestLoggerOnWarningLevel(t *testing.T) {
+       const resultLogName = "testdata/test_result_warn.log"
+       const expectedLogName = "testdata/test_expected_warn.log"
+
+       SetConfigFileName("testdata/test_logger_config_warn.json")
+       logger := GetLoggerWithName("loggername")
+
+       logOnAllLevels(logger)
+
+       resultLogBytes := readFile(resultLogName)
+       expectedLogBytes := readFile(expectedLogName)
+
+       assertLogEquals(t, resultLogBytes, expectedLogBytes, resultLogName)
+}
+
+func TestLoggerOnDebugLevel(t *testing.T) {
+       const resultLogName = "testdata/test_result_debug.log"
+       const expectedLogName = "testdata/test_expected_debug.log"
+
+       SetConfigFileName("testdata/test_logger_config_debug.json")
+       logger := GetLoggerWithName("loggername")
+
+    logOnAllLevels(logger)
+
+       resultLogBytes := readFile(resultLogName)
+       expectedLogBytes := readFile(expectedLogName)
+
+       assertLogEquals(t, resultLogBytes, expectedLogBytes, resultLogName)
+}
+
+func logOnAllLevels(logger Logger) {
+       logger.Debug("this is a debug message")
+       logger.Info("this is an info message")
+       logger.Warning("this is a warning message", "key1", "value1")
+       logger.Error(fmt.Errorf("this is an error message"), "err msg")
+}
+
+func assertLogEquals(t *testing.T, resultLogBytes []byte, expectedLogBytes []byte, resultLogName string) {
+       if areEqual(resultLogBytes, expectedLogBytes) {
+               removeTemporaryFile(resultLogName)
+       } else {
+               t.Fatal("Logs are different than expected. Please check: " + resultLogName)
+       }
+}
+
+func areEqual(slice1 []byte, slice2 []byte) bool {
+       return bytes.Compare(slice1, slice2) == 0
+}
+
+func removeTemporaryFile(fileName string) {
+       if _, err := os.Stat(fileName); err == nil {
+               e := os.Remove(fileName)
+               if e != nil {
+                       log.Fatal(e)
+               }
+       }
+}
diff --git a/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_debug.log b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_debug.log
new file mode 100644 (file)
index 0000000..25242ee
--- /dev/null
@@ -0,0 +1,4 @@
+DEBUG  loggername      this is a debug message
+INFO   loggername      this is an info message
+WARN   loggername      this is a warning message       {"key1": "value1"}
+ERROR  loggername      err msg {"error": "this is an error message"}
diff --git a/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_warn.log b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_warn.log
new file mode 100644 (file)
index 0000000..b6a1985
--- /dev/null
@@ -0,0 +1,2 @@
+WARN   loggername      this is a warning message       {"key1": "value1"}
+ERROR  loggername      err msg {"error": "this is an error message"}
diff --git a/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_debug.json b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_debug.json
new file mode 100644 (file)
index 0000000..96ac5dc
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "level": "debug",
+  "encoding": "console",
+  "outputPaths": ["stdout", "testdata/test_result_debug.log"],
+  "encoderConfig": {
+    "messageKey": "message",
+    "levelKey": "level",
+    "nameKey": "name",
+    "levelEncoder": "capital"
+  }
+}
diff --git a/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_warn.json b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_warn.json
new file mode 100644 (file)
index 0000000..a07bdb2
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "level": "warn",
+  "encoding": "console",
+  "outputPaths": ["stdout", "testdata/test_result_warn.log"],
+  "encoderConfig": {
+    "messageKey": "message",
+    "levelKey": "level",
+    "nameKey": "name",
+    "levelEncoder": "capital"
+  }
+}