Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Bug Report: ambiguously-named clusters cannot be targeted with the proxy endpoint #15901

Open
2 tasks done
jamieklassen opened this issue Jan 23, 2023 · 5 comments
Open
2 tasks done
Labels
area:kubernetes Related to the Kubernetes Project Area - not deploying Backstage with k8s. bug Something isn't working will-fix We will fix this at some point

Comments

@jamieklassen
Copy link
Member

jamieklassen commented Jan 23, 2023

📜 Description

If two clusters located by Backstage have the same name, proxy requests targeting that name will always be routed to the first one -- there's no way to target the second one! You can test this by curling the proxy endpoint for all namespaces, specifying the ambiguous cluster name, and providing a bearer token that is only valid for the second cluster.

👍 Expected behavior

Well, depends on what you know. If you're only aware of the second cluster you might expect to see namespaces. If you know there are two ambiguously-named clusters, you might expect to see an error about this.

👎 Actual Behavior with Screenshots

console prints

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}

This indicates that only the first cluster got queried -- since the token we used isn't valid for that cluster.

👟 Reproduction steps

  1. Create two kind clusters: kind create cluster --name kind-1 && kind create cluster --name kind-2
  2. Grab their server URLs:
    export KIND_1_URL=$(kubectl config view -o jsonpath='{.clusters[?(@.name == "kind-kind-1")].cluster.server}')
    export KIND_2_URL=$(kubectl config view -o jsonpath='{.clusters[?(@.name == "kind-kind-2")].cluster.server}')
  3. Get a high-powered bearer token for the second cluster:
    kubectl config use-context kind-kind-2
    kubectl create clusterrolebinding default-sa-admin --serviceaccount default:default --clusterrole cluster-admin
    export TOKEN=$(kubectl get secret -o go-template='{{(index .items 0).data.token | base64decode}}')
  4. Set up an app-config to target these clusters, but with both having the same name:
    kubernetes:
      serviceLocatorMethod:
        type: 'multiTenant'
      clusterLocatorMethods:
        - type: config
          clusters:
            - name: kind
              url: ${KIND_1_URL}
              skipTLSVerify: true
              skipMetricsLookup: true
              authProvider: serviceAccount
            - name: kind
              url: ${KIND_2_URL}
              skipTLSVerify: true
              skipMetricsLookup: true
              authProvider: serviceAccount
  5. Run the backend: yarn start-backend
  6. In a separate process, try to fetch namespaces specifying the ambiguous cluster name, using the token for the second cluster:
    curl -H "Authorization: Bearer $TOKEN" \
      -H 'X-Kubernetes-Cluster: kind' \
      localhost:7007/api/kubernetes/proxy/api/v1/namespaces

📃 Provide the context for the Bug.

Cause

We already know that this bug is caused by the find() call here:

const cluster = await this.clusterSupplier
.getClusters()
.then(clusters => clusters.find(c => c.name === clusterName));

According to the MDN docs:

The find() method returns the first element in the provided array that satisfies the provided testing function

and this is why it is always the first cluster with the given name that gets targeted.

Background

In October 2022, in my big "Let's just do single-cluster" comment, I suggested

At the moment there is no guarantee within the kubernetes subsystem that clusters have unique names (let's file an issue about this), so if this procedure results in multiple clusters, fail the response.

Unfortunately we didn't implement that requirement, and I'm just now filing part of the relevant issue! The rest of the issue should take the form of an RFC about unique identifiers for Kubernetes clusters generally.

🖥️ Your Environment

If you really wanna know, I'm running MacOS Ventura 13.1 on a 2019 16-inch Macbook Pro, and I just completed the reproduction steps with the code on master at the time of writing:

% yarn backstage-cli info
OS:   Darwin 22.2.0 - darwin/x64
node: v16.19.0
yarn: 3.2.3
cli:  0.22.1 (local)
backstage:  N/A

Dependencies:
  @backstage/app-defaults                                        0.0.0-use.local
  @backstage/backend-app-api                                     0.0.0-use.local
  @backstage/backend-common                                      0.0.0-use.local
  @backstage/backend-defaults                                    0.0.0-use.local
  @backstage/backend-plugin-api                                  0.0.0-use.local
  @backstage/backend-tasks                                       0.0.0-use.local
  @backstage/backend-test-utils                                  0.0.0-use.local
  @backstage/catalog-client                                      0.0.0-use.local
  @backstage/catalog-model                                       0.0.0-use.local
  @backstage/cli-common                                          0.0.0-use.local
  @backstage/cli                                                 0.0.0-use.local
  @backstage/codemods                                            0.0.0-use.local
  @backstage/config-loader                                       0.0.0-use.local
  @backstage/config                                              0.0.0-use.local
  @backstage/core-app-api                                        0.0.0-use.local
  @backstage/core-components                                     0.0.0-use.local
  @backstage/core-plugin-api                                     0.0.0-use.local
  @backstage/create-app                                          0.0.0-use.local
  @backstage/dev-utils                                           0.0.0-use.local
  @backstage/errors                                              0.0.0-use.local
  @backstage/integration-aws-node                                0.0.0-use.local
  @backstage/integration-react                                   0.0.0-use.local
  @backstage/integration                                         0.0.0-use.local
  @backstage/plugin-adr-backend                                  0.0.0-use.local
  @backstage/plugin-adr-common                                   0.0.0-use.local
  @backstage/plugin-adr                                          0.0.0-use.local
  @backstage/plugin-airbrake-backend                             0.0.0-use.local
  @backstage/plugin-airbrake                                     0.0.0-use.local
  @backstage/plugin-allure                                       0.0.0-use.local
  @backstage/plugin-analytics-module-ga                          0.0.0-use.local
  @backstage/plugin-apache-airflow                               0.0.0-use.local
  @backstage/plugin-api-docs-module-protoc-gen-doc               0.0.0-use.local
  @backstage/plugin-api-docs                                     0.0.0-use.local
  @backstage/plugin-apollo-explorer                              0.0.0-use.local
  @backstage/plugin-app-backend                                  0.0.0-use.local
  @backstage/plugin-auth-backend                                 0.0.0-use.local
  @backstage/plugin-auth-node                                    0.0.0-use.local
  @backstage/plugin-azure-devops-backend                         0.0.0-use.local
  @backstage/plugin-azure-devops-common                          0.0.0-use.local
  @backstage/plugin-azure-devops                                 0.0.0-use.local
  @backstage/plugin-azure-sites-backend                          0.0.0-use.local
  @backstage/plugin-azure-sites-common                           0.0.0-use.local
  @backstage/plugin-azure-sites                                  0.0.0-use.local
  @backstage/plugin-badges-backend                               0.0.0-use.local
  @backstage/plugin-badges                                       0.0.0-use.local
  @backstage/plugin-bazaar-backend                               0.0.0-use.local
  @backstage/plugin-bazaar                                       0.0.0-use.local
  @backstage/plugin-bitbucket-cloud-common                       0.0.0-use.local
  @backstage/plugin-bitrise                                      0.0.0-use.local
  @backstage/plugin-catalog-backend-module-aws                   0.0.0-use.local
  @backstage/plugin-catalog-backend-module-azure                 0.0.0-use.local
  @backstage/plugin-catalog-backend-module-bitbucket-cloud       0.0.0-use.local
  @backstage/plugin-catalog-backend-module-bitbucket-server      0.0.0-use.local
  @backstage/plugin-catalog-backend-module-bitbucket             0.0.0-use.local
  @backstage/plugin-catalog-backend-module-gerrit                0.0.0-use.local
  @backstage/plugin-catalog-backend-module-github                0.0.0-use.local
  @backstage/plugin-catalog-backend-module-gitlab                0.0.0-use.local
  @backstage/plugin-catalog-backend-module-incremental-ingestion 0.0.0-use.local
  @backstage/plugin-catalog-backend-module-ldap                  0.0.0-use.local
  @backstage/plugin-catalog-backend-module-msgraph               0.0.0-use.local
  @backstage/plugin-catalog-backend-module-openapi               0.0.0-use.local
  @backstage/plugin-catalog-backend                              0.0.0-use.local
  @backstage/plugin-catalog-common                               0.0.0-use.local
  @backstage/plugin-catalog-graph                                0.0.0-use.local
  @backstage/plugin-catalog-graphql                              0.0.0-use.local
  @backstage/plugin-catalog-import                               0.0.0-use.local
  @backstage/plugin-catalog-node                                 0.0.0-use.local
  @backstage/plugin-catalog-react                                0.0.0-use.local
  @backstage/plugin-catalog                                      0.0.0-use.local
  @backstage/plugin-cicd-statistics-module-gitlab                0.0.0-use.local
  @backstage/plugin-cicd-statistics                              0.0.0-use.local
  @backstage/plugin-circleci                                     0.0.0-use.local
  @backstage/plugin-cloudbuild                                   0.0.0-use.local
  @backstage/plugin-code-climate                                 0.0.0-use.local
  @backstage/plugin-code-coverage-backend                        0.0.0-use.local
  @backstage/plugin-code-coverage                                0.0.0-use.local
  @backstage/plugin-codescene                                    0.0.0-use.local
  @backstage/plugin-config-schema                                0.0.0-use.local
  @backstage/plugin-cost-insights-common                         0.0.0-use.local
  @backstage/plugin-cost-insights                                0.0.0-use.local
  @backstage/plugin-dynatrace                                    0.0.0-use.local
  @backstage/plugin-events-backend-module-aws-sqs                0.0.0-use.local
  @backstage/plugin-events-backend-module-azure                  0.0.0-use.local
  @backstage/plugin-events-backend-module-bitbucket-cloud        0.0.0-use.local
  @backstage/plugin-events-backend-module-gerrit                 0.0.0-use.local
  @backstage/plugin-events-backend-module-github                 0.0.0-use.local
  @backstage/plugin-events-backend-module-gitlab                 0.0.0-use.local
  @backstage/plugin-events-backend-test-utils                    0.0.0-use.local
  @backstage/plugin-events-backend                               0.0.0-use.local
  @backstage/plugin-events-node                                  0.0.0-use.local
  @backstage/plugin-explore-backend                              0.0.0-use.local
  @backstage/plugin-explore-common                               0.0.0-use.local
  @backstage/plugin-explore-react                                0.0.0-use.local
  @backstage/plugin-explore                                      0.0.0-use.local
  @backstage/plugin-firehydrant                                  0.0.0-use.local
  @backstage/plugin-fossa                                        0.0.0-use.local
  @backstage/plugin-gcalendar                                    0.0.0-use.local
  @backstage/plugin-gcp-projects                                 0.0.0-use.local
  @backstage/plugin-git-release-manager                          0.0.0-use.local
  @backstage/plugin-github-actions                               0.0.0-use.local
  @backstage/plugin-github-deployments                           0.0.0-use.local
  @backstage/plugin-github-issues                                0.0.0-use.local
  @backstage/plugin-github-pull-requests-board                   0.0.0-use.local
  @backstage/plugin-gitops-profiles                              0.0.0-use.local
  @backstage/plugin-gocd                                         0.0.0-use.local
  @backstage/plugin-graphiql                                     0.0.0-use.local
  @backstage/plugin-graphql-backend                              0.0.0-use.local
  @backstage/plugin-home                                         0.0.0-use.local
  @backstage/plugin-ilert                                        0.0.0-use.local
  @backstage/plugin-jenkins-backend                              0.0.0-use.local
  @backstage/plugin-jenkins-common                               0.0.0-use.local
  @backstage/plugin-jenkins                                      0.0.0-use.local
  @backstage/plugin-kafka-backend                                0.0.0-use.local
  @backstage/plugin-kafka                                        0.0.0-use.local
  @backstage/plugin-kubernetes-backend                           0.0.0-use.local
  @backstage/plugin-kubernetes-common                            0.0.0-use.local
  @backstage/plugin-kubernetes                                   0.0.0-use.local
  @backstage/plugin-lighthouse                                   0.0.0-use.local
  @backstage/plugin-newrelic-dashboard                           0.0.0-use.local
  @backstage/plugin-newrelic                                     0.0.0-use.local
  @backstage/plugin-org-react                                    0.0.0-use.local
  @backstage/plugin-org                                          0.0.0-use.local
  @backstage/plugin-pagerduty                                    0.0.0-use.local
  @backstage/plugin-periskop-backend                             0.0.0-use.local
  @backstage/plugin-periskop                                     0.0.0-use.local
  @backstage/plugin-permission-backend                           0.0.0-use.local
  @backstage/plugin-permission-common                            0.0.0-use.local
  @backstage/plugin-permission-node                              0.0.0-use.local
  @backstage/plugin-permission-react                             0.0.0-use.local
  @backstage/plugin-playlist-backend                             0.0.0-use.local
  @backstage/plugin-playlist-common                              0.0.0-use.local
  @backstage/plugin-playlist                                     0.0.0-use.local
  @backstage/plugin-proxy-backend                                0.0.0-use.local
  @backstage/plugin-rollbar-backend                              0.0.0-use.local
  @backstage/plugin-rollbar                                      0.0.0-use.local
  @backstage/plugin-scaffolder-backend-module-cookiecutter       0.0.0-use.local
  @backstage/plugin-scaffolder-backend-module-rails              0.0.0-use.local
  @backstage/plugin-scaffolder-backend-module-sentry             0.0.0-use.local
  @backstage/plugin-scaffolder-backend-module-yeoman             0.0.0-use.local
  @backstage/plugin-scaffolder-backend                           0.0.0-use.local
  @backstage/plugin-scaffolder-common                            0.0.0-use.local
  @backstage/plugin-scaffolder-node                              0.0.0-use.local
  @backstage/plugin-scaffolder-react                             0.0.0-use.local
  @backstage/plugin-scaffolder                                   0.0.0-use.local
  @backstage/plugin-search-backend-module-elasticsearch          0.0.0-use.local
  @backstage/plugin-search-backend-module-pg                     0.0.0-use.local
  @backstage/plugin-search-backend-node                          0.0.0-use.local
  @backstage/plugin-search-backend                               0.0.0-use.local
  @backstage/plugin-search-common                                0.0.0-use.local
  @backstage/plugin-search-react                                 0.0.0-use.local
  @backstage/plugin-search                                       0.0.0-use.local
  @backstage/plugin-sentry                                       0.0.0-use.local
  @backstage/plugin-shortcuts                                    0.0.0-use.local
  @backstage/plugin-sonarqube-backend                            0.0.0-use.local
  @backstage/plugin-sonarqube-react                              0.0.0-use.local
  @backstage/plugin-sonarqube                                    0.0.0-use.local
  @backstage/plugin-splunk-on-call                               0.0.0-use.local
  @backstage/plugin-stack-overflow-backend                       0.0.0-use.local
  @backstage/plugin-stack-overflow                               0.0.0-use.local
  @backstage/plugin-tech-insights-backend-module-jsonfc          0.0.0-use.local
  @backstage/plugin-tech-insights-backend                        0.0.0-use.local
  @backstage/plugin-tech-insights-common                         0.0.0-use.local
  @backstage/plugin-tech-insights-node                           0.0.0-use.local
  @backstage/plugin-tech-insights                                0.0.0-use.local
  @backstage/plugin-tech-radar                                   0.0.0-use.local
  @backstage/plugin-techdocs-addons-test-utils                   0.0.0-use.local
  @backstage/plugin-techdocs-backend                             0.0.0-use.local
  @backstage/plugin-techdocs-module-addons-contrib               0.0.0-use.local
  @backstage/plugin-techdocs-node                                0.0.0-use.local
  @backstage/plugin-techdocs-react                               0.0.0-use.local
  @backstage/plugin-techdocs                                     0.0.0-use.local
  @backstage/plugin-todo-backend                                 0.0.0-use.local
  @backstage/plugin-todo                                         0.0.0-use.local
  @backstage/plugin-user-settings-backend                        0.0.0-use.local
  @backstage/plugin-user-settings                                0.0.0-use.local
  @backstage/plugin-vault-backend                                0.0.0-use.local
  @backstage/plugin-vault                                        0.0.0-use.local
  @backstage/plugin-xcmetrics                                    0.0.0-use.local
  @backstage/release-manifests                                   0.0.0-use.local
  @backstage/repo-tools                                          0.0.0-use.local
  @backstage/test-utils                                          0.0.0-use.local
  @backstage/theme                                               0.0.0-use.local
  @backstage/types                                               0.0.0-use.local
  @backstage/version-bridge                                      0.0.0-use.local

👀 Have you spent some time to check if this bug has been raised before?

  • I checked and didn't find similar issue

🏢 Have you read the Code of Conduct?

Are you willing to submit PR?

Yes I am willing to submit a PR!

@jamieklassen jamieklassen added the bug Something isn't working label Jan 23, 2023
@benjdlambert benjdlambert added the area:kubernetes Related to the Kubernetes Project Area - not deploying Backstage with k8s. label Jan 26, 2023
@benjdlambert
Copy link
Member

@mclarke47 for visibility.

@github-actions
Copy link
Contributor

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale label Mar 27, 2023
@benjdlambert
Copy link
Member

@jamieklassen is this still something you're interested in?

@github-actions github-actions bot removed the stale label Mar 30, 2023
@RubenV-dev
Copy link
Contributor

RubenV-dev commented Apr 19, 2023

Personally i think tackling the much larger acceptance of ambiguisly-named clusters might be the right thing to address here but I took a look at the proxy endpoint and if all we are looking to do is to ensure that the proxy is tackling the right cluster for the case where we have multiple clusters that share the same name, we could also make it so we not only find()using the clusterName but also using the already available cluster url in the clusterDetails. Will take a look to see if this approach is one that can resolve this bug. It might be the case that the url isn't a unique identifier but that doesn't appear to be a likely case to me.

it also appears like that would expect our request to include a cluster server url which doesn't seem to be very user freindly.

@github-actions
Copy link
Contributor

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:kubernetes Related to the Kubernetes Project Area - not deploying Backstage with k8s. bug Something isn't working will-fix We will fix this at some point
Projects
None yet
Development

No branches or pull requests

4 participants