Skip to content

Commit

Permalink
Merge pull request #146 from stevendborrelli/status-conditions
Browse files Browse the repository at this point in the history
Add Status conditions for Claim and Composite
  • Loading branch information
ezgidemirel authored Dec 2, 2024
2 parents 6250ace + 56034b6 commit 2bcc90e
Show file tree
Hide file tree
Showing 12 changed files with 734 additions and 13 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,47 @@ spec:

For more information, see the example in [recursive](example/recursive).

## Setting Conditions on the Claim and Composite

Starting with Crossplane 1.17, Composition authors can set custom Conditions on the
Composite and the Claim.

Add a `ClaimConditions` to your template to set Conditions:

```yaml
apiVersion: meta.gotemplating.fn.crossplane.io/v1alpha1
kind: ClaimConditions
conditions:
# Guide to ClaimConditions fields:
# Type of the condition, e.g. DatabaseReady.
# 'Healthy', 'Ready' and 'Synced' are reserved for use by Crossplane and this function will raise an error if used
# - type:
# Status of the condition. String of "True"/"False"/"Unknown"
# status:
# Machine-readable PascalCase reason, for example "ErrorProvisioning"
# reason:
# Optional Target. Publish Condition only to the Composite, or the Composite and the Claim (CompositeAndClaim).
# Defaults to Composite
# target:
# Optional message:
# message:
- type: TestCondition
status: "False"
reason: InstallFail
message: "failed to install"
target: CompositeAndClaim
- type: ConditionTrue
status: "True"
reason: TrueCondition
message: we are true
target: Composite
- type: DatabaseReady
status: "True"
reason: Ready
message: Database is ready
target: CompositeAndClaim
```

## Additional functions

| Name | Description |
Expand Down
88 changes: 88 additions & 0 deletions claimconditions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package main

import (
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/crossplane/function-sdk-go/errors"
fnv1 "github.com/crossplane/function-sdk-go/proto/v1"
"github.com/crossplane/function-sdk-go/response"
corev1 "k8s.io/api/core/v1"
)

// A CompositionTarget is the target of a composition event or condition.
type CompositionTarget string

// A TargetedCondition represents a condition produced by the composition
// process. It can target either the XR only, or both the XR and the claim.
type TargetedCondition struct {
xpv1.Condition `json:",inline"`
Target CompositionTarget `json:"target"`
}

// Composition event and condition targets.
const (
CompositionTargetComposite CompositionTarget = "Composite"
CompositionTargetCompositeAndClaim CompositionTarget = "CompositeAndClaim"
)

// UpdateClaimConditions updates Conditions in the Claim and Composite
func UpdateClaimConditions(rsp *fnv1.RunFunctionResponse, conditions ...TargetedCondition) error {
if rsp == nil {
return nil
}
for _, c := range conditions {
if xpv1.IsSystemConditionType(xpv1.ConditionType(c.Type)) {
response.Fatal(rsp, errors.Errorf("cannot set ClaimCondition type: %s is a reserved Crossplane Condition", c.Type))
return errors.New("error updating response")
}
co := transformCondition(c)
UpdateResponseWithCondition(rsp, co)
}
return nil
}

// transformCondition converts a TargetedCondition to be compatible with the Protobuf SDK
func transformCondition(tc TargetedCondition) *fnv1.Condition {
c := &fnv1.Condition{
Type: string(tc.Condition.Type),
Reason: string(tc.Condition.Reason),
Target: transformTarget(tc.Target),
}

switch tc.Condition.Status {
case corev1.ConditionTrue:
c.Status = fnv1.Status_STATUS_CONDITION_TRUE
case corev1.ConditionFalse:
c.Status = fnv1.Status_STATUS_CONDITION_FALSE
case corev1.ConditionUnknown:
fallthrough
default:
c.Status = fnv1.Status_STATUS_CONDITION_UNKNOWN
}

if tc.Message != "" {
c.Message = &tc.Message
}
return c
}

// transformTarget converts the input into a target Go SDK Enum
// Default to TARGET_COMPOSITE
func transformTarget(ct CompositionTarget) *fnv1.Target {
if ct == CompositionTargetCompositeAndClaim {
return fnv1.Target_TARGET_COMPOSITE_AND_CLAIM.Enum().Enum()
}
return fnv1.Target_TARGET_COMPOSITE.Enum()
}

// UpdateResponseWithCondition updates the RunFunctionResponse with a Condition
func UpdateResponseWithCondition(rsp *fnv1.RunFunctionResponse, c *fnv1.Condition) {
if rsp == nil {
return
}
if rsp.GetConditions() == nil {
rsp.Conditions = make([]*fnv1.Condition, 0, 1)
}
if c != nil {
rsp.Conditions = append(rsp.GetConditions(), c)
}
}
Loading

0 comments on commit 2bcc90e

Please sign in to comment.