From 1815faa0ee14d5c27105a39f641a5b46939e72f8 Mon Sep 17 00:00:00 2001 From: Jan Malkiewicz Date: Thu, 5 Nov 2020 15:25:12 +0100 Subject: [OOM-K8S-CERT-EXTERNAL-PROVIDER] Refactoring & code improvements Issue-ID: OOM-2559 Signed-off-by: Jan Malkiewicz Change-Id: I52c38aacf064682f0018ac37b1400893bd9e53fc --- .../updater/certificate_request_status_updater.go | 74 +++++++++++++ .../updater/cmpv2_issuer_status_updater.go | 117 +++++++++++++++++++++ .../updater/k8s_resource_updater.go | 49 +++++++++ .../updater/k8s_resource_updater_test.go | 68 ++++++++++++ .../src/cmpv2controller/updater/status_reason.go | 28 +++++ 5 files changed, 336 insertions(+) create mode 100644 certServiceK8sExternalProvider/src/cmpv2controller/updater/certificate_request_status_updater.go create mode 100644 certServiceK8sExternalProvider/src/cmpv2controller/updater/cmpv2_issuer_status_updater.go create mode 100644 certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater.go create mode 100644 certServiceK8sExternalProvider/src/cmpv2controller/updater/k8s_resource_updater_test.go create mode 100644 certServiceK8sExternalProvider/src/cmpv2controller/updater/status_reason.go (limited to 'certServiceK8sExternalProvider/src/cmpv2controller/updater') 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/updater/cmpv2_issuer_status_updater.go b/certServiceK8sExternalProvider/src/cmpv2controller/updater/cmpv2_issuer_status_updater.go new file mode 100644 index 00000000..e11c2b02 --- /dev/null +++ b/certServiceK8sExternalProvider/src/cmpv2controller/updater/cmpv2_issuer_status_updater.go @@ -0,0 +1,117 @@ +/* + * ============LICENSE_START======================================================= + * oom-certservice-k8s-external-provider + * ================================================================================ + * Copyright (c) 2019 Smallstep Labs, Inc. + * Modifications 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" + + 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 { + client client.Client + recorder record.EventRecorder + issuer *cmpv2api.CMPv2Issuer + clock clock.Clock + logger leveledlogger.Logger +} + +func NewCMPv2IssuerStatusUpdater(client client.Client, recorder record.EventRecorder, issuer *cmpv2api.CMPv2Issuer, clock clock.Clock, log leveledlogger.Logger) *CMPv2IssuerStatusUpdater { + return &CMPv2IssuerStatusUpdater{ + client: client, + recorder: recorder, + issuer: issuer, + clock: clock, + logger: log, + } +} + +func (instance *CMPv2IssuerStatusUpdater) Update(ctx context.Context, status cmpv2api.ConditionStatus, reason, message string, args ...interface{}) error { + completeMessage := fmt.Sprintf(message, args...) + instance.setCondition(status, reason, completeMessage) + + FireEventIssuer(instance.recorder, instance.issuer, status, reason, completeMessage) + + return instance.client.Update(ctx, instance.issuer) +} + +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) + } +} + +// setCondition will set a 'condition' on the given cmpv2api.CMPv2Issuer resource. +// +// - If no condition of the same type already exists, the condition will be +// inserted with the LastTransitionTime set to the current time. +// - If a condition of the same type and state already exists, the condition +// will be updated but the LastTransitionTime will not be modified. +// - 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 (instance *CMPv2IssuerStatusUpdater) setCondition(status cmpv2api.ConditionStatus, reason, message string) { + now := meta.NewTime(instance.clock.Now()) + issuerCondition := cmpv2api.CMPv2IssuerCondition{ + Type: cmpv2api.ConditionReady, + Status: status, + Reason: reason, + Message: message, + LastTransitionTime: &now, + } + + // Search through existing conditions + for i, condition := range instance.issuer.Status.Conditions { + // Skip unrelated conditions + if condition.Type != cmpv2api.ConditionReady { + continue + } + + // If this update doesn't contain a state transition, we don't update + // the conditions LastTransitionTime to Now() + if condition.Status == status { + issuerCondition.LastTransitionTime = condition.LastTransitionTime + } else { + 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 + 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. + 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/updater/status_reason.go b/certServiceK8sExternalProvider/src/cmpv2controller/updater/status_reason.go new file mode 100644 index 00000000..8fe8664c --- /dev/null +++ b/certServiceK8sExternalProvider/src/cmpv2controller/updater/status_reason.go @@ -0,0 +1,28 @@ +/* + * ============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 + +const ( + NotFound = "NotFound" + ValidationFailed = "ValidationFailed" + Error = "Error" + Verified = "Verified" +) -- cgit 1.2.3-korg