provider-gcp: googleapi: Error 400: Cluster.name must be less than 40 characters -- when using long namespace name

Problem

Created a KubernetesCluster claim in a namespace with a long name and got this error:

    - lastTransitionTime: '2020-04-21T22:13:30Z'
      message: >-
        googleapi: Error 400: Cluster.name must be less than 40 characters.,
        badRequest
      reason: Encountered an error during resource reconciliation
      status: 'False'
      type: Synced

Using:

  • Wordpress v0.3.0
  • GCP Provider v0.8.0
  • GCP Sample Stack v0.4.0
  • Crossplane 0.10.0-rc.49.gae92a62

Expected

Provider GCP should truncate to a smaller random name as needed by the google API.

Details

WordpressInstance

apiVersion: wordpress.apps.crossplane.io/v1alpha1
kind: WordpressInstance
metadata:
  creationTimestamp: '2020-04-21T22:13:26Z'
  generation: 1
  name: wp1
  namespace: apr21-prasek-dev-gcp-ws1
  resourceVersion: '729881'
  selfLink: >-
    /apis/wordpress.apps.crossplane.io/v1alpha1/namespaces/apr21-prasek-dev-gcp-ws1/wordpressinstances/wp1
  uid: 28d78471-3390-4488-8b68-2bde0bc84b4d
spec:
  provisionPolicy: ProvisionNewCluster
status:
  conditions:
    - lastTransitionTime: '2020-04-21T22:13:28Z'
      reason: Successfully reconciled resource
      status: 'True'
      type: Synced

KubernetesCluster

apiVersion: compute.crossplane.io/v1alpha1
kind: KubernetesCluster
metadata:
  creationTimestamp: '2020-04-21T22:13:28Z'
  generation: 3
  labels:
    app: wp1
    core.crossplane.io/parent-group: wordpress.apps.crossplane.io
    core.crossplane.io/parent-kind: WordpressInstance
    core.crossplane.io/parent-name: wp1
    core.crossplane.io/parent-namespace: apr21-prasek-dev-gcp-ws1
    core.crossplane.io/parent-uid: 28d78471-3390-4488-8b68-2bde0bc84b4d
    core.crossplane.io/parent-version: v1alpha1
  name: wp1-cluster
  namespace: apr21-prasek-dev-gcp-ws1
  ownerReferences:
    - apiVersion: wordpress.apps.crossplane.io/v1alpha1
      blockOwnerDeletion: true
      kind: WordpressInstance
      name: wp1
      uid: 28d78471-3390-4488-8b68-2bde0bc84b4d
  resourceVersion: '729910'
  selfLink: >-
    /apis/compute.crossplane.io/v1alpha1/namespaces/apr21-prasek-dev-gcp-ws1/kubernetesclusters/wp1-cluster
  uid: e26bab4f-33f7-4005-87ea-b32a256f57b3
spec:
  classRef:
    apiVersion: compute.gcp.crossplane.io/v1alpha3
    kind: GKEClusterClass
    name: apr21-prasek-dev-gcp-gkeclusterclass
    uid: a9c63352-82cf-4ae7-9061-9b98675819df
  resourceRef:
    apiVersion: compute.gcp.crossplane.io/v1alpha3
    kind: GKECluster
    name: apr21-prasek-dev-gcp-ws1-wp1-cluster-2m5mn
    uid: 7bf28fc6-96b0-4bea-b6f4-686f1da7bbaa
  writeConnectionSecretToRef:
    name: wp1-cluster
status:
  conditions:
    - lastTransitionTime: '2020-04-21T22:13:30Z'
      reason: Managed claim is waiting for managed resource to become bindable
      status: 'False'
      type: Ready
    - lastTransitionTime: '2020-04-21T22:13:30Z'
      reason: Successfully reconciled resource
      status: 'True'
      type: Synced

GKECluster

apiVersion: compute.gcp.crossplane.io/v1alpha3
kind: GKECluster
metadata:
  annotations:
    crossplane.io/external-name: apr21-prasek-dev-gcp-ws1-wp1-cluster-2m5mn
  creationTimestamp: '2020-04-21T22:13:30Z'
  finalizers:
    - finalizer.gke.compute.gcp.crossplane.io
  generateName: apr21-prasek-dev-gcp-ws1-wp1-cluster-
  generation: 3
  name: apr21-prasek-dev-gcp-ws1-wp1-cluster-2m5mn
  resourceVersion: '729920'
  selfLink: >-
    /apis/compute.gcp.crossplane.io/v1alpha3/gkeclusters/apr21-prasek-dev-gcp-ws1-wp1-cluster-2m5mn
  uid: 7bf28fc6-96b0-4bea-b6f4-686f1da7bbaa
spec:
  claimRef:
    apiVersion: compute.crossplane.io/v1alpha1
    kind: KubernetesCluster
    name: wp1-cluster
    namespace: apr21-prasek-dev-gcp-ws1
    uid: e26bab4f-33f7-4005-87ea-b32a256f57b3
  classRef:
    apiVersion: compute.gcp.crossplane.io/v1alpha3
    kind: GKEClusterClass
    name: apr21-prasek-dev-gcp-gkeclusterclass
    uid: a9c63352-82cf-4ae7-9061-9b98675819df
  clusterSecondaryRangeName: pods
  enableIPAlias: true
  machineType: n1-standard-1
  network: projects/crossplane-playground/global/networks/apr21-prasek-dev-gcp-network
  networkRef:
    name: apr21-prasek-dev-gcp-network
  numNodes: 1
  providerRef:
    name: apr21-prasek-dev-gcp-gcp-provider
  reclaimPolicy: Delete
  servicesSecondaryRangeName: services
  subnetwork: >-
    projects/crossplane-playground/regions/us-west1/subnetworks/apr21-prasek-dev-gcp-subnetwork
  subnetworkRef:
    name: apr21-prasek-dev-gcp-subnetwork
  writeConnectionSecretToRef:
    name: e26bab4f-33f7-4005-87ea-b32a256f57b3
    namespace: crossplane-system
  zone: us-west1-b
status:
  conditions:
    - lastTransitionTime: '2020-04-21T22:13:30Z'
      reason: Successfully resolved resource references to other resources
      status: 'True'
      type: ReferencesResolved
    - lastTransitionTime: '2020-04-21T22:13:30Z'
      reason: Resource is being created
      status: 'False'
      type: Ready
    - lastTransitionTime: '2020-04-21T22:13:30Z'
      message: >-
        googleapi: Error 400: Cluster.name must be less than 40 characters.,
        badRequest
      reason: Encountered an error during resource reconciliation
      status: 'False'
      type: Synced

Also note this is happening on Azure as well:

apiVersion: compute.azure.crossplane.io/v1alpha3
kind: AKSCluster
metadata:
  annotations:
    crossplane.io/external-name: apr21-prasek-dev-azure-ws1-wp1-cluster-kq4wb
  creationTimestamp: '2020-04-21T22:23:44Z'
  finalizers:
    - finalizer.managedresource.crossplane.io
  generateName: apr21-prasek-dev-azure-ws1-wp1-cluster-
  generation: 2
  name: apr21-prasek-dev-azure-ws1-wp1-cluster-kq4wb
  resourceVersion: '758606'
  selfLink: >-
    /apis/compute.azure.crossplane.io/v1alpha3/aksclusters/apr21-prasek-dev-azure-ws1-wp1-cluster-kq4wb
  uid: 1a9955b8-6f92-4cb5-bcaa-bd1a6fea730d
spec:
  claimRef:
    apiVersion: compute.crossplane.io/v1alpha1
    kind: KubernetesCluster
    name: wp1-cluster
    namespace: apr21-prasek-dev-azure-ws1
    uid: 94eed131-9923-47de-9b62-e56cb8f8204d
  classRef:
    apiVersion: compute.azure.crossplane.io/v1alpha3
    kind: AKSClusterClass
    name: apr21-prasek-dev-azure-akscluster
    uid: c4738520-12c2-4591-9103-50f0ee1e4d93
  dnsNamePrefix: crossplane-aks
  location: West US
  nodeCount: 1
  nodeVMSize: Standard_B2s
  providerRef:
    name: apr21-prasek-dev-azure-azure-provider
  reclaimPolicy: Delete
  resourceGroupName: apr21-prasek-dev-azure-resourcegroup
  resourceGroupNameRef:
    name: apr21-prasek-dev-azure-resourcegroup
  version: 1.14.8
  vnetSubnetID: >-
    /subscriptions/038f2b7c-3265-43b8-8624-c9ad5da610a8/resourceGroups/apr21-prasek-dev-azure-resourcegroup/providers/Microsoft.Network/virtualNetworks/apr21-prasek-dev-azure-virtualnetwork/subnets/apr21-prasek-dev-azure-subnet
  vnetSubnetIDRef:
    name: apr21-prasek-dev-azure-subnet
  writeConnectionSecretToRef:
    name: 94eed131-9923-47de-9b62-e56cb8f8204d
    namespace: crossplane-system
status:
  conditions:
    - lastTransitionTime: '2020-04-21T23:15:26Z'
      message: >-
        [{reference:apr21-prasek-dev-azure-resourcegroup status:NotReady}
        {reference:apr21-prasek-dev-azure-subnet status:NotFound}]
      reason: 'One or more referenced resources do not exist, or are not yet Ready'
      status: 'False'
      type: ReferencesResolved
    - lastTransitionTime: '2020-04-21T22:23:46Z'
      reason: Resource is being created
      status: 'False'
      type: Ready
    - lastTransitionTime: '2020-04-21T22:23:57Z'
      message: >-
        create failed: cannot create AKSCluster:
        containerservice.ManagedClustersClient#CreateOrUpdate: Failure sending
        request: StatusCode=400 -- Original Error: Code="InvalidParameter"
        Message="The length of the node resource group name is too long. The
        maximum length is 80 and the length of the value provided is 91. Please
        see https://aka.ms/aks-naming-rules for more details." Target="name"
      reason: Encountered an error during resource reconciliation
      status: 'False'
      type: Synced
  endpoint: ''

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (14 by maintainers)

Most upvoted comments

This sounds like it’s pretty much putting the onus on each managed resource developer to keep up with the quirks and restrictions of the API.

That’s correct and I mean developer knows this information or at least it’s pretty easy to find and I don’t think that’s a problem like spec fields because I don’t expect validation rule of a resource name ever change.

Think of our self-service scenario. As a user, I’m given a namespace with my user-id or some long string that identifies me. If it’s like 25 characters, suddenly I’m not able use N services and it’s not my fault. Or thinking of CI/CD pipelines, the namespace could be some kind of UID and the pipeline would fail just because of the namespace string being long.

Honestly, I can’t figure out a better argument than this. I would say if folks don’t feel comfortable about it, then let’s document that annotation really well and look for user feedback. If we decide to do the truncation at some point, the change shouldn’t be a breaking one since it won’t affect the existing resources.

This has been brought up during GCP ServiceAccount implementation as well, which allows only max of 30 characters as name.

I think the problem here is that the decision of the namespace and/or name of the claim is not made with what services that the user is going to use in mind and that sounds reasonable to me. For example, in this case I see that the namespace is chosen to enumerate a test run with a date and that’s perfectly fine. However, it suddenly makes some of the resources practically unavailable for use. So, the error is not because user chose a name but because their namespace/name was incompatible.

Think of our self-service scenario. As a user, I’m given a namespace with my user-id or some long string that identifies me. If it’s like 25 characters, suddenly I’m not able use N services and it’s not my fault. Or thinking of CI/CD pipelines, the namespace could be some kind of UID and the pipeline would fail just because of the namespace string being long. It’s also not only one resource, the max length of the name/namespace of your resource is determined by the min of max allowed length between all the resources you’re provisioning. If you have GKECluster as one of the resources, then you’re limited to max 40 chars even though other resources allow longer names.

In short, it’s tough to keep up with the various (and sometimes changing) requirements of names and other cloud provider fields, so we take the approach of letting you provide an invalid value and returning the error from the cloud provider so that you can fix it.

IMO, this is a problem that we need to fix in our defaulting mechanism rather than something we have to suffer because cloud provider says so. We should definitely return error and not modify the config inputs, but this input is produced by us. In fact, when you look at it, I don’t see a case where the allowed length of a name of the resource getting changed at all as opposed to validation of config fields. I agree that we should let the user know about the error and fix it but in this case it’s not the user, it’s our default name generation; user should not worry about the name length validation of N resources when they just create a namespace/name of a claim. That’s not to say let’s decouple it completely, but I would say it should be best-effort rather than as-is.

would it make sense for the Reconciler to default to a shorter auto-generated default crossplane.io/external-name in configurator.go#L65 which uses {claim-namespace}-{claim-name}-{random-string} if crossplane.io/external-name isn’t specified on the claim?

I think the change should be per managed resource rather than on claim level, since claim doesn’t know what it’s going to be bound to. I would propose that we’d make NameAsExternalName accept a max length for the external name that the dev will choose in Setup of the managed reconciler, like other options. The name of the managed resource will still be <claim ns>-<claim name>-<5 rand chars> but if that name is longer than max allowed, it will be truncated until max-6 chars and -<5 rand chars> will be appended and that’s going to be used as crossplane.io/external-name rather than blindly returning name of the managed resource.