provider-kubernetes: Cannot get secret when performing a patch

What happened?

I have created a cluster in AWS using Crossplane. In the same composition, I also install FluxCD onto the cluster which creates a secret with a couple of values in there. I am interested in the public key value (identity.pub). So I am using the kubernetes provider to try and retrieve the public key from the secret, however, it cannot be found. Currently, I’m just trying to retrieve it and put the value into a config map - just to see if secret retrieval works. Once this works, I will be attempting to output the public key value to the XR using ToCompositeFieldPath so I can use it in another resource (a Gitlab resource that uses the public key to create a Deploy Key)

The following error is returned when I do a describe on the resource.

Events:
  Type     Reason                         Age                   From                                     Message
  ----     ------                         ----                  ----                                     -------
  Warning  CannotConnectToProvider        5m21s (x18 over 17m)  managed/object.kubernetes.crossplane.io  cannot get ProviderConfig: ProviderConfig.kubernetes.crossplane.io "default" not found
  Warning  CannotObserveExternalResource  21s (x7 over 5m4s)    managed/object.kubernetes.crossplane.io  cannot resolve resource references: cannot get referenced resource: secrets "test-vpc-sync" not found

How can we reproduce it?

Have an external resource that is a secret on another cluster and then try and retrieve one of it’s values.

Kubernetes Composition

    - name: kubernetes
      base:
        apiVersion: kubernetes.crossplane.io/v1alpha1
        kind: ProviderConfig
        spec:
          credentials:
            source: Secret
            secretRef:
              key: kubeconfig
      patches:
      - fromFieldPath: spec.id
        toFieldPath: metadata.name
      - fromFieldPath: spec.writeConnectionSecretToRef.namespace
        toFieldPath: spec.credentials.secretRef.namespace
      - fromFieldPath: spec.id
        toFieldPath: spec.credentials.secretRef.name
        transforms:
          - type: string
            string:
              fmt: "%s-cluster"
      readinessChecks:
        - type: None
    - name: get-public-key
      base:
        apiVersion: kubernetes.crossplane.io/v1alpha1
        kind: Object
        metadata:
          name: foo
        spec:
          references:
            - patchesFrom:
                apiVersion: v1
                kind: Secret
                name: "test-vpc-sync"
                namespace: flux-system
                fieldPath: data[identity.pub]
              toFieldPath: data.publicKey
          forProvider:
            manifest:
              apiVersion: v1
              kind: ConfigMap
              metadata:
                namespace: flux-system
                name: pubsecret
              data:
                publicKey: sample-value
      patches:
      - fromFieldPath: spec.id
        toFieldPath: spec.providerConfigRef.name
      - fromFieldPath: spec.id
        toFieldPath: metadata.name
      - fromFieldPath: spec.writeConnectionSecretToRef.namespace
        toFieldPath: spec.credentials.secretRef.namespace
      - fromFieldPath: spec.id
        toFieldPath: spec.credentials.secretRef.name
        transforms:
          - type: string
            string:
              fmt: "%s-cluster"
      readinessChecks:
        - type: None

What environment did it happen in?

Crossplane version: Chart version: 1.7.1

  • AWS EKS
  • K8s: 1.22

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 20 (8 by maintainers)

Most upvoted comments

Agree w/ @bobh66, @ChrisJBurns since this is a common use case on retrieving and transferring secrets among resources, it doesn’t have to be coupled w/ Flux case. Also, if it’s hard to show it based on the existing example in in-composition folder, I’d think it’s ok to add another one.

The functionality will work but I don’t think the overall affect will be what you want if it’s on the retrieval side since the target Secret will still get created with the empty data field(s) since the “missing” data that it’s retrieving is not considered to be an error. The policy is essentially creating a “required” field on the target resource so it will fail until there is a value available to put in that field. Making the source field required will not affect the target resource.

It appears to be a little more complicated because the finalizer uses the local client to process the references and I don’t think the “remote” client is immediately available to the finalizer. So it definitely needs more analysis by someone more familiar with the internals of the provider.