crossplane-contrib / function-status-transformer

A @crossplane composition function that can create custom status conditions and events for claims and XRs
Apache License 2.0
11 stars 1 forks source link

Status transformer not able to propage conditional message to the Composite resource and Claim #34

Open ashishkurian opened 6 hours ago

ashishkurian commented 6 hours ago

What happened?

Status transformer failing to propagate conditional message to the Composite resource and Claim even though the StatusTransformationSuccess is True on the composite resource.

Expectation

I want to propagate the conditions.InstanceProfileRoleReady type to be in status: "False" with message "Encountered an error creating the instance profile role: <the error that I am capturing using regex>"

Current composite resource status conditions

image

What am I missing or doing incorrect here?

How can we reproduce it?

I am sharing my XRD, Composition and claim below. I assume I can set any type for the setConditions.condition.type as I have x-kubernetes-preserve-unknown-fields: true set under the conditions for the XRD.

In my iam role managed resource, I am deliberately creating an error so that I can propagate that error message to the composite and claim.

I have the following error on the managed aws iam role.

image

Manifest I am using.

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xawsinstanceprofile.mycompany.com
spec:
  group: mycompany.com
  names:
    kind: XAwsInstanceProfile
    plural: xawsinstanceprofile
  claimNames:
    kind: AwsInstanceProfile
    plural: awsinstanceprofile
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                myParameters:
                  type: object
                  description: My claim parameters
                  properties:
                    myId:
                      type: string
                      description: my Id
                  required:
                    - myId                      
              required:
                - myParameters
            status:
              type: object
              description: status of instance profile.
              properties:
                InstanceProfile:
                  description: Details of the created AWS Instanceprofile 
                  type: object
                  properties:
                    arn:
                      type: string
                  x-kubernetes-preserve-unknown-fields: true
                Condition:
                  description: Condition of the requested AWS Instanceprofile 
                  type: object
                  x-kubernetes-preserve-unknown-fields: true

---
# Definition

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xawsinstanceprofile.mycompany.com
spec:
  group: mycompany.com
  names:
    kind: XAwsInstanceProfile
    plural: xawsinstanceprofile
  claimNames:
    kind: AwsInstanceProfile
    plural: awsinstanceprofile
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                myParameters:
                  type: object
                  description: My claim parameters
                  properties:
                    myId:
                      type: string
                      description: my Id
                  required:
                    - myId                      
              required:
                - myParameters
            status:
              type: object
              description: status of instance profile.
              properties:
                InstanceProfile:
                  description: Details of the created AWS Instanceprofile 
                  type: object
                  properties:
                    arn:
                      type: string
                  x-kubernetes-preserve-unknown-fields: true
                Condition:
                  description: Condition of the requested AWS Instanceprofile 
                  type: object
                  x-kubernetes-preserve-unknown-fields: true

# Composition
---
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: xawsinstanceprofile.mycompany.com
spec:
  compositeTypeRef:
    apiVersion: mycompany.com/v1alpha1
    kind: XAwsInstanceProfile
  environment:
    environmentConfigs:
    - type: Reference
      ref:
        name: iaws-main
    - type: Reference
      ref:
        name: iaws-auto
  mode: Pipeline
  pipeline:
    - step: aws-instance-profile-role
      functionRef:
        name: function-go-templating
      input:
        apiVersion: gotemplating.fn.crossplane.io/v1beta1
        kind: GoTemplate
        source: Inline
        inline:
          template: |
            {{- $environmentConfigs := (index .context "apiextensions.crossplane.io/environment") }}
            {{- $eksClusterName := (index $environmentConfigs "eksClusterName") }}
            {{- $accountId := (index $environmentConfigs "accountId") }}
            # {{- $deletionPolicy := .observed.composite.resource.spec.crossplaneParameters.deletionPolicy }}
            {{- $deletionPolicy := "Delete" }}
            {{- $providerConfigRef := "providerconfig-aws" }}
            {{- $claimName := (index .observed.composite.resource.metadata.labels "crossplane.io/claim-name") }}
            ---
            apiVersion: iam.aws.crossplane.io/v1beta1
            kind: Role
            metadata:
              name: sc-role-servicerole-insproroashtest
              labels:
                resource: instance-profile-role-ashishtest
              annotations:
                gotemplating.fn.crossplane.io/composition-resource-name: InsProRoashtest
            spec:
              deletionPolicy: {{$deletionPolicy}}
              providerConfigRef:
                name: {{$providerConfigRef}}
              forProvider:
                assumeRolePolicyDocument: |
                  {
                    "Version": "2012-10-17",
                    "junk": "somejunk",
                    "Statement": [
                      {
                        "Effect": "Allow",
                        "Principal": {
                          "Service": [
                            "ec2.amazonaws.com"
                          ]
                        },
                        "Action": "sts:AssumeRole"
                      }
                    ]
                  }
                permissionsBoundary: {{ printf "arn:aws:iam::%s:policy/sc-policy-cdk-pipeline-permission-boundary" $accountId }}
                tags:
                  - key: claim-name
                    value: {{$claimName}}
                  - key: created-by
                    value: crossplane
                  - key: composition-name
                    value: AwsInstanceProfile

    - step: status-population
      functionRef:
        name: function-status-transformer
      input:
        apiVersion: function-status-transformer.fn.crossplane.io/v1beta1
        kind: StatusTransformation
        statusConditionHooks:
        - matchers:
          - resources:
            - name: "sc-role-servicerole-insproroashtest"
            conditions:
            - type: Synced
              status: "False"
              reason: ReconcileError
              message: "create failed: (?P<Error>.+)"
          setConditions:
          - target: CompositeAndClaim
            condition:
              type: InstanceProfileRoleReady
              status: "False"
              reason: FailedToCreate
              message: "Encountered an error creating the instance profile role: {{ .Error }}"
          createEvents:
          - target: CompositeAndClaim
            event:
              type: Warning
              reason: FailedToCreate
              message: "Encountered an error creating the instance profile role: {{ .Error }}"    
# Claim           
---
apiVersion: mycompany.com/v1alpha1
kind: AwsInstanceProfile
metadata:
  name: ashish-test
  namespace: mynamespace
spec:
  myParameters:
    myId: ashish-test

What environment did it happen in?

Status transformer function version: v0.4.0 Cloud provider: AWS Kubernetes version: v1.29.1 Kubernetes distribution: EKS Crossplane version: v1.17.3

dalton-hill-0 commented 2 hours ago

Hi @ashishkurian 👋

I believe the name is not matching.

The matcher is looking for sc-role-servicerole-insproroashtest.

        - matchers:
          - resources:
            - name: "sc-role-servicerole-insproroashtest"

That is the name of the resource being created.

            apiVersion: iam.aws.crossplane.io/v1beta1
            kind: Role
            metadata:
              name: sc-role-servicerole-insproroashtest

But we match on the "name" key in the desired resource map. This name is derived from the gotemplating.fn.crossplane.io/composition-resource-name annotation, which is set to InsProRoashtest.

            apiVersion: iam.aws.crossplane.io/v1beta1
            kind: Role
            metadata:
              annotations:
                gotemplating.fn.crossplane.io/composition-resource-name: InsProRoashtest

To resolve the issue, either change the matcher to look for InsProRoashtest, or change the resource name annotation to equal sc-role-servicerole-insproroashtest.