-
Notifications
You must be signed in to change notification settings - Fork 710
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
Fix dashboard + proxy incompatibility #441
Conversation
This fantastic thanks for doing this. |
@@ -61,7 +61,7 @@ func CreateHTTPAPIHandler(client client.ClientManager) (http.Handler, error) { | |||
|
|||
apiV1Ws := new(restful.WebService) | |||
|
|||
apiV1Ws.Path("/api"). | |||
apiV1Ws.Path("/tfjobs/api"). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you capture the relevant details from the PR description in a comment here or wherever it makes sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
So the biggest issue was figuring out which part of the url corresponded to the application itself, and which parts were related to the proxying.
If we have this url with kubectl proxy + ambassador:
127.0.0.1:8001/api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/ui/
Proxy parts are:
127.0.0.1:8001/api/v1/namespaces/kubeflow/services/ambassador:80/proxy
Application parts are (depending on how the rewrite is configured in ambassador):
/tfjobs/ui/
So the way the application handles it, is finding the first occurence of tfjobs
in the url and appending /api/
to reach the backend.
Finally, by rewriting in ambassador to /tfjobs/
and not /
and by having the backend listening on /tfjobs/ui
and /tfjobs/api
we ensure that the logic won't break when not using ambassador, i.e:
- When using a dev server:
127.0.0.1:3000/tfjobs/ui
- When proxying directly on the dashboard service:
http://127.0.0.1:8001/api/v1/namespaces/kubeflow/services/tf-job-dashboard:80/proxy/tfjobs/ui/#/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this a comment in the code.
dashboard/frontend/package.json
Outdated
@@ -2,6 +2,7 @@ | |||
"name": "tensorflowk8s-dashboard", | |||
"version": "0.1.0", | |||
"description": "Dashboard for kubeflow/tf-operator.", | |||
"homepage": ".", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Homepage defines where the frontend will query for the static assets. If not specified the static assets will be queried at the root, i.e: 127.0.0.1:8001/static
which breaks.
"."
means that we query at the path where the application is served. i.e: http://127.0.0.1:8001/api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/ui/static
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this a comment in the code.
@@ -2,7 +2,7 @@ import React from "react"; | |||
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider"; | |||
import getMuiTheme from "material-ui/styles/getMuiTheme"; | |||
import FlatButton from "material-ui/FlatButton"; | |||
import { BrowserRouter as Router, Link } from "react-router-dom"; | |||
import { HashRouter as Router, Link } from "react-router-dom"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BrowserRouter is a traditional router, If I currently am at the root /
and I navigate to /new
, the resulting route will be: ${baseroute}/new
. However this breaks with ambassador:
If I am at /api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/ui/
and I navigate to /new
I still end up on /new
.
And we also can't just figure out the proxy part of the url and preprend it to each link, such as: /api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/ui/new
since the go backend is configured to only handle /tfjobs/ui
not /api/v1/....
.
So instead we can use the HashRouter
, which will only use the part of the url located after a #
to infer it's current state.
So /api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/ui/#
will become /api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/ui/#/new
. This works regardless of how the dashboard is accessed. This is also how the k8s dashboard works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this a comment in the code.
@jimexist Any chance you can review this? |
Looks good except please make the explanation comments in the code. It might be useful to capture guidance in our developer guide on how to write react APPs so that they work correctly with Ambassador. |
@jlewi Added the comments in the code. |
looks good to me but feeling sad that ambassador couldn't have fixed all this and an application has to adapt and use a different frontent router (I am thinking why not using a subdomain, e.g.) |
/retest |
Thanks. Looks good but looks like there was a problem running the tests. I retriggered them. /assign jlewi |
@jlewi Tests are fixed, had to pull master. |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jlewi The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
* dashboard: dev guide * fix dashboard + proxy issue * dashboard: move to hash router * [dashboard] Add comments about routes and proxying
Fixes #323 .
The frontend is now using
hashRouter
instead ofbrowserRouter
, meaning the location of the UI is determined only by the portion of the url after the#
(similar to k8s dashboard).Request to the backend are also properly routed now.
The backend request are sent to the portion of the url until the first occurence of
tfjobs
+/api
i.e:
http://127.0.0.1:8001/api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/ui/#/new
will translate into:
http://127.0.0.1:8001/api/v1/namespaces/kubeflow/services/ambassador:80/proxy/tfjobs/api
This means this would break if we decide to route the dashboard with ambassador on
/dashboard
instead of/tfjob
, so the route should be part of a dashboard config at some point.See kubeflow/kubeflow#381 for the related route change in ambassador.
cc @jlewi @jimexist
This change is