1
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
121
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
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