...

Source file src/github.com/cert-manager/issuer-lib/controllers/request_objecthelper_certificaterequest.go

Documentation: github.com/cert-manager/issuer-lib/controllers

     1  /*
     2  Copyright 2023 The cert-manager Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package controllers
    18  
    19  import (
    20  	"fmt"
    21  
    22  	cmutil "github.com/cert-manager/cert-manager/pkg/api/util"
    23  	cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
    24  	cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
    25  	corev1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/client-go/tools/record"
    28  	"k8s.io/utils/clock"
    29  	"sigs.k8s.io/controller-runtime/pkg/client"
    30  
    31  	v1alpha1 "github.com/cert-manager/issuer-lib/api/v1alpha1"
    32  	"github.com/cert-manager/issuer-lib/conditions"
    33  	"github.com/cert-manager/issuer-lib/controllers/signer"
    34  	"github.com/cert-manager/issuer-lib/internal/ssaclient"
    35  )
    36  
    37  type certificateRequestObjectHelper struct {
    38  	readOnlyObj               *cmapi.CertificateRequest
    39  	setCAOnCertificateRequest bool
    40  }
    41  
    42  var _ RequestObjectHelper = &certificateRequestObjectHelper{}
    43  
    44  func (c *certificateRequestObjectHelper) IsApproved() bool {
    45  	return cmutil.CertificateRequestIsApproved(c.readOnlyObj)
    46  }
    47  
    48  func (c *certificateRequestObjectHelper) IsDenied() bool {
    49  	return cmutil.CertificateRequestHasCondition(c.readOnlyObj, cmapi.CertificateRequestCondition{
    50  		Type:   cmapi.CertificateRequestConditionReady,
    51  		Status: cmmeta.ConditionFalse,
    52  		Reason: cmapi.CertificateRequestReasonDenied,
    53  	})
    54  }
    55  
    56  func (c *certificateRequestObjectHelper) IsReady() bool {
    57  	return cmutil.CertificateRequestHasCondition(c.readOnlyObj, cmapi.CertificateRequestCondition{
    58  		Type:   cmapi.CertificateRequestConditionReady,
    59  		Status: cmmeta.ConditionTrue,
    60  	})
    61  }
    62  
    63  func (c *certificateRequestObjectHelper) IsFailed() bool {
    64  	return cmutil.CertificateRequestHasCondition(c.readOnlyObj, cmapi.CertificateRequestCondition{
    65  		Type:   cmapi.CertificateRequestConditionReady,
    66  		Status: cmmeta.ConditionFalse,
    67  		Reason: cmapi.CertificateRequestReasonFailed,
    68  	})
    69  }
    70  
    71  func (c *certificateRequestObjectHelper) RequestObject() signer.CertificateRequestObject {
    72  	return signer.CertificateRequestObjectFromCertificateRequest(c.readOnlyObj)
    73  }
    74  
    75  func (c *certificateRequestObjectHelper) NewPatch(
    76  	clock clock.PassiveClock,
    77  	fieldOwner string,
    78  	eventRecorder record.EventRecorder,
    79  ) RequestPatchHelper {
    80  	return &certificateRequestPatchHelper{
    81  		clock:                     clock,
    82  		readOnlyObj:               c.readOnlyObj,
    83  		fieldOwner:                fieldOwner,
    84  		setCAOnCertificateRequest: c.setCAOnCertificateRequest,
    85  		patch:                     &cmapi.CertificateRequestStatus{},
    86  		eventRecorder:             eventRecorder,
    87  	}
    88  }
    89  
    90  type certificateRequestPatchHelper struct {
    91  	clock                     clock.PassiveClock
    92  	readOnlyObj               *cmapi.CertificateRequest
    93  	fieldOwner                string
    94  	setCAOnCertificateRequest bool
    95  
    96  	patch         *cmapi.CertificateRequestStatus
    97  	eventRecorder record.EventRecorder
    98  }
    99  
   100  var _ RequestPatchHelper = &certificateRequestPatchHelper{}
   101  var _ RequestPatch = &certificateRequestPatchHelper{}
   102  var _ CertificateRequestPatch = &certificateRequestPatchHelper{}
   103  
   104  func (c *certificateRequestPatchHelper) setCondition(
   105  	conditionType cmapi.CertificateRequestConditionType,
   106  	status cmmeta.ConditionStatus,
   107  	reason, message string,
   108  ) (string, *metav1.Time) {
   109  	condition, updatedAt := conditions.SetCertificateRequestStatusCondition(
   110  		c.clock,
   111  		c.readOnlyObj.Status.Conditions,
   112  		&c.patch.Conditions,
   113  		conditionType, status,
   114  		reason, message,
   115  	)
   116  	return condition.Message, updatedAt
   117  }
   118  
   119  func (c *certificateRequestPatchHelper) SetInitializing() bool {
   120  	// If the CertificateRequest is already denied, we initialize/ overwrite to a failed Reason=Denied
   121  	// condition.
   122  	if cmutil.CertificateRequestIsDenied(c.readOnlyObj) {
   123  		message, failedAt := c.setCondition(
   124  			cmapi.CertificateRequestConditionReady,
   125  			cmmeta.ConditionFalse,
   126  			cmapi.CertificateRequestReasonDenied,
   127  			"Detected that the CertificateRequest is denied, so it will never be Ready.",
   128  		)
   129  		c.patch.FailureTime = failedAt.DeepCopy()
   130  		c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeWarning, eventRequestPermanentError, message)
   131  		return true
   132  	}
   133  
   134  	if ready := cmutil.GetCertificateRequestCondition(
   135  		c.readOnlyObj,
   136  		cmapi.CertificateRequestConditionReady,
   137  	); ready != nil {
   138  		return false
   139  	}
   140  
   141  	c.setCondition(
   142  		cmapi.CertificateRequestConditionReady,
   143  		cmmeta.ConditionUnknown,
   144  		v1alpha1.CertificateRequestConditionReasonInitializing,
   145  		fmt.Sprintf("%s has started reconciling this CertificateRequest", c.fieldOwner),
   146  	)
   147  	return true
   148  }
   149  
   150  func (c *certificateRequestPatchHelper) SetWaitingForIssuerExist(err error) {
   151  	message, _ := c.setCondition(
   152  		cmapi.CertificateRequestConditionReady,
   153  		cmmeta.ConditionFalse,
   154  		cmapi.CertificateRequestReasonPending,
   155  		fmt.Sprintf("%s. Waiting for it to be created.", err),
   156  	)
   157  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeNormal, eventRequestWaitingForIssuerExist, message)
   158  }
   159  
   160  func (c *certificateRequestPatchHelper) SetWaitingForIssuerReadyNoCondition() {
   161  	message, _ := c.setCondition(
   162  		cmapi.CertificateRequestConditionReady,
   163  		cmmeta.ConditionFalse,
   164  		cmapi.CertificateRequestReasonPending,
   165  		"Waiting for issuer to become ready. Current issuer ready condition: <none>.",
   166  	)
   167  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeNormal, eventRequestWaitingForIssuerReady, message)
   168  }
   169  
   170  func (c *certificateRequestPatchHelper) SetWaitingForIssuerReadyOutdated() {
   171  	message, _ := c.setCondition(
   172  		cmapi.CertificateRequestConditionReady,
   173  		cmmeta.ConditionFalse,
   174  		cmapi.CertificateRequestReasonPending,
   175  		"Waiting for issuer to become ready. Current issuer ready condition is outdated.",
   176  	)
   177  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeNormal, eventRequestWaitingForIssuerReady, message)
   178  }
   179  
   180  func (c *certificateRequestPatchHelper) SetWaitingForIssuerReadyNotReady(cond *cmapi.IssuerCondition) {
   181  	message, _ := c.setCondition(
   182  		cmapi.CertificateRequestConditionReady,
   183  		cmmeta.ConditionFalse,
   184  		cmapi.CertificateRequestReasonPending,
   185  		fmt.Sprintf("Waiting for issuer to become ready. Current issuer ready condition is \"%s\": %s.", cond.Reason, cond.Message),
   186  	)
   187  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeNormal, eventRequestWaitingForIssuerReady, message)
   188  }
   189  
   190  func (c *certificateRequestPatchHelper) SetCustomCondition(
   191  	conditionType string,
   192  	conditionStatus metav1.ConditionStatus,
   193  	conditionReason string, conditionMessage string,
   194  ) bool {
   195  	c.setCondition(
   196  		cmapi.CertificateRequestConditionType(conditionType),
   197  		cmmeta.ConditionStatus(conditionStatus),
   198  		conditionReason,
   199  		conditionMessage,
   200  	)
   201  
   202  	// check if the custom condition transitioned
   203  	currentCustom := cmutil.GetCertificateRequestCondition(c.readOnlyObj, cmapi.CertificateRequestConditionType(conditionType))
   204  	didCustomConditionTransition := currentCustom == nil || currentCustom.Status != cmmeta.ConditionStatus(conditionStatus)
   205  	return didCustomConditionTransition
   206  }
   207  
   208  func (c *certificateRequestPatchHelper) SetUnexpectedError(err error) {
   209  	message := "Got an unexpected error while processing the CertificateRequest"
   210  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeWarning, eventRequestUnexpectedError, message)
   211  }
   212  
   213  func (c *certificateRequestPatchHelper) SetPending(reason string) {
   214  	message, _ := c.setCondition(
   215  		cmapi.CertificateRequestConditionReady,
   216  		cmmeta.ConditionFalse,
   217  		cmapi.CertificateRequestReasonPending,
   218  		fmt.Sprintf("Signing still in progress. Reason: %s", reason),
   219  	)
   220  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeWarning, eventRequestRetryableError, message)
   221  }
   222  
   223  func (c *certificateRequestPatchHelper) SetRetryableError(err error) {
   224  	message, _ := c.setCondition(
   225  		cmapi.CertificateRequestConditionReady,
   226  		cmmeta.ConditionFalse,
   227  		cmapi.CertificateRequestReasonPending,
   228  		fmt.Sprintf("Failed to sign CertificateRequest, will retry: %s", err),
   229  	)
   230  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeWarning, eventRequestRetryableError, message)
   231  }
   232  
   233  func (c *certificateRequestPatchHelper) SetPermanentError(err error) {
   234  	message, failedAt := c.setCondition(
   235  		cmapi.CertificateRequestConditionReady,
   236  		cmmeta.ConditionFalse,
   237  		cmapi.CertificateRequestReasonFailed,
   238  		fmt.Sprintf("Failed permanently to sign CertificateRequest: %s", err),
   239  	)
   240  	c.patch.FailureTime = failedAt.DeepCopy()
   241  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeWarning, eventRequestPermanentError, message)
   242  }
   243  
   244  func (c *certificateRequestPatchHelper) SetIssued(bundle signer.PEMBundle) {
   245  	c.patch.Certificate = bundle.ChainPEM
   246  	if c.setCAOnCertificateRequest {
   247  		c.patch.CA = bundle.CAPEM
   248  	}
   249  	message, _ := c.setCondition(
   250  		cmapi.CertificateRequestConditionReady,
   251  		cmmeta.ConditionTrue,
   252  		cmapi.CertificateRequestReasonIssued,
   253  		"Succeeded signing the CertificateRequest",
   254  	)
   255  	c.eventRecorder.Event(c.readOnlyObj, corev1.EventTypeNormal, eventRequestIssued, message)
   256  }
   257  
   258  func (c *certificateRequestPatchHelper) Patch() (client.Object, client.Patch, error) {
   259  	cr, patch, err := ssaclient.GenerateCertificateRequestStatusPatch(
   260  		c.readOnlyObj.Name,
   261  		c.readOnlyObj.Namespace,
   262  		c.patch,
   263  	)
   264  	return &cr, patch, err
   265  }
   266  
   267  func (c *certificateRequestPatchHelper) CertificateRequestPatch() *cmapi.CertificateRequestStatus {
   268  	return c.patch
   269  }
   270  

View as plain text