Skip to content

Commit cd64e64

Browse files
authored
Merge pull request crossplane#6121 from jbw976/render-conditions
feat(cli): include status conditions in output of render command
2 parents 62dedb8 + 4addd41 commit cd64e64

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

cmd/crank/render/render.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ func Render(ctx context.Context, log logging.Logger, in Inputs) (Outputs, error)
207207
d := &fnv1.State{}
208208

209209
results := make([]unstructured.Unstructured, 0)
210+
conditions := make([]xpv1.Condition, 0)
210211

211212
// The Function context starts empty.
212213
fctx := &structpb.Struct{Fields: map[string]*structpb.Value{}}
@@ -271,6 +272,26 @@ func Render(ctx context.Context, log logging.Logger, in Inputs) (Outputs, error)
271272
// We intentionally discard/ignore this after the last Function runs.
272273
fctx = rsp.GetContext()
273274

275+
for _, c := range rsp.GetConditions() {
276+
var status corev1.ConditionStatus
277+
switch c.GetStatus() {
278+
case fnv1.Status_STATUS_CONDITION_TRUE:
279+
status = corev1.ConditionTrue
280+
case fnv1.Status_STATUS_CONDITION_FALSE:
281+
status = corev1.ConditionFalse
282+
case fnv1.Status_STATUS_CONDITION_UNKNOWN, fnv1.Status_STATUS_CONDITION_UNSPECIFIED:
283+
status = corev1.ConditionUnknown
284+
}
285+
286+
conditions = append(conditions, xpv1.Condition{
287+
Type: xpv1.ConditionType(c.GetType()),
288+
Status: status,
289+
LastTransitionTime: conditionTime(),
290+
Reason: xpv1.ConditionReason(c.GetReason()),
291+
Message: c.GetMessage(),
292+
})
293+
}
294+
274295
// Results of fatal severity stop the Composition process.
275296
for _, rs := range rsp.GetResults() {
276297
switch rs.GetSeverity() { //nolint:exhaustive // We intentionally have a broad default case.
@@ -335,11 +356,20 @@ func Render(ctx context.Context, log logging.Logger, in Inputs) (Outputs, error)
335356
if len(unready) > 0 {
336357
xrCond = xpv1.Creating().WithMessage(fmt.Sprintf("Unready resources: %s", resource.StableNAndSomeMore(resource.DefaultFirstN, unready)))
337358
}
338-
// lastTransitionTime would just be noise, but we can't drop it as it's a
339-
// required field and null is not allowed, so we set a random time.
340-
xrCond.LastTransitionTime = metav1.NewTime(time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC))
359+
xrCond.LastTransitionTime = conditionTime()
341360
xr.SetConditions(xrCond)
342361

362+
for _, c := range conditions {
363+
if xpv1.IsSystemConditionType(c.Type) {
364+
// Do not let users update system conditions.
365+
continue
366+
}
367+
// update the XR with the current condition. If it targets the claim, we
368+
// could also set it on the claim here, but we don't support Claims in
369+
// render yet.
370+
xr.SetConditions(c)
371+
}
372+
343373
out := Outputs{CompositeResource: xr, ComposedResources: desired, Results: results}
344374
if fctx != nil {
345375
out.Context = &unstructured.Unstructured{Object: map[string]any{
@@ -414,3 +444,9 @@ func (f *FilteringFetcher) Fetch(_ context.Context, rs *fnv1.ResourceSelector) (
414444

415445
return out, nil
416446
}
447+
448+
func conditionTime() metav1.Time {
449+
// lastTransitionTime for conditions would just be noise, but we can't drop it
450+
// as it's a required field and null is not allowed, so we set a random time.
451+
return metav1.NewTime(time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC))
452+
}

cmd/crank/render/render_test.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3333
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3434
"k8s.io/apimachinery/pkg/runtime"
35+
"k8s.io/utils/ptr"
3536

3637
"github.com/crossplane/crossplane-runtime/pkg/logging"
3738
"github.com/crossplane/crossplane-runtime/pkg/resource/unstructured/composed"
@@ -249,6 +250,15 @@ func TestRender(t *testing.T) {
249250
},
250251
},
251252
},
253+
Conditions: []*fnv1.Condition{
254+
{
255+
Type: "ProvisioningSuccess",
256+
Status: fnv1.Status_STATUS_CONDITION_TRUE,
257+
Reason: "Provisioned",
258+
Message: ptr.To("Provisioned successfully"),
259+
Target: fnv1.Target_TARGET_COMPOSITE_AND_CLAIM.Enum(),
260+
},
261+
},
252262
})
253263
listeners = append(listeners, lis)
254264

@@ -280,13 +290,22 @@ func TestRender(t *testing.T) {
280290
},
281291
"status": {
282292
"widgets": 9001,
283-
"conditions": [{
284-
"lastTransitionTime": "2024-01-01T00:00:00Z",
285-
"type": "Ready",
286-
"status": "False",
287-
"reason": "Creating",
288-
"message": "Unready resources: a-cool-resource, b-cool-resource"
289-
}]
293+
"conditions": [
294+
{
295+
"lastTransitionTime": "2024-01-01T00:00:00Z",
296+
"type": "Ready",
297+
"status": "False",
298+
"reason": "Creating",
299+
"message": "Unready resources: a-cool-resource, b-cool-resource"
300+
},
301+
{
302+
"lastTransitionTime": "2024-01-01T00:00:00Z",
303+
"type": "ProvisioningSuccess",
304+
"status": "True",
305+
"reason": "Provisioned",
306+
"message": "Provisioned successfully"
307+
}
308+
]
290309
}
291310
}`),
292311
},

0 commit comments

Comments
 (0)