aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--certService/pom.xml4
-rw-r--r--certService/version.properties2
-rw-r--r--certServiceClient/pom.xml4
-rw-r--r--certServiceClient/version.properties2
-rw-r--r--certServiceK8sExternalProvider/README.md50
-rw-r--r--certServiceK8sExternalProvider/deploy/deployment.yaml1
-rw-r--r--certServiceK8sExternalProvider/go.mod4
-rw-r--r--certServiceK8sExternalProvider/main.go21
-rw-r--r--certServiceK8sExternalProvider/main_test.go8
-rw-r--r--certServiceK8sExternalProvider/pom.xml2
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller.go76
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller_test.go4
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go41
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go23
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger.go56
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger_test.go100
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/logger/testdata/test_logger_config.json11
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/updater/certificate_request_status_updater.go74
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/updater/cmpv2_issuer_status_updater.go (renamed from certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_status_updater.go)59
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater.go49
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater_test.go68
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2controller/updater/status_reason.go (renamed from certServiceK8sExternalProvider/src/cmpv2controller/status_reason.go)2
-rw-r--r--certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner.go20
-rw-r--r--certServiceK8sExternalProvider/src/leveledlogger/logger.go138
-rw-r--r--certServiceK8sExternalProvider/src/leveledlogger/logger_config.json13
-rw-r--r--certServiceK8sExternalProvider/src/leveledlogger/logger_test.go87
-rw-r--r--certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_debug.log4
-rw-r--r--certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_warn.log2
-rw-r--r--certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_debug.json11
-rw-r--r--certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_warn.json11
-rw-r--r--certServicePostProcessor/pom.xml4
-rw-r--r--docs/sections/release-notes.rst45
-rw-r--r--pom.xml2
-rw-r--r--releases/2.2.0-container.yaml16
-rw-r--r--version.properties4
35 files changed, 792 insertions, 226 deletions
diff --git a/certService/pom.xml b/certService/pom.xml
index 9cff262b..2c7b5d44 100644
--- a/certService/pom.xml
+++ b/certService/pom.xml
@@ -18,10 +18,10 @@
<parent>
<groupId>org.onap.oom.platform.cert-service</groupId>
<artifactId>oom-certservice</artifactId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
</parent>
<artifactId>oom-certservice-api</artifactId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
<name>oom-certservice-api</name>
<description>OOM Certification Service Api</description>
<packaging>jar</packaging>
diff --git a/certService/version.properties b/certService/version.properties
index 00ef5645..3ad2137c 100644
--- a/certService/version.properties
+++ b/certService/version.properties
@@ -1,4 +1,4 @@
-major=1
+major=2
minor=2
patch=0
base_version=${major}.${minor}.${patch}
diff --git a/certServiceClient/pom.xml b/certServiceClient/pom.xml
index 4c2bae90..9201b813 100644
--- a/certServiceClient/pom.xml
+++ b/certServiceClient/pom.xml
@@ -18,12 +18,12 @@
<parent>
<artifactId>oom-certservice</artifactId>
<groupId>org.onap.oom.platform.cert-service</groupId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>oom-certservice-client</artifactId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
<name>oom-certservice-client</name>
<description>OOM Certification Service Api Client</description>
<packaging>jar</packaging>
diff --git a/certServiceClient/version.properties b/certServiceClient/version.properties
index 00ef5645..3ad2137c 100644
--- a/certServiceClient/version.properties
+++ b/certServiceClient/version.properties
@@ -1,4 +1,4 @@
-major=1
+major=2
minor=2
patch=0
base_version=${major}.${minor}.${patch}
diff --git a/certServiceK8sExternalProvider/README.md b/certServiceK8sExternalProvider/README.md
index bb3e0b8c..ee739a3f 100644
--- a/certServiceK8sExternalProvider/README.md
+++ b/certServiceK8sExternalProvider/README.md
@@ -1,21 +1,32 @@
-## Cert Service k8s external cert signing provider
+## Cert Service K8s external provider
+
+### General description
+
+Cert Service K8s external provider ia a part of certificate distribution infrastructure in ONAP.
+The main functionality of the provider is to forward Certificate Signing Requests (CSRs) created by cert-mananger (https://cert-manager.io) to CertServiceAPI.
+
+More information can found on a dedicated page: https://wiki.onap.org/display/DW/CertService+and+K8s+Cert-Manager+integration.
### Build project
There are two methods for building the project:
- - mvn clean install
- - make
+ - mvn clean install (used by CI)
+ - make (used by DEV)
### Installation
+#### Providing K8s secret containing TLS certificates
+
Create secret with certificates for communication between CMPv2Issuer and Cert Service API:
```
kubectl create secret generic -n onap cmpv2-issuer-secret --from-file=<project-base-dir>/certs/cmpv2Issuer-key.pem
--from-file=<project-base-dir>/certs/cmpv2Issuer-cert.pem --from-file=<project-base-dir>/certs/cacert.pem
```
-Apply k8s files from 'deploy' directory in following order:
+#### Deployment of the application
+
+Apply K8s files from 'deploy' directory in following order:
- crd.yaml
- roles.yaml
@@ -25,18 +36,32 @@ Apply k8s files from 'deploy' directory in following order:
**Note:** Files and installation are currently examples, which should be used as a guide for OOM Helm Charts implementation
+#### Log level adjustment
+
+Log level can be set during deployment as docker container argument --> see deployment.yaml file.
+Here is an interesting part from the deployment.yaml file:
+
+ - args:
+ - --metrics-addr=127.0.0.1:8080
+ - --log-level=debug
+ command:
+ - /oom-certservice-cmpv2issuer
+ image: onap/oom-certservice-cmpv2issuer:1.0.0
+
+Supported values of log-level flag (case-sensitive): debug, info, warn, error
+
### Usage
-To issue a certificate adjust and apply following k8s file:
+To issue a certificate adjust and apply following K8s file:
- certificate_example.yaml
#### Unsupported Certificate fields
-Some of the fields present in Cert Manager Certificate are not currently supported by CertService API, because of that they are
-filtered from the Certificate Signing Request.
+Some fields present in Cert-Manager Certificate are currently not supported by CertService API and because of that they are
+filtered out from the Certificate Signing Request.
-**Filtered fields:**
+**Fields that are filtered out:**
- subjectDN fields:
- serialNumber
- streetAddresses
@@ -48,3 +73,12 @@ filtered from the Certificate Signing Request.
- duration
- usages
+ #### Overridden Certificate fields
+
+Some fields present in a Cert-Manager Certificate will be overridden by a CMPv2 server.
+
+**Overridden fields:**
+ - duration
+ - usages
+
+
diff --git a/certServiceK8sExternalProvider/deploy/deployment.yaml b/certServiceK8sExternalProvider/deploy/deployment.yaml
index 20dd65a8..e7073cf6 100644
--- a/certServiceK8sExternalProvider/deploy/deployment.yaml
+++ b/certServiceK8sExternalProvider/deploy/deployment.yaml
@@ -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
diff --git a/certServiceK8sExternalProvider/go.mod b/certServiceK8sExternalProvider/go.mod
index f4626d81..93fe45c2 100644
--- a/certServiceK8sExternalProvider/go.mod
+++ b/certServiceK8sExternalProvider/go.mod
@@ -28,14 +28,14 @@ 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
k8s.io/client-go v0.19.0
- k8s.io/klog/v2 v2.3.0
k8s.io/utils v0.0.0-20200729134348-d5654de09c73
sigs.k8s.io/controller-runtime v0.6.2
)
diff --git a/certServiceK8sExternalProvider/main.go b/certServiceK8sExternalProvider/main.go
index 430d4020..c649e3fc 100644
--- a/certServiceK8sExternalProvider/main.go
+++ b/certServiceK8sExternalProvider/main.go
@@ -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)
diff --git a/certServiceK8sExternalProvider/main_test.go b/certServiceK8sExternalProvider/main_test.go
index 0ad70246..83420d6f 100644
--- a/certServiceK8sExternalProvider/main_test.go
+++ b/certServiceK8sExternalProvider/main_test.go
@@ -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)
-
}
diff --git a/certServiceK8sExternalProvider/pom.xml b/certServiceK8sExternalProvider/pom.xml
index 0347db60..a34ffc3f 100644
--- a/certServiceK8sExternalProvider/pom.xml
+++ b/certServiceK8sExternalProvider/pom.xml
@@ -5,7 +5,7 @@
<parent>
<artifactId>oom-certservice</artifactId>
<groupId>org.onap.oom.platform.cert-service</groupId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller.go b/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller.go
index e5dc4d1c..cb667bd6 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller.go
@@ -29,10 +29,7 @@ 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"
core "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
@@ -42,20 +39,22 @@ import (
"onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
"onap.org/oom-certservice/k8s-external-provider/src/cmpv2controller/logger"
+ "onap.org/oom-certservice/k8s-external-provider/src/cmpv2controller/updater"
provisioners "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner"
+ "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
x509utils "onap.org/oom-certservice/k8s-external-provider/src/x509"
)
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
+ Client client.Client
Recorder record.EventRecorder
+ Log leveledlogger.Logger
}
// Reconcile will read and validate a CMPv2Issuer resource associated to the
@@ -63,10 +62,12 @@ 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)
+ certUpdater := updater.NewCertificateRequestUpdater(controller.Client, controller.Recorder, certificateRequest, ctx, log)
+
log.Info("Registered new certificate sign request: ", "cert-name", certificateRequest.Name)
if err := controller.Client.Get(ctx, k8sRequest.NamespacedName, certificateRequest); err != nil {
err = handleErrorResourceNotFound(log, err)
@@ -95,20 +96,20 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
Name: certificateRequest.Spec.IssuerRef.Name,
}
if err := controller.Client.Get(ctx, issuerNamespaceName, &issuer); err != nil {
- controller.handleErrorGettingCMPv2Issuer(ctx, log, err, certificateRequest, issuerNamespaceName, k8sRequest)
+ controller.handleErrorGettingCMPv2Issuer(certUpdater, log, err, certificateRequest, issuerNamespaceName, k8sRequest)
return ctrl.Result{}, err
}
// 5. Check if CMPv2Issuer is ready to sing certificates
if !isCMPv2IssuerReady(issuer) {
- err := controller.handleErrorCMPv2IssuerIsNotReady(ctx, log, issuerNamespaceName, certificateRequest, k8sRequest)
+ err := controller.handleErrorCMPv2IssuerIsNotReady(certUpdater, log, issuerNamespaceName, certificateRequest, k8sRequest)
return ctrl.Result{}, err
}
// 6. Load the provisioner that will sign the CertificateRequest
provisioner, ok := provisioners.Load(issuerNamespaceName)
if !ok {
- err := controller.handleErrorCouldNotLoadCMPv2Provisioner(ctx, log, issuerNamespaceName, certificateRequest)
+ err := controller.handleErrorCouldNotLoadCMPv2Provisioner(certUpdater, log, issuerNamespaceName)
return ctrl.Result{}, err
}
@@ -120,7 +121,7 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
}
var privateKeySecret core.Secret
if err := controller.Client.Get(ctx, privateKeySecretNamespaceName, &privateKeySecret); err != nil {
- controller.handleErrorGettingPrivateKey(ctx, log, err, certificateRequest, privateKeySecretNamespaceName)
+ controller.handleErrorGettingPrivateKey(certUpdater, log, err, privateKeySecretNamespaceName)
return ctrl.Result{}, err
}
privateKeyBytes := privateKeySecret.Data[privateKeySecretKey]
@@ -129,54 +130,36 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
log.Info("Decoding CSR...")
csr, err := x509utils.DecodeCSR(certificateRequest.Spec.Request)
if err != nil {
- controller.handleErrorFailedToDecodeCSR(ctx, log, err, certificateRequest)
+ controller.handleErrorFailedToDecodeCSR(certUpdater, log, err)
return ctrl.Result{}, err
}
// 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)
if err != nil {
- controller.handleErrorFailedToSignCertificate(ctx, log, err, certificateRequest)
+ controller.handleErrorFailedToSignCertificate(certUpdater, log, err)
return ctrl.Result{}, nil
}
// 11. Store signed certificates in CertificateRequest
certificateRequest.Status.Certificate = signedPEM
certificateRequest.Status.CA = trustedCAs
- if err := controller.updateCertificateRequestWithSignedCerficates(ctx, certificateRequest); err != nil {
+ if err := certUpdater.UpdateCertificateRequestWithSignedCertificates(); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
-func (controller *CertificateRequestController) updateCertificateRequestWithSignedCerficates(ctx context.Context, certificateRequest *cmapi.CertificateRequest) error {
- return controller.setStatus(ctx, certificateRequest, cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Certificate issued")
-}
-
func (controller *CertificateRequestController) SetupWithManager(manager ctrl.Manager) error {
return ctrl.NewControllerManagedBy(manager).
For(&cmapi.CertificateRequest{}).
Complete(controller)
}
-func (controller *CertificateRequestController) setStatus(ctx context.Context, certificateRequest *cmapi.CertificateRequest, status cmmeta.ConditionStatus, reason, message string, args ...interface{}) error {
- completeMessage := fmt.Sprintf(message, args...)
- apiutil.SetCertificateRequestCondition(certificateRequest, cmapi.CertificateRequestConditionReady, status, reason, completeMessage)
-
- // Fire an Event to additionally inform users of the change
- eventType := core.EventTypeNormal
- if status == cmmeta.ConditionFalse {
- eventType = core.EventTypeWarning
- }
- controller.Recorder.Event(certificateRequest, eventType, reason, completeMessage)
-
- return controller.Client.Status().Update(ctx, certificateRequest)
-}
-
func isCMPv2IssuerReady(issuer cmpv2api.CMPv2Issuer) bool {
condition := cmpv2api.CMPv2IssuerCondition{Type: cmpv2api.ConditionReady, Status: cmpv2api.ConditionTrue}
return hasCondition(issuer, condition)
@@ -201,42 +184,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(updater *updater.CertificateRequestStatusUpdater, log leveledlogger.Logger, issuerNamespaceName types.NamespacedName) 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)
+ _ = updater.UpdateStatusWithEventTypeWarning(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(updater *updater.CertificateRequestStatusUpdater, 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)
+ _ = updater.UpdateStatusWithEventTypeWarning(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(updater *updater.CertificateRequestStatusUpdater, 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)
+ _ = updater.UpdateStatusWithEventTypeWarning(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(updater *updater.CertificateRequestStatusUpdater, log leveledlogger.Logger, err error, 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)
+ _ = updater.UpdateStatusWithEventTypeWarning(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(updater *updater.CertificateRequestStatusUpdater, log leveledlogger.Logger, err error) {
log.Error(err, "Failed to sign certificate request")
- _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to sign certificate request: %v", err)
+ _ = updater.UpdateStatusWithEventTypeWarning(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(updater *updater.CertificateRequestStatusUpdater, log leveledlogger.Logger, err error) {
log.Error(err, "Failed to decode certificate sign request")
- _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to decode CSR: %v", err)
+ _ = updater.UpdateStatusWithEventTypeWarning(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 {
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller_test.go b/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller_test.go
index f5869ea2..24b6b89e 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller_test.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/certificate_request_controller_test.go
@@ -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
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go
index 9bc41e7f..3f3a4651 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller.go
@@ -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"
@@ -40,15 +39,17 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+ "onap.org/oom-certservice/k8s-external-provider/src/cmpv2controller/updater"
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
- Clock clock.Clock
- Recorder record.EventRecorder
+ Client client.Client
+ Log leveledlogger.Logger
+ Clock clock.Clock
+ Recorder record.EventRecorder
ProvisionerFactory provisioners.ProvisionerFactory
}
@@ -56,7 +57,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)
@@ -67,8 +68,8 @@ func (controller *CMPv2IssuerController) Reconcile(req ctrl.Request) (ctrl.Resul
log.Info("CMPv2Issuer loaded: ", "issuer", issuer)
// 2. Validate CMPv2Issuer
- statusUpdater := newStatusUpdater(controller, issuer, log)
- if err := validateCMPv2IssuerSpec(issuer.Spec, log); err != nil {
+ statusUpdater := updater.NewCMPv2IssuerStatusUpdater(controller.Client, controller.Recorder, issuer, controller.Clock, log)
+ if err := validateCMPv2IssuerSpec(issuer.Spec); err != nil {
handleErrorCMPv2IssuerValidation(ctx, log, err, statusUpdater)
return ctrl.Result{}, err
}
@@ -118,7 +119,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,36 +138,36 @@ func validateCMPv2IssuerSpec(issuerSpec cmpv2api.CMPv2IssuerSpec, log logr.Logge
}
}
-func updateCMPv2IssuerStatusToVerified(statusUpdater *CMPv2IssuerStatusUpdater, ctx context.Context, log logr.Logger) error {
+func updateCMPv2IssuerStatusToVerified(statusUpdater *updater.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")
+ return statusUpdater.Update(ctx, cmpv2api.ConditionTrue, updater.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 *updater.CMPv2IssuerStatusUpdater) {
log.Error(err, "Failed to initialize provisioner")
- statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, Error, "Failed to initialize provisioner: %v", err)
+ statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, updater.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 *updater.CMPv2IssuerStatusUpdater) {
log.Error(err, "Failed to validate CMPv2Issuer resource")
- statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, ValidationFailed, "Failed to validate resource: %v", err)
+ statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, updater.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 *updater.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)
+ statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, updater.NotFound, "Failed to retrieve provisioner secret: %v", err)
} else {
- statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, Error, "Failed to retrieve provisioner secret: %v", err)
+ statusUpdater.UpdateNoError(ctx, cmpv2api.ConditionFalse, updater.Error, "Failed to retrieve provisioner secret: %v", err)
}
}
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go
index f4cb6944..cc3ba9f5 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_controller_test.go
@@ -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 }
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger.go b/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger.go
index 0aaf48d3..649ce47f 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger.go
@@ -26,8 +26,9 @@ 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,28 +36,33 @@ const (
CMPv2ServerName = "CMPv2 Server"
)
-func LogCertRequestProperties(log logr.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
- logSupportedProperties(log, request, csr)
+func LogCertRequestProperties(log leveledlogger.Logger, request *cmapi.CertificateRequest, csr *x509.CertificateRequest) {
+ logSupportedProperties(log, csr)
logPropertiesNotSupportedByCertService(log, request, csr)
logPropertiesOverriddenByCMPv2Server(log, request)
}
-func logSupportedProperties(log logr.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")
- logSupportedProperty(log, csr.Subject.Province, "state")
- logSupportedProperty(log, csr.Subject.Locality, "location")
- logSupportedProperty(log, csr.DNSNames, "dns names")
+func logSupportedProperties(log leveledlogger.Logger, csr *x509.CertificateRequest) {
+ logSupportedSingleValueProperty(log, csr.Subject.CommonName, "common name")
+ logSupportedMultiValueProperty(log, csr.Subject.Organization, "organization")
+ logSupportedMultiValueProperty(log, csr.Subject.OrganizationalUnit, "organization unit")
+ logSupportedMultiValueProperty(log, csr.Subject.Country, "country")
+ logSupportedMultiValueProperty(log, csr.Subject.Province, "state")
+ logSupportedMultiValueProperty(log, csr.Subject.Locality, "location")
+ logSupportedMultiValueProperty(log, csr.DNSNames, "dns names")
}
-func logSupportedProperty(log logr.Logger, values []string, propertyName string) {
+func logSupportedMultiValueProperty(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 logSupportedSingleValueProperty(log leveledlogger.Logger, value string, propertyName string) {
+ log.Info(getSupportedMessage(propertyName, value))
+}
+
+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 +79,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))
}
}
@@ -131,14 +137,14 @@ func extractIPAddresses(addresses []net.IP) string {
return values
}
-func getNotSupportedMessage(property string, value string) string {
- return "WARNING: Property '" + property + "' with value: " + value + " is not supported by " + CertServiceName
+func getSupportedMessage(property string, value string) string {
+ return "+ property '" + property + "' with value '" + value + "' will be sent in certificate signing request to " + CMPv2ServerName
}
-func getSupportedMessage(property string, value string) string {
- return "Property '" + property + "' with value: " + value + " will be sent in certificate signing request to " + CMPv2ServerName
+func getNotSupportedMessage(property string, value string) string {
+ return "- property '" + property + "' with value '" + value + "' is not supported by " + CertServiceName
}
func getOverriddenMessage(property string, values string) string {
- return "Property '" + property + "' with value: " + values + " will be overridden by " + CMPv2ServerName
+ return "* property '" + property + "' with value '" + values + "' will be overridden by " + CMPv2ServerName
}
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger_test.go b/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger_test.go
index ea1076dc..250fab8b 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger_test.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/logger/certificate_request_logger_test.go
@@ -22,7 +22,8 @@ package logger
import (
"bytes"
- "flag"
+ "io/ioutil"
+ "log"
"os"
"strings"
"testing"
@@ -31,35 +32,40 @@ 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"
+ "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
x509utils "onap.org/oom-certservice/k8s-external-provider/src/x509"
)
-var checkedLogMessages = [7]string{"Property 'duration'", "Property 'usages'", "Property 'ipAddresses'",
- "Property 'isCA'", "Property 'subject.streetAddress'", "Property 'subject.postalCodes'",
- "Property 'subject.serialNumber'"}
-
-var supportedProperties = [7]string{"Property 'organization'", "Property 'organization unit'", "Property 'country'",
- "Property 'state'", "Property 'location'", "Property 'dns names'"}
-
+var unsupportedProperties = []string{
+ "* property 'duration'",
+ "* property 'usages'",
+ "- property 'ipAddresses'",
+ "- property 'isCA'",
+ "- property 'subject.streetAddress'",
+ "- property 'subject.postalCodes'",
+ "- property 'subject.serialNumber'"}
+
+var supportedProperties = []string{
+ "+ property 'common name'",
+ "+ 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 +74,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")
+ for _, logMsg := range unsupportedProperties {
+ assert.False(t, logsContainExpectedMessage(logsArray, logMsg), "Logs should not contain: ["+logMsg+"]")
}
+ 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 +95,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)
+ for _, logMsg := range unsupportedProperties {
+ assert.True(t, logsContainExpectedMessage(logsArray, logMsg), "Logs should 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 +116,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)
+ assert.True(t, logsContainExpectedMessage(logsArray, logMsg), "Logs should contain: ["+logMsg+"]")
}
+ removeTemporaryFile(RESULT_LOG)
}
func getCertificateRequestWithoutSkippedProperties() *cmapi.CertificateRequest {
@@ -135,18 +140,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
index 00000000..02030b6e
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/logger/testdata/test_logger_config.json
@@ -0,0 +1,11 @@
+{
+ "level": "debug",
+ "encoding": "json",
+ "outputPaths": ["stdout", "testdata/test_result.log"],
+ "encoderConfig": {
+ "messageKey": "message",
+ "levelKey": "level",
+ "nameKey": "name",
+ "levelEncoder": "capital"
+ }
+}
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/updater/certificate_request_status_updater.go b/certServiceK8sExternalProvider/src/cmpv2controller/updater/certificate_request_status_updater.go
new file mode 100644
index 00000000..d4ed0237
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/updater/certificate_request_status_updater.go
@@ -0,0 +1,74 @@
+/*
+ * ============LICENSE_START=======================================================
+ * oom-certservice-k8s-external-provider
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * This source code was copied from the following git repository:
+ * https://github.com/smallstep/step-issuer
+ * The source code was modified for usage in the ONAP project.
+ * ================================================================================
+ * 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 updater
+
+import (
+ "context"
+ "fmt"
+
+ 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"
+ "k8s.io/client-go/tools/record"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+
+ "onap.org/oom-certservice/k8s-external-provider/src/leveledlogger"
+)
+
+type CertificateRequestStatusUpdater struct {
+ client client.Client
+ recorder record.EventRecorder
+ logger leveledlogger.Logger
+ ctx context.Context
+ certificateRequest *cmapi.CertificateRequest
+}
+
+func NewCertificateRequestUpdater(client client.Client,
+ recorder record.EventRecorder, certificateRequest *cmapi.CertificateRequest, ctx context.Context, log leveledlogger.Logger) *CertificateRequestStatusUpdater {
+ return &CertificateRequestStatusUpdater{
+ client: client,
+ recorder: recorder,
+ logger: log,
+ ctx: ctx,
+ certificateRequest: certificateRequest,
+ }
+}
+
+func (instance *CertificateRequestStatusUpdater) UpdateStatusWithEventTypeWarning(reason string, message string, args ...interface{}) error {
+ return instance.updateStatus(cmmeta.ConditionFalse, reason, message, args...)
+}
+
+func (instance *CertificateRequestStatusUpdater) UpdateCertificateRequestWithSignedCertificates() error {
+ return instance.updateStatus(cmmeta.ConditionTrue, cmapi.CertificateRequestReasonIssued, "Certificate issued")
+}
+
+func (instance *CertificateRequestStatusUpdater) updateStatus(status cmmeta.ConditionStatus, reason string, message string, args ...interface{}) error {
+ completeMessage := fmt.Sprintf(message, args...)
+ apiutil.SetCertificateRequestCondition(instance.certificateRequest, cmapi.CertificateRequestConditionReady, status, reason, completeMessage)
+
+ FireEventCert(instance.recorder, instance.certificateRequest, status, reason, completeMessage)
+
+ return instance.client.Status().Update(instance.ctx, instance.certificateRequest)
+}
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_status_updater.go b/certServiceK8sExternalProvider/src/cmpv2controller/updater/cmpv2_issuer_status_updater.go
index f07101db..e11c2b02 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/cmpv2_issuer_status_updater.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/updater/cmpv2_issuer_status_updater.go
@@ -23,50 +23,51 @@
* ============LICENSE_END=========================================================
*/
-package cmpv2controller
+package updater
import (
"context"
"fmt"
- "github.com/go-logr/logr"
- core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/tools/record"
+ "k8s.io/utils/clock"
+ "sigs.k8s.io/controller-runtime/pkg/client"
"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
+ client client.Client
+ recorder record.EventRecorder
+ issuer *cmpv2api.CMPv2Issuer
+ clock clock.Clock
+ logger leveledlogger.Logger
}
-func newStatusUpdater(controller *CMPv2IssuerController, issuer *cmpv2api.CMPv2Issuer, log logr.Logger) *CMPv2IssuerStatusUpdater {
+func NewCMPv2IssuerStatusUpdater(client client.Client, recorder record.EventRecorder, issuer *cmpv2api.CMPv2Issuer, clock clock.Clock, log leveledlogger.Logger) *CMPv2IssuerStatusUpdater {
return &CMPv2IssuerStatusUpdater{
- CMPv2IssuerController: controller,
- issuer: issuer,
- logger: log,
+ client: client,
+ recorder: recorder,
+ issuer: issuer,
+ clock: clock,
+ logger: log,
}
}
-func (updater *CMPv2IssuerStatusUpdater) Update(ctx context.Context, status cmpv2api.ConditionStatus, reason, message string, args ...interface{}) error {
+func (instance *CMPv2IssuerStatusUpdater) Update(ctx context.Context, status cmpv2api.ConditionStatus, reason, message string, args ...interface{}) error {
completeMessage := fmt.Sprintf(message, args...)
- updater.setCondition(status, reason, completeMessage)
+ instance.setCondition(status, reason, completeMessage)
- // Fire an Event to additionally inform users of the change
- eventType := core.EventTypeNormal
- if status == cmpv2api.ConditionFalse {
- eventType = core.EventTypeWarning
- }
- updater.Recorder.Event(updater.issuer, eventType, reason, completeMessage)
+ FireEventIssuer(instance.recorder, instance.issuer, status, reason, completeMessage)
- return updater.Client.Update(ctx, updater.issuer)
+ return instance.client.Update(ctx, instance.issuer)
}
-func (updater *CMPv2IssuerStatusUpdater) UpdateNoError(ctx context.Context, status cmpv2api.ConditionStatus, reason, message string, args ...interface{}) {
- if err := updater.Update(ctx, status, reason, message, args...); err != nil {
- updater.logger.Error(err, "failed to update", "status", status, "reason", reason)
+func (instance *CMPv2IssuerStatusUpdater) UpdateNoError(ctx context.Context, status cmpv2api.ConditionStatus, reason, message string, args ...interface{}) {
+ if err := instance.Update(ctx, status, reason, message, args...); err != nil {
+ instance.logger.Error(err, "failed to update", "status", status, "reason", reason)
}
}
@@ -79,8 +80,8 @@ func (updater *CMPv2IssuerStatusUpdater) UpdateNoError(ctx context.Context, stat
// - If a condition of the same type and different state already exists, the
// condition will be updated and the LastTransitionTime set to the current
// time.
-func (updater *CMPv2IssuerStatusUpdater) setCondition(status cmpv2api.ConditionStatus, reason, message string) {
- now := meta.NewTime(updater.Clock.Now())
+func (instance *CMPv2IssuerStatusUpdater) setCondition(status cmpv2api.ConditionStatus, reason, message string) {
+ now := meta.NewTime(instance.clock.Now())
issuerCondition := cmpv2api.CMPv2IssuerCondition{
Type: cmpv2api.ConditionReady,
Status: status,
@@ -90,7 +91,7 @@ func (updater *CMPv2IssuerStatusUpdater) setCondition(status cmpv2api.ConditionS
}
// Search through existing conditions
- for i, condition := range updater.issuer.Status.Conditions {
+ for i, condition := range instance.issuer.Status.Conditions {
// Skip unrelated conditions
if condition.Type != cmpv2api.ConditionReady {
continue
@@ -101,16 +102,16 @@ func (updater *CMPv2IssuerStatusUpdater) setCondition(status cmpv2api.ConditionS
if condition.Status == status {
issuerCondition.LastTransitionTime = condition.LastTransitionTime
} else {
- updater.logger.Info("found status change for CMPv2Issuer condition; setting lastTransitionTime", "condition", condition.Type, "old_status", condition.Status, "new_status", status, "time", now.Time)
+ instance.logger.Info("found status change for CMPv2Issuer condition; setting lastTransitionTime", "condition", condition.Type, "old_status", condition.Status, "new_status", status, "time", now.Time)
}
// Overwrite the existing condition
- updater.issuer.Status.Conditions[i] = issuerCondition
+ instance.issuer.Status.Conditions[i] = issuerCondition
return
}
// If we've not found an existing condition of this type, we simply insert
// the new condition into the slice.
- updater.issuer.Status.Conditions = append(updater.issuer.Status.Conditions, issuerCondition)
- updater.logger.Info("setting lastTransitionTime for CMPv2Issuer condition", "condition", cmpv2api.ConditionReady, "time", now.Time)
+ instance.issuer.Status.Conditions = append(instance.issuer.Status.Conditions, issuerCondition)
+ instance.logger.Info("setting lastTransitionTime for CMPv2Issuer condition", "condition", cmpv2api.ConditionReady, "time", now.Time)
}
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater.go b/certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater.go
new file mode 100644
index 00000000..e638d84a
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater.go
@@ -0,0 +1,49 @@
+/*
+ * ============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 updater
+
+import (
+ core "k8s.io/api/core/v1"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/tools/record"
+
+ cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
+
+ "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+)
+
+// Fire an Event to additionally inform users of the change
+func FireEventCert(recorder record.EventRecorder, resource runtime.Object, status cmmeta.ConditionStatus, reason string, message string) {
+ eventType := core.EventTypeNormal
+ if status == cmmeta.ConditionFalse {
+ eventType = core.EventTypeWarning
+ }
+ recorder.Event(resource, eventType, reason, message)
+}
+
+func FireEventIssuer(recorder record.EventRecorder, resource runtime.Object, status cmpv2api.ConditionStatus, reason string, message string) {
+ eventType := core.EventTypeNormal
+ if status == cmpv2api.ConditionFalse {
+ eventType = core.EventTypeWarning
+ }
+ recorder.Event(resource, eventType, reason, message)
+}
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater_test.go b/certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater_test.go
new file mode 100644
index 00000000..553c419f
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater_test.go
@@ -0,0 +1,68 @@
+/*
+ * ============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 updater
+
+import (
+ "testing"
+
+ cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
+ "github.com/stretchr/testify/assert"
+ "k8s.io/client-go/tools/record"
+
+ "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+)
+
+const (
+ recorderBufferSize = 3
+)
+
+
+func Test_shouldFireWarningEvent_forCmpv2Issuer(t *testing.T) {
+ fakeRecorder := record.NewFakeRecorder(recorderBufferSize)
+
+ FireEventIssuer(fakeRecorder, nil, cmpv2api.ConditionFalse, "testReason", "testMessage")
+
+ assert.Equal(t, <-fakeRecorder.Events, "Warning testReason testMessage")
+}
+
+func Test_shouldFireNormalEvent_forCmpv2Issuer(t *testing.T) {
+ fakeRecorder := record.NewFakeRecorder(recorderBufferSize)
+
+ FireEventIssuer(fakeRecorder, nil, cmpv2api.ConditionTrue, "testReason", "testMessage")
+
+ assert.Equal(t, <-fakeRecorder.Events, "Normal testReason testMessage")
+}
+
+func Test_shouldFireWarningEvent_forCertRequest(t *testing.T) {
+ fakeRecorder := record.NewFakeRecorder(recorderBufferSize)
+
+ FireEventCert(fakeRecorder, nil, cmmeta.ConditionFalse, "testReason", "testMessage")
+
+ assert.Equal(t, <-fakeRecorder.Events, "Warning testReason testMessage")
+}
+
+func Test_shouldFireNormalEvent_forCertRequest(t *testing.T) {
+ fakeRecorder := record.NewFakeRecorder(recorderBufferSize)
+
+ FireEventCert(fakeRecorder, nil, cmmeta.ConditionTrue, "testReason", "testMessage")
+
+ assert.Equal(t, <-fakeRecorder.Events, "Normal testReason testMessage")
+}
diff --git a/certServiceK8sExternalProvider/src/cmpv2controller/status_reason.go b/certServiceK8sExternalProvider/src/cmpv2controller/updater/status_reason.go
index fc1772e9..8fe8664c 100644
--- a/certServiceK8sExternalProvider/src/cmpv2controller/status_reason.go
+++ b/certServiceK8sExternalProvider/src/cmpv2controller/updater/status_reason.go
@@ -18,7 +18,7 @@
* ============LICENSE_END=========================================================
*/
-package cmpv2controller
+package updater
const (
NotFound = "NotFound"
diff --git a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner.go b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner.go
index 14cb228f..e89eb1f4 100644
--- a/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner.go
+++ b/certServiceK8sExternalProvider/src/cmpv2provisioner/cmpv2_provisioner.go
@@ -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,26 +89,27 @@ 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("Original CSR PEM: ", "bytes", csrBytes)
filteredCsrBytes, err := csr.FilterFieldsFromCSR(csrBytes, privateKeyBytes)
if err != nil {
return nil, nil, err
}
+ log.Debug("Filtered out CSR PEM: ", "bytes", csrBytes)
response, err := ca.certServiceClient.GetCertificates(filteredCsrBytes, privateKeyBytes)
if err != nil {
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 +121,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
index 00000000..ee839cbc
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/leveledlogger/logger.go
@@ -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
index 00000000..96ba7024
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/leveledlogger/logger_config.json
@@ -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
index 00000000..84aa5907
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/leveledlogger/logger_test.go
@@ -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
index 00000000..25242eee
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_debug.log
@@ -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
index 00000000..b6a1985b
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_expected_warn.log
@@ -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
index 00000000..96ac5dc7
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_debug.json
@@ -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
index 00000000..a07bdb26
--- /dev/null
+++ b/certServiceK8sExternalProvider/src/leveledlogger/testdata/test_logger_config_warn.json
@@ -0,0 +1,11 @@
+{
+ "level": "warn",
+ "encoding": "console",
+ "outputPaths": ["stdout", "testdata/test_result_warn.log"],
+ "encoderConfig": {
+ "messageKey": "message",
+ "levelKey": "level",
+ "nameKey": "name",
+ "levelEncoder": "capital"
+ }
+}
diff --git a/certServicePostProcessor/pom.xml b/certServicePostProcessor/pom.xml
index 484531e9..0e3e1608 100644
--- a/certServicePostProcessor/pom.xml
+++ b/certServicePostProcessor/pom.xml
@@ -5,12 +5,12 @@
<parent>
<artifactId>oom-certservice</artifactId>
<groupId>org.onap.oom.platform.cert-service</groupId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>oom-certservice-post-processor</artifactId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
<name>oom-certservice-post-processor</name>
<description>An application which conducts certificate post-processing like: merging truststores, copying keystores.</description>
<packaging>jar</packaging>
diff --git a/docs/sections/release-notes.rst b/docs/sections/release-notes.rst
index a31bf810..f1c7eecb 100644
--- a/docs/sections/release-notes.rst
+++ b/docs/sections/release-notes.rst
@@ -7,6 +7,51 @@ Release Notes
==============
+Version: 2.2.0
+--------------
+
+:Release Date:
+
+**New Features**
+
+* Added module **oom-certservice-k8s-external-provider** with following functionality:
+
+ An external provider is a part of PKI infrastructure. It consumes CertificateRequest CRD from Cert-Manager and calls CertService API to enroll certificate from CMPv2 server.
+
+ More information can be found on dedicated `wiki page <https://wiki.onap.org/display/DW/CertService+and+K8s+Cert-Manager+integration>`_
+
+**Bug Fixes**
+
+ N/A
+
+**Known Issues**
+
+ N/A
+
+**Security Notes**
+
+ N/A
+
+*Fixed Security Issues*
+
+ N/A
+
+*Known Security Issues*
+
+ N/A
+
+*Known Vulnerabilities in Used Modules*
+
+ N/A
+
+**Upgrade Notes**
+
+**Deprecation Notes**
+
+**Other**
+
+==============
+
Version: 2.1.0
--------------
diff --git a/pom.xml b/pom.xml
index a867349f..179b7712 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
</parent>
<groupId>org.onap.oom.platform.cert-service</groupId>
<artifactId>oom-certservice</artifactId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
<name>oom-certservice</name>
<description>OOM Certification Service</description>
<packaging>pom</packaging>
diff --git a/releases/2.2.0-container.yaml b/releases/2.2.0-container.yaml
new file mode 100644
index 00000000..07164cd6
--- /dev/null
+++ b/releases/2.2.0-container.yaml
@@ -0,0 +1,16 @@
+distribution_type: 'container'
+container_release_tag: '2.2.0'
+container_pull_registry: nexus3.onap.org:10003
+container_push_registry: nexus3.onap.org:10002
+project: 'oom-platform-cert-service'
+log_dir: 'oom-platform-cert-service-maven-docker-stage-master/118'
+ref: c3c260ac52d12a8a2bcec9c3e2451c48d388ecec
+containers:
+ - name: 'org.onap.oom.platform.cert-service.oom-certservice-api'
+ version: '2.2.0-20201112T134226Z'
+ - name: 'org.onap.oom.platform.cert-service.oom-certservice-client'
+ version: '2.2.0-20201112T134226Z'
+ - name: 'org.onap.oom.platform.cert-service.oom-certservice-post-processor'
+ version: '2.2.0-20201112T134226Z'
+ - name: 'org.onap.oom.platform.cert-service.oom-certservice-k8s-external-provider'
+ version: '2.2.0-20201112T134226Z'
diff --git a/version.properties b/version.properties
index 3c5fba7f..3ad2137c 100644
--- a/version.properties
+++ b/version.properties
@@ -1,6 +1,6 @@
major=2
-minor=1
-patch=1
+minor=2
+patch=0
base_version=${major}.${minor}.${patch}
release_version=${base_version}
snapshot_version=${base_version}-SNAPSHOT