Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

user.sql.gcp.jet.crossplane.io not created and external-name changed on the fly #71

Open
prune998 opened this issue Aug 23, 2022 · 0 comments
Labels
bug Something isn't working

Comments

@prune998
Copy link

What happened?

I created a user.sql.gcp.jet.crossplane.io through a composition + patch, which looked like:

k get managed

NAME                                                                                         READY   SYNCED   EXTERNAL-NAME                                    AGE
user.sql.gcp.jet.crossplane.io/jet-db-claim-4-lscnc-5h6gt                False    [email protected]   2m23s

a few moments later, same command:

k get managed

NAME                                                                                           READY   SYNCED   EXTERNAL-NAME    AGE
user.sql.gcp.jet.crossplane.io/jet-db-claim-4-lscnc-5h6gt   True        False          jet-db-claim-4      4m42s

external name changed from [email protected] to jet-db-claim-4

When I look at the User resource:

k get user.sql.gcp.jet.crossplane.io/jet-db-claim-4-lscnc-5h6gt -o yaml                        
                                                                                                       
apiVersion: sql.gcp.jet.crossplane.io/v1alpha2
kind: User
metadata:
  annotations:
    crossplane.io/composition-resource-name: cloudsqldbuser
    crossplane.io/external-create-pending: "2022-08-23T17:56:15Z"
    crossplane.io/external-create-succeeded: "2022-08-23T17:56:15Z"
    crossplane.io/external-name: [email protected]
    terrajet.crossplane.io/provider-meta: '{"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0":{"create":600000000000,"delete":600000000000,"update":600000000000},"schema_version":"1"}'
  creationTimestamp: "2022-08-23T17:53:27Z"
  finalizers:
  - finalizer.managedresource.crossplane.io
  generateName: jet-db-claim-4-lscnc-
  generation: 3
  labels:
    crossplane.io/app: jet-db-claim-4
    crossplane.io/claim-name: jet-db-claim-4
    crossplane.io/claim-namespace: jet-namespace
    crossplane.io/composite: jet-db-claim-4-lscnc
  name: jet-db-claim-4-lscnc-5h6gt
  ownerReferences:
  - apiVersion: database.wk/v1alpha1
    controller: true
    kind: XJetPostgreSQL
    name: jet-db-claim-4-lscnc
    uid: 495dde06-3dbc-457d-95d0-2934b2d6f479
  resourceVersion: "1081089003"
  uid: 4ec9268d-d6fe-42e2-b42a-2c1b3e5470ee
spec:
  deletionPolicy: Delete
  forProvider:
    instance: jet-db-claim-4
    instanceRef:
      name: jet-db-claim-4-lscnc-hlms7
    instanceSelector: {}
    project: my-project
    type: CLOUD_IAM_SERVICE_ACCOUNT
  providerConfigRef:
    name: crossplane-provider-jet-gcp
  writeConnectionSecretToRef:
    name: jet-db-claim-4-pguser
    namespace: idp-integration-api-argo
status:
  atProvider:
    id: [email protected]//jet-db-claim-4
  conditions:
  - lastTransitionTime: "2022-08-23T18:03:35Z"
    message: 'observe failed: cannot run plan: plan failed: Instance cannot be destroyed:
      Resource google_sql_user.jet-db-claim-4-lscnc-5h6gt has lifecycle.prevent_destroy
      set, but the plan calls for this resource to be destroyed. To avoid this error
      and continue with the plan, either disable lifecycle.prevent_destroy or reduce
      the scope of the plan using the -target flag.: File name: main.tf.json'
    reason: ReconcileError
    status: "False"
    type: Synced
  - lastTransitionTime: "2022-08-23T17:56:20Z"
    reason: Available
    status: "True"
    type: Ready
  - lastTransitionTime: "2022-08-23T17:56:17Z"
    reason: Finished
    status: "True"
    type: AsyncOperation
  - lastTransitionTime: "2022-08-23T17:56:17Z"
    reason: Success
    status: "True"
    type: LastAsyncOperation

I don't know why the resource is to be destroyed, but the message makes me wonder how am I supposed to set the resource lifecycle ?

Resource google_sql_user.jet-db-claim-4-lscnc-5h6gt has lifecycle.prevent_destroy
      set, but the plan calls for this resource to be destroyed.

Also, the deletionPolicy for the User resource is really limited:

expected deletion_policy to be one of [ABANDON ]

So there's no way to set de policy / lifecycle to delete in here....

Note: Crossplane and provider are run with --debug, and no specific logs or errors are generated at first.
Then, the provider is complaining about the resource lifecycle:

2022-08-23T18:38:17.723Z	DEBUG	provider-jet-gcp	plan ended	{"workspace": "/tmp/4ec9268d-d6fe-42e2-b42a-2c1b3e5470ee", "out": "{\"@level\":\"info\",\"@message\":\"Terraform 1.0.11\",\"@module\":\"terraform.ui\",\"@timestamp\":\"2022-08-23T18:38:16.547782Z\",\"terraform\":\"1.0.11\",\"type\":\"version\",\"ui\":\"0.1.0\"}\n{\"@level\":\"error\",\"@message\":\"Error: Instance cannot be destroyed\",\"@module\":\"terraform.ui\",\"@timestamp\":\"2022-08-23T18:38:17.713562Z\",\"diagnostic\":{\"severity\":\"error\",\"summary\":\"Instance cannot be destroyed\",\"detail\":\"Resource google_sql_user.jet-db-claim-4-lscnc-5h6gt has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.\",\"range\":{\"filename\":\"main.tf.json\",\"start\":{\"line\":1,\"column\":119,\"byte\":118},\"end\":{\"line\":1,\"column\":120,\"byte\":119}},\"snippet\":{\"context\":\"resource.google_sql_user\",\"code\":\"{\\\"provider\\\":{\\\"google\\\":{\\\"project\\\":\\\"wk-quality-assurance\\\"}},\\\"resource\\\":{\\\"google_sql_user\\\":{\\\"jet-db-claim-4-lscnc-5h6gt\\\":{\\\"instance\\\":\\\"jet-db-claim-4\\\",\\\"lifecycle\\\":{\\\"prevent_destroy\\\":true},\\\"name\\\":\\\"jet-db-claim-4\\\",\\\"project\\\":\\\"my-project\\\",\\\"type\\\":\\\"CLOUD_IAM_SERVICE_ACCOUNT\\\"}}},\\\"terraform\\\":{\\\"required_providers\\\":{\\\"google\\\":{\\\"source\\\":\\\"hashicorp/google\\\",\\\"version\\\":\\\"4.0.0\\\"}}}}\",\"start_line\":1,\"highlight_start_offset\":118,\"highlight_end_offset\":119,\"values\":[]}},\"type\":\"diagnostic\"}\n"}

2022-08-23T18:38:17.724Z	DEBUG	provider-jet-gcp	Cannot observe external resource	{"controller": "managed/sql.gcp.jet.crossplane.io/v1alpha2, kind=user", "request": "/jet-db-claim-4-lscnc-5h6gt", "uid": "4ec9268d-d6fe-42e2-b42a-2c1b3e5470ee", "version": "1081163760", "external-name": "jet-db-claim-4", "error": "cannot run plan: plan failed: Instance cannot be destroyed: Resource google_sql_user.jet-db-claim-4-lscnc-5h6gt has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.: File name: main.tf.json", "errorVerbose": "plan failed: Instance cannot be destroyed: Resource google_sql_user.jet-db-claim-4-lscnc-5h6gt has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.: File name: main.tf.json\ncannot run plan\ngithub.com/crossplane/terrajet/pkg/controller.(*external).Observe\n\t/home/runner/work/provider-jet-gcp/provider-jet-gcp/vendor/github.com/crossplane/terrajet/pkg/controller/external.go:184\ngithub.com/crossplane/crossplane-runtime/pkg/reconciler/managed.(*Reconciler).Reconcile\n\t/home/runner/work/provider-jet-gcp/provider-jet-gcp/vendor/github.com/crossplane/crossplane-runtime/pkg/reconciler/managed/reconciler.go:681\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/home/runner/work/provider-jet-gcp/provider-jet-gcp/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:298\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/home/runner/work/provider-jet-gcp/provider-jet-gcp/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:253\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2\n\t/home/runner/work/provider-jet-gcp/provider-jet-gcp/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:214\nruntime.goexit\n\t/opt/hostedtoolcache/go/1.16.12/x64/src/runtime/asm_amd64.s:1371"}

2022-08-23T18:38:17.724Z	DEBUG	controller-runtime.manager.events	Warning	{"object": {"kind":"User","name":"jet-db-claim-4-lscnc-5h6gt","uid":"4ec9268d-d6fe-42e2-b42a-2c1b3e5470ee","apiVersion":"sql.gcp.jet.crossplane.io/v1alpha2","resourceVersion":"1081163760"}, "reason": "CannotObserveExternalResource", "message": "cannot run plan: plan failed: Instance cannot be destroyed: Resource google_sql_user.jet-db-claim-4-lscnc-5h6gt has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.: File name: main.tf.json"}

Expected behaviour

The User resource should be created using the right External Name ([email protected]) and there shouldn't be any lifecycle issue.

How can we reproduce it?

XRD

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xjetpostgresqls.database.wk
spec:
  group: database.wk
  names:
    kind: XJetPostgreSQL
    plural: xjetpostgresqls
  claimNames:
    kind: JetPostgreSQL
    plural: jetpostgresqls
  versions:
  - name: v1alpha1
    served: true
    referenceable: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              parameters:
                type: object
                properties:
                  storageGB:
                    type: integer
                    description: size of the Database in GB - integer
                  dbName:
                    type: string
                    description: name of the new DB inside the DB instance - string
                  instanceSize:
                    type: string
                    description: instance size - string
                    enum:
                      - small
                      - medium
                      - large
                required:
                  - storageGB
                  - dbName
                  - instanceSize
            required:
              - parameters

Composition

See how the value is hardcoded... it shouldn't change...

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: jetpostgresql.gcp.database.wk
  labels:
    provider: gcp
    crossplane.io/xrd: xjetpostgresql.database.wk
spec:
  compositeTypeRef:
    apiVersion: database.wk/v1alpha1
    kind: XJetPostgreSQL
  resources:
    - name: cloudsqlinstance
      base:
        apiVersion: sql.gcp.jet.crossplane.io/v1alpha2
        kind: DatabaseInstance
        metadata:
          annotations: 
            crossplane.io/external-name: "crossplanesqlinstance"
        spec:
          providerConfigRef:
            name: crossplane-provider-jet-gcp
          deletionPolicy: Delete
          forProvider:
            databaseVersion: POSTGRES_14
            region: us-central1
            deletionProtection: false
            settings:
            - tier: db-custom-1-3840
              diskType: PD_SSD
              diskSize: 20
              ipConfiguration:
                - ipv4Enabled: true
                  authorizedNetworks:
                    - value: "0.0.0.0/0"
            userLabels:
              creator: crossplane
              owner: prune
          writeConnectionSecretToRef:
            namespace: crossplane
            name: cloudsqlinstance
      patches:
        # set the secret name to the claim name
        - fromFieldPath: "metadata.labels[crossplane.io/claim-name]"
          toFieldPath: "spec.writeConnectionSecretToRef.name"
          transforms:
            - type: string
              string:
                fmt: "%s-pginstance"
        # change secret namespace to the one of the claim
        - fromFieldPath: "metadata.labels[crossplane.io/claim-namespace]"
          toFieldPath: "spec.writeConnectionSecretToRef.namespace"
        # set diskSize based on the Claim
        - fromFieldPath: "spec.parameters.storageGB"
          toFieldPath: "spec.forProvider.settings[0].diskSize"
        # set label app = name of the original claim
        - fromFieldPath: "metadata.labels[crossplane.io/claim-name]"
          toFieldPath: "metadata.labels[crossplane.io/app]"
        # set the name of the external resource to be the name of the claim
        - fromFieldPath: "metadata.labels[crossplane.io/claim-name]"
          toFieldPath: "metadata.annotations[crossplane.io/external-name]"
        # set instance size to the one defined in the claim
        - fromFieldPath: "spec.parameters.instanceSize"
          toFieldPath: "spec.forProvider.settings[0].tier"
          transforms:
            - type: map
              map:
                small: db-custom-1-3840
                medium: db-custom-2-7680
                large: db-custom-4-15360
          policy:
            fromFieldPath: Required
    - name: cloudsqldb
      base:
        apiVersion: sql.gcp.jet.crossplane.io/v1alpha2
        kind: Database
        metadata:
          annotations: 
            crossplane.io/external-name: "crossplanesqldb"
        spec:
          providerConfigRef:
            name: crossplane-provider-jet-gcp
          deletionPolicy: Delete
          forProvider:
            instanceSelector:
              MatchControllerRef: true
          writeConnectionSecretToRef:
            namespace: crossplane
            name: cloudsqldb
      patches:
        # set the secret name to the claim name
        - fromFieldPath: "metadata.labels[crossplane.io/claim-name]"
          toFieldPath: "spec.writeConnectionSecretToRef.name"
          transforms:
            - type: string
              string:
                fmt: "%s-pgdb"
        # change secret namespace to the one of the claim
        - fromFieldPath: "metadata.labels[crossplane.io/claim-namespace]"
          toFieldPath: "spec.writeConnectionSecretToRef.namespace"
        # set the name of the DB resource to be the name defined in the claim
        - fromFieldPath: "spec.parameters.dbName"
          toFieldPath: "metadata.annotations[crossplane.io/external-name]"
        # set app Label
        - fromFieldPath: "metadata.labels[crossplane.io/claim-name]"
          toFieldPath: "metadata.labels[crossplane.io/app]"
    - name: cloudsqldbuser
      base:
        apiVersion: sql.gcp.jet.crossplane.io/v1alpha2
        kind: User
        metadata:
          annotations: 
            # set the name of the DB User, this is hardcoded for demo but should come from the CRD
            crossplane.io/external-name: "crossplane-qa-central@my-cluster"   <--------------------------------------
        spec:
          providerConfigRef:
            name: crossplane-provider-jet-gcp
          deletionPolicy: Delete
          forProvider:
            instanceSelector:
              MatchControllerRef: true
            type: CLOUD_IAM_SERVICE_ACCOUNT
          writeConnectionSecretToRef:
            namespace: crossplane
            name: cloudsqluser
      patches:
        # set the secret name to the claim name
        - fromFieldPath: "metadata.labels[crossplane.io/claim-name]"
          toFieldPath: "spec.writeConnectionSecretToRef.name"
          transforms:
            - type: string
              string:
                fmt: "%s-pguser"
        # change secret namespace to the one of the claim
        - fromFieldPath: "metadata.labels[crossplane.io/claim-namespace]"
          toFieldPath: "spec.writeConnectionSecretToRef.namespace"
        # set app Label
        - fromFieldPath: "metadata.labels[crossplane.io/claim-name]"
          toFieldPath: "metadata.labels[crossplane.io/app]"

Claim

apiVersion: database.wk/v1alpha1
kind: JetPostgreSQL
metadata:
  namespace: my-namespace
  name: jet-db-claim-4
spec:
  parameters:
    storageGB: 25
    dbName: xrdb
    instanceSize: small # small, medium, large
  writeConnectionSecretToRef:
    name: jet-xr-db-claim-details

What environment did it happen in?

Crossplane version: 1.9.0
Provider version: provider-jet-gcp-controller:v0.2.0-preview

Running on Google GKE

 k version                                                                                                                                                                                                       

Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.3", GitCommit:"aef86a93758dc3cb2c658dd9657ab4ad4afc21cb", GitTreeState:"clean", BuildDate:"2022-07-13T14:21:56Z", GoVersion:"go1.18.4", Compiler:"gc", Platform:"darwin/amd64"}
Kustomize Version: v4.5.4
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.10-gke.600", GitCommit:"2c921d7b040ed9c5a3a1f9407fb109b74d72d0a4", GitTreeState:"clean", BuildDate:"2022-06-02T09:20:24Z", GoVersion:"go1.16.15b7", Compiler:"gc", Platform:"linux/amd64"}
@prune998 prune998 added the bug Something isn't working label Aug 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant