Skip to content

Commit d4a4c96

Browse files
committed
Extend with syncedFalse approach
* Try approach with invalidation synced status on XR * General example cleanup Signed-off-by: Yury Tsarev <yury@upbound.io>
1 parent 94f6de2 commit d4a4c96

28 files changed

+238
-733
lines changed

NOTES.txt

Lines changed: 0 additions & 41 deletions
This file was deleted.

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A Crossplane Composition Function for implementing manual approval workflows.
77
The `function-approve` provides a serverless approval mechanism at the Crossplane level that:
88

99
1. Tracks changes to a specified field by computing a hash
10-
2. Pauses reconciliation when changes are detected
10+
2. Pauses reconciliation when changes are detected (using either pause annotation or Synced=False condition)
1111
3. Requires explicit approval before allowing reconciliation to continue
1212
4. Prevents drift by storing previously approved state
1313

@@ -73,6 +73,7 @@ spec:
7373
| `pauseAnnotation` | string | Annotation to use for pausing reconciliation. Default: `crossplane.io/paused` |
7474
| `detailedCondition` | bool | Whether to add detailed information to conditions. Default: `true` |
7575
| `approvalMessage` | string | Message to display when approval is required. Default: `Changes detected. Approval required.` |
76+
| `setSyncedFalse` | bool | Use Synced=False condition instead of pause annotation. Default: `false` |
7677

7778
## Using with Custom Resources
7879

@@ -142,6 +143,32 @@ kubectl patch xapproval example --type=merge --subresource=status -p '{"status":
142143
- Use RBAC to control who can approve changes by restricting access to the status subresource
143144
- Consider implementing additional verification steps or multi-party approval in your workflow
144145

146+
## Pausing Reconciliation Methods
147+
148+
The function supports two methods to pause reconciliation when changes are detected:
149+
150+
### 1. Pause Annotation (Default)
151+
152+
By default, the function adds the `crossplane.io/paused` annotation (or specified annotation) to pause reconciliation:
153+
154+
```yaml
155+
pauseAnnotation: "crossplane.io/paused"
156+
setSyncedFalse: false # Or omit this field as it defaults to false
157+
```
158+
159+
### 2. Synced=False Condition
160+
161+
Alternatively, the function can set the Synced condition to False instead of using an annotation:
162+
163+
```yaml
164+
setSyncedFalse: true
165+
```
166+
167+
This approach may be preferred in environments where:
168+
- Annotations are subject to stricter validation or policies
169+
- You want to leverage Crossplane's native condition-based reconciliation control
170+
- You need better integration with monitoring systems that use conditions
171+
145172
## Complete Example
146173

147174
Here's a complete example of a composition using `function-approve`:
@@ -169,6 +196,7 @@ spec:
169196
oldHashField: "status.approvedHash"
170197
detailedCondition: true
171198
approvalMessage: "Cluster changes require admin approval"
199+
setSyncedFalse: true # Use Synced=False condition instead of pause annotation
172200
- step: create-resources
173201
functionRef:
174202
name: function-patch-and-transform

example/README.md

Lines changed: 51 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,81 @@
1-
# Microsoft Graph API Function Examples
1+
# Approval Function Examples
22

3-
This directory contains practical examples that demonstrate the function-msgraph capabilities for querying Microsoft Graph API.
3+
This directory contains examples demonstrating the function-approve capabilities for implementing approval workflows in Crossplane.
44

55
## Prerequisites
66

77
To run these examples, you need:
88

99
1. The Crossplane CLI installed
10-
2. Valid Azure credentials with Microsoft Graph API permissions:
11-
- User.Read.All (for user validation)
12-
- Group.Read.All (for group operations)
13-
- Application.Read.All (for service principal details)
10+
2. function-approve built and available
1411

15-
## Update Credentials
12+
## Understanding the Approval Function
1613

17-
Before running any examples, update `secrets/azure-creds.yaml` with your valid Azure credentials:
14+
The approval function provides a controlled way to manage changes to Crossplane resources, requiring manual approval before changes are applied. This is useful for scenarios where you want to review changes before they are applied to your infrastructure.
1815

19-
```yaml
20-
apiVersion: v1
21-
kind: Secret
22-
metadata:
23-
name: azure-account-creds
24-
type: Opaque
25-
stringData:
26-
credentials: |
27-
{
28-
"clientId": "your-client-id",
29-
"clientSecret": "your-client-secret",
30-
"tenantId": "your-tenant-id",
31-
"subscriptionId": "your-subscription-id"
32-
}
33-
```
34-
35-
## Core Examples
36-
37-
### 1. User Validation
38-
39-
Validate if specified Azure AD users exist:
40-
41-
```shell
42-
crossplane render xr.yaml user-validation-example.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
43-
```
44-
45-
Dynamic `usersRef` variations:
46-
47-
```shell
48-
crossplane render xr.yaml user-validation-example-status-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
49-
```
50-
51-
```shell
52-
crossplane render xr.yaml user-validation-example-context-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc --extra-resources=envconfig.yaml
53-
```
54-
55-
```shell
56-
crossplane render xr.yaml user-validation-example-spec-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
57-
```
58-
59-
### 2. Group Membership
60-
61-
Get all members of a specified Azure AD group:
62-
63-
```shell
64-
crossplane render xr.yaml group-membership-example.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
65-
```
16+
The function works by:
17+
1. Computing a hash of specified data in your composite resource
18+
2. Checking if the hash has changed since the last approved version
19+
3. Pausing reconciliation if changes are detected and approval is needed
20+
4. Resuming reconciliation once changes are approved
6621

67-
Dynamic `groupRef` variations:
22+
## Running the Examples
6823

69-
```shell
70-
crossplane render xr.yaml group-membership-example-status-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
71-
```
24+
### Basic Example with Pause Annotation
7225

73-
```shell
74-
crossplane render xr.yaml group-membership-example-context-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc --extra-resources=envconfig.yaml
75-
```
26+
The default behavior uses the `crossplane.io/paused` annotation to pause reconciliation:
7627

7728
```shell
78-
crossplane render xr.yaml group-membership-example-spec-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
29+
crossplane render xr.yaml composition.yaml functions.yaml
7930
```
8031

81-
### 3. Group Object IDs
32+
### Example with Synced=False Condition
8233

83-
Get object IDs for specified Azure AD groups:
34+
This alternative approach uses the Synced=False condition instead of the pause annotation:
8435

8536
```shell
86-
crossplane render xr.yaml group-objectids-example.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
37+
crossplane render xr.yaml composition.yaml functions.yaml
8738
```
8839

89-
Dynamic `groupsRef` variations:
90-
91-
```shell
92-
crossplane render xr.yaml group-objectids-example-status-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
93-
```
94-
95-
```shell
96-
crossplane render xr.yaml group-objectids-example-context-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc --extra-resources=envconfig.yaml
97-
```
40+
The `setSyncedFalse: true` option in the composition enables this behavior.
9841

99-
```shell
100-
crossplane render xr.yaml group-objectids-example-spec-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
101-
```
42+
## Configuration Options
10243

103-
### 4. Service Principal Details
44+
The function supports these configuration options:
10445

105-
Get details of specified service principals:
46+
- `dataField`: Specifies which field to monitor for changes (required)
47+
- `approvalField`: Status field to check for approval (default: "status.approved")
48+
- `oldHashField`: Where to store the approved hash (default: "status.oldHash")
49+
- `newHashField`: Where to store the current hash (default: "status.newHash")
50+
- `pauseAnnotation`: Annotation used to pause reconciliation (default: "crossplane.io/paused")
51+
- `detailedCondition`: Whether to include hash details in conditions (default: true)
52+
- `approvalMessage`: Custom message for approval required condition
53+
- `setSyncedFalse`: Use Synced=False condition instead of pause annotation (default: false)
10654

107-
```shell
108-
crossplane render xr.yaml service-principal-example.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
109-
```
55+
## Approval Workflow
11056

111-
Dynamic `servicePrinicpalsRef` variations:
57+
1. Make changes to the resource's spec
58+
2. The function detects changes and pauses reconciliation
59+
3. Review the changes through the resource's conditions
60+
4. Set the approval field (default: `status.approved: true`)
61+
5. The function detects approval and resumes reconciliation
11262

113-
```shell
114-
crossplane render xr.yaml service-principal-example-status-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
115-
```
63+
## Example With setSyncedFalse
11664

117-
```shell
118-
crossplane render xr.yaml service-principal-example-context-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc --extra-resources=envconfig.yaml
119-
```
65+
In some environments, it may be preferable to use Synced=False condition instead of annotations.
66+
The `setSyncedFalse: true` option enables this alternative approach:
12067

121-
```shell
122-
crossplane render xr.yaml service-principal-example-spec-ref.yaml functions.yaml --function-credentials=./secrets/azure-creds.yaml -rc
123-
```
68+
```yaml
69+
apiVersion: approve.fn.crossplane.io/v1alpha1
70+
kind: Input
71+
dataField: "spec.resources"
72+
approvalField: "status.approved"
73+
newHashField: "status.newHash"
74+
oldHashField: "status.oldHash"
75+
detailedCondition: true
76+
approvalMessage: "Changes detected. Administrative approval required."
77+
setSyncedFalse: true
78+
```
79+
80+
When enabled, this sets the Synced condition to False instead of adding the pause annotation,
81+
providing the same pause functionality through a different mechanism.

example/claim.yaml

Lines changed: 0 additions & 14 deletions
This file was deleted.

example/composition.yaml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ spec:
66
compositeTypeRef:
77
apiVersion: example.crossplane.io/v1
88
kind: XApproval
9+
mode: Pipeline
910
pipeline:
1011
- step: require-approval
1112
functionRef:
@@ -20,24 +21,21 @@ spec:
2021
pauseAnnotation: "crossplane.io/paused"
2122
detailedCondition: true
2223
approvalMessage: "Changes detected. Administrative approval required."
24+
setSyncedFalse: true
2325
- step: render-resources
2426
functionRef:
2527
name: function-patch-and-transform
2628
input:
27-
apiVersion: pt.fn.crossplane.io/v1alpha1
29+
apiVersion: pt.fn.crossplane.io/v1beta1
2830
kind: Resources
2931
resources:
30-
- name: example-configmap
32+
- name: example-envconfig
3133
base:
32-
apiVersion: v1
33-
kind: ConfigMap
34-
metadata:
35-
name: example-configmap
36-
data:
37-
key1: value1
34+
apiVersion: apiextensions.crossplane.io/v1beta1
35+
kind: EnvironmentConfig
3836
patches:
3937
- type: FromCompositeFieldPath
4038
fromFieldPath: spec.resources.data
4139
toFieldPath: data
4240
policy:
43-
fromFieldPath: Required
41+
fromFieldPath: Required

example/definition.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ spec:
4444
required:
4545
- spec
4646
type: object
47-
served: true
47+
served: true

example/functions.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ kind: Function
1313
metadata:
1414
name: function-patch-and-transform
1515
spec:
16-
package: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.2.1
16+
package: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.9.0

example/group-membership-example-context-ref.yaml

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)