Geo GraphQL error "The resource that you are attempting to access does not exist..."

Problem

Follow up for !114673 (comment 1387826024).

Geo sites need to be able to handle GraphQL requests for data specific to secondary sites. This was done by creating a very special endpoint /api/v4/geo/node_proxy/:id/graphql which routes the query to the appropriate secondary site. It magically works even if your request is initially routed to the primary site, or a different secondary site.

We are now adding more GraphQL types and mutations. These produce autogenerated GraphQL reference documentation.

But, one would normally expect that everything in the autogenerated docs can be used with /api/graphql. Unfortunately the Geo queries won't work like that:

➜  gitlab git:(64cc7a1c018b) curl --location 'https://gdk.test:3443/api/graphql' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $GITLAB_PAT' \
--data '{"query":"mutation {\n  geoRegistriesUpdate(\n    input: {\n      action: REVERIFY\n      registryId: \"gid://gitlab/Geo::UploadRegistry/1\",\n      registryClass: UPLOAD_REGISTRY\n    }\n  ) {\n    registry {\n      ... on UploadRegistry {\n        id\n        state\n        retryCount\n        lastSyncFailure\n        retryAt\n        lastSyncedAt\n        verifiedAt\n        verificationRetryAt\n        createdAt\n        fileId    \n      }\n    }\n    errors\n  }\n}\n"}'
{"data":{"geoRegistriesUpdate":null},"errors":[{"message":"The resource that you are attempting to access does not exist or you don't have permission to perform this action","locations":[{"line":2,"column":3}],"path":["geoRegistriesUpdate"]}]}%                                                                                                                      
➜  gitlab git:(64cc7a1c018b) curl --location 'https://gdk2.test:3444/api/graphql' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $GITLAB_PAT' \
--data '{"query":"mutation {\n  geoRegistriesUpdate(\n    input: {\n      action: REVERIFY\n      registryId: \"gid://gitlab/Geo::UploadRegistry/1\",\n      registryClass: UPLOAD_REGISTRY\n    }\n  ) {\n    registry {\n      ... on UploadRegistry {\n        id\n        state\n        retryCount\n        lastSyncFailure\n        retryAt\n        lastSyncedAt\n        verifiedAt\n        verificationRetryAt\n        createdAt\n        fileId    \n      }\n    }\n    errors\n  }\n}\n"}'
{"data":{"geoRegistriesUpdate":null},"errors":[{"message":"The resource that you are attempting to access does not exist or you don't have permission to perform this action","locations":[{"line":2,"column":3}],"path":["geoRegistriesUpdate"]}]}% 

It doesn't work because:

  1. The request is ambiguous-- the desired Geo site isn't specified. Geo expects it to be specified in the path /api/v4/geo/node_proxy/:id/graphql.
  2. Even if the site were specified, for example, in the query, the special Geo routing implementation would need to account for that.

Proposal

Make it possible to make Geo-specific queries with /api/graphql.

For GraphQL queries operating on Geo-site-specific data:

  1. The query should require a Geo site ID param to eliminate the ambiguity when sending the request to /api/graphql.
  2. Make /api/graphql do the magic Geo site routing.

For example, in curl --location 'https://gdk2.test:3444/api/graphql' --header 'Content-Type: application/json' --header 'Authorization: Bearer $GITLAB_PAT' --data '{"query":"mutation { geoRegistriesUpdate( input: { action: REVERIFY registryId: \"gid://gitlab/Geo::UploadRegistry/1\", registryClass: UPLOAD_REGISTRY } ) { registry { ... on UploadRegistry { id state retryCount lastSyncFailure retryAt lastSyncedAt verifiedAt verificationRetryAt createdAt fileId } } errors } } "}', Geo site could be specified in the query like curl --location 'https://gdk2.test:3444/api/graphql' --header 'Content-Type: application/json' --header 'Authorization: Bearer $GITLAB_PAT' --data '{"query":"mutation { geoRegistriesUpdate( input: { geoSiteId: 2, action: REVERIFY registryId: \"gid://gitlab/Geo::UploadRegistry/1\", registryClass: UPLOAD_REGISTRY } ) { registry { ... on UploadRegistry { id state retryCount lastSyncFailure retryAt lastSyncedAt verifiedAt verificationRetryAt createdAt fileId } } errors } } "}'.

Notice geoSiteId: 2, added to the input of the geoRegistriesUpdate mutation.

This might be difficult. It seems like, somewhere in the GraphQL processing, we would need to inspect the query, realize that it's Geo-site-specific, and then call it on the appropriate Geo site.

Other ideas

Documentation?

Better error output when attempting Geo-site-specific queries with /api/graphql?

Edited by Michael Kozono