google-github-actions / get-gke-credentials

A GitHub Action that configure authentication to a GKE cluster.
https://cloud.google.com/gke
Apache License 2.0
105 stars 41 forks source link

Please add support for gkeMemberships in Connect Gateway endpoint URL #245

Closed dinvlad closed 1 year ago

dinvlad commented 2 years ago

TL;DR

Some recent clusters and/or Connect Gateway API seem to be using a slightly different format for their endpoint:

 https://connectgateway.googleapis.com/v1/projects/<PROJECT_NUMBER>/locations/<LOCATION>/gkeMemberships/<MEMBERSHIP_NAME>

(note gkeMemberships here instead of just memberships).

Connections using the older format don't seem to work, and I'd like to add support for that.

Detailed design

My proposed design for backwards compatibility is to just allow both formats with a non-capturing group in the membershipResourceNamePattern regex:

/^projects\/(.+)\/locations\/(.+)\/(?:memberships|gkeMemberships)\/(.+)$/i,

Alternatively, if the new format is the new "default" for the Connect Gateway API, we should adjust the action to use only that instead of memberships (but I'm curious to hear your thoughts, since I don't have an inside view).

The current regex makes it impossible to override the new endpoints using fleet_membership_name. And when the old format is used, the connection just hangs for a little and then returns the server doesn't have a resource type <X> for any request when using this Action.

I've tested this locally with the same Workload Identity Service Account, and only the endpoint with gkeMemberships works:

$ curl -sH "Authorization: Bearer $(gcloud auth print-access-token)" https://connectgateway.googleapis.com/v1/projects/<PROJECT_NUMBER>/locations/global/gkeMemberships/<MEMBERSHIP>/api/v1/namespaces/default
{"kind":"Namespace","apiVersion":"v1","metadata":{"name":"default","uid":"<uuid>","resourceVersion":"204","creationTimestamp":"<timestamp>","labels":{"kubernetes.io/metadata.name":"default"},"managedFields":[{"manager":"kube-apiserver","operation":"Update","apiVersion":"v1","time":"<time>","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:labels":{".":{},"f:kubernetes.io/metadata.name":{}}}}}]},"spec":{"finalizers":["kubernetes"]},"status":{"phase":"Active"}}

$ curl -sH "Authorization: Bearer $(gcloud auth print-access-token)" https://connectgateway.googleapis.com/v1/projects/<PROJECT_NUMBER>/locations/global/memberships/<MEMBERSHIP>/api/v1/namespaces/default
[{
  "error": {
    "code": 400,
    "message": "Request contains an invalid argument.",
    "status": "INVALID_ARGUMENT"
  }
}
]

When using gcloud container fleet memberships get-credentials locally, it also stores the URL in the new format (which is how I was able to discover it) - e.g.

$  k config view | head -4
apiVersion: v1
clusters:
- cluster:
    server: https://connectgateway.googleapis.com/v1/projects/<PROJECT_NUMBER>/locations/global/memberships/<MEMBERSHIP>

Curiously, the fleet membership API also returns the URL is the old format, so I'm not sure how gcloud is able to infer gkeMemberships from that (but assuming there's some business logic for that):

$ gcloud container fleet memberships describe <MEMBERSHIP> --format 'value(name)'
projects/<PROJECT_ID>/locations/global/memberships/<MEMBERSHIP>

Additional information

I've only found reference to gkeMemberships in a very recent Google Cloud blog post, so I'm assuming this change is quite new, but it seems to be breaking. It appears not to a public API yet, hence such changes are expected, but the Action needs to be adjusted as well.

bharathkkb commented 1 year ago

@dinvlad Thanks for the report and sorry for the delay. Did you notice this gkeMemberships in the URI as a response from gkehub API or within the kubeconfig generated via gcloud container fleet memberships get-credentials? From your snippet for k config view | head -4 it seemed like it was still using the https://connectgateway.googleapis.com/.../memberships/<MEMBERSHIP> format. I tried a repro and this is what my kubeconfig also looked like.

I did look at the blog post and some other docs and from which it seemed like both gkeMemberships and memberships are supported. The distinction per docs seemed to be based on the way you register the cluster. I will try following up with the service owner for clarity and next steps.