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

CONSOLE-2425: Support localization of dynamic plugins #9196

Merged
merged 1 commit into from Jul 23, 2021

Conversation

jhadvig
Copy link
Member

@jhadvig jhadvig commented Jun 9, 2021

Implementing additional endpoint for handling locales. The endpoint has following format:
api/locales/<language>/<plugin-locale-file>
eg. api/locales/en/olm.json

When the request hits the endpoint:

  1. it will parse out language and plugin's locale file
  2. then it will compare the plugin name against the list of enabled plugins
  3. if it matches any of the enabled plugins, it will redirect to its service
  4. if it doesn't match any of the enabled plugins, use redirect to loadPath, which is set to static/locales/{{lng}}/{{ns}}.json

Hopefully I understood the desired logic correctly.
@spadgett shall I also update the i18n enhancement ?

PTAL

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 9, 2021
@openshift-ci openshift-ci bot added the component/backend Related to backend label Jun 9, 2021
Copy link
Member

@spadgett spadgett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @jhadvig. We'll want to update the frontend code as well to use the new endpoint.

@@ -55,6 +55,7 @@ const (
devfileEndpoint = "/api/devfile/"
devfileSamplesEndpoint = "/api/devfile/samples/"
pluginsEndpoint = "/api/plugins/"
localesEndpoint = "api/locales/"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't put this under /api because this request doesn't require auth. Any request under the /api path will have the user's session cookie.


// parseLangAndPluginName will parse the language and plugin locale file
func parseLangAndPluginLocaleFile(urlPath string) (string, string, error) {
langAndPluginLocaleFile := strings.SplitN(urlPath, "/", 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we were using something like https://github.com/gorilla/mux to handle variables in the path, although that seems like overkill for one endpoint.

I'd suggest simply using query parameters lng and ns to avoid having to parse the path. We might eventually support multi-loading, and the query parameters would fit better with that (although that could be difficult if we need to proxy some requests).

https://github.com/i18next/i18next-http-backend#backend-options

klog.Errorf(redirectTo)
}

resp, err := p.Client.Get(redirectTo)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this actually making an HTTP request for static files? Can we serve static files directly instead using http.ServeFile?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should

@openshift-ci openshift-ci bot added the component/core Related to console core functionality label Jun 16, 2021
// In case of the dynamic plugin the localization namespace should contain name of the plugin prefixed with 'plugin:' prefix
// No file extension is needed since for the dynamic plugins we will fetch 'default.json' from the plugin pod.
// eg. 'plugin:helm-plugin'
pluginLocale := query.Get("ns")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a locale. I'd stick to namespace as the variable name.

Comment on lines 43 to 45
// In case of the dynamic plugin the localization namespace should contain name of the plugin prefixed with 'plugin:' prefix
// No file extension is needed since for the dynamic plugins we will fetch 'default.json' from the plugin pod.
// eg. 'plugin:helm-plugin'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you open a PR to update the dynamic plugin enhancement with this proposal? Then we can get agreement from stakeholders.

cc @christianvogt @vojtechszocs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
// in case of dynamic-plugin we need to trim the "plugin:" prefix.
pluginName := strings.TrimPrefix(pluginLocale, "plugin:")
http.Redirect(w, r, path.Join(r.Host, "api/plugins", pluginName, "locales", lang, "default.json"), http.StatusSeeOther)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should confirm that i18next-http-backend handles redirects. It might be better just to proxy the content here if it's not too hard.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, proxying makes more sense ... updated

@jhadvig
Copy link
Member Author

jhadvig commented Jun 28, 2021

@spadgett comments addressed.

@jhadvig jhadvig changed the title [WIP] CONSOLE-2425: Support localization of dynamic plugins CONSOLE-2425: Support localization of dynamic plugins Jun 28, 2021
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 28, 2021
@jhadvig
Copy link
Member Author

jhadvig commented Jul 1, 2021

@spadgett updated the PR per updates in the enhancement

@jhadvig
Copy link
Member Author

jhadvig commented Jul 1, 2021

/test e2e-gcp-console

@jhadvig jhadvig force-pushed the CONSOLE-2425 branch 3 times, most recently from 60fbab5 to b38a92b Compare July 1, 2021 15:45
@jhadvig
Copy link
Member Author

jhadvig commented Jul 1, 2021

@spadgett I've addted locales to the dynamic-demo-plugin and updated the two Dockerfiles we have for it.

@spadgett
Copy link
Member

spadgett commented Jul 1, 2021

@vojtechszocs @christianvogt FYI

pkg/plugins/handlers.go Outdated Show resolved Hide resolved
pkg/plugins/handlers.go Outdated Show resolved Hide resolved
pkg/plugins/handlers.go Outdated Show resolved Hide resolved
Comment on lines 51 to 56
// in case of dynamic-plugin we need to trim the "plugin__" prefix.
pluginName := strings.TrimPrefix(namespace, "plugin__")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally wouldn't trim the prefix here. I'd make the the filename match the actual namespace used like plugin__kubevirt.json since that's how i18next normally works.

Either way, we should make that more clear in the enhancement proposal with a specific example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the plus side, this would prevent e.g. plugin__kubevirt-plugin.json file names 😃

Having i18n namespace match the file name sounds pretty straight-forward, sounds OK to me.

Copy link
Member Author

@jhadvig jhadvig Jul 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spadgett I trim the plugin__ prefix to get the plugin service endpoint from the map of all the active plugins, where we are mapping the plugin name to its service endpoint. Based on the conversation I dont think ConsolePlugin resource name will contain the prefix, thats why Im trimming it to get the real name.

pkg/plugins/handlers.go Outdated Show resolved Hide resolved
@@ -0,0 +1,3 @@
{
"Subject": "Subject"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used anywhere in the demo plugin?

I would only add the JSON files if we're actually using it somewhere in the demo plugin to give a real example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no its not, in that case I can just put there and empty json

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have a follow-up PR that illustrates localization usage in dynamic demo plugin.

  • localizing strings in console-extensions.json
  • localizing strings in a plain function
  • localizing strings in a React component

Once this PR is merged and the conventions are settled, I can write that PR.

@openshift-ci openshift-ci bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 16, 2021
@openshift-ci openshift-ci bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 16, 2021
@jhadvig
Copy link
Member Author

jhadvig commented Jul 16, 2021

@spadgett @vojtechszocs I've rebased the PR and addressed comments. Also remove the i18n changes in the dynamic plugin since we will address those as follow up

PTAL

@spadgett
Copy link
Member

Test failure looks like it might be related.

Error: Failed: Missing i18n key "YAML" in namespace "public" and language "en."

@spadgett
Copy link
Member

Looking deeper, I see the files are failing to load.

[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=ceph-storage-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=console-shared - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=devconsole - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=container-security - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=console-app - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=git-service - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=gitops-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=helm-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=insights-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=kubevirt-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=knative-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=lso-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=metal3-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=notification-drawer - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=olm - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=public - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=pipelines-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=rhoas-plugin - Failed to load resource: the server responded with a status of 404 (Not Found)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/locales/resource.json?lng=en&ns=topology - Failed to load resource: the server responded with a status of 404 (Not Found)

@jhadvig
Copy link
Member Author

jhadvig commented Jul 16, 2021

Hmm wondering if thats related to the PR since there are also other errors

[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/api/console/knative-event-sources - Failed to load resource: the server responded with a status of 401 (Unauthorized)
[WARNING] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/static/main-chunk-ab5505283ddc025dfa57.min.js 0:380641 "Error fetching CRDs for dynamic event sources" Error: Unauthorized
    at https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/static/main-chunk-ab5505283ddc025dfa57.min.js:1:123823
    at Generator.next (<anonymous>)
    at https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/static/main-chunk-ab5505283ddc025dfa57.min.js:1:123209
    at new Promise (<anonymous>)
    at s (https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/static/main-chunk-ab5505283ddc025dfa57.min.js:1:122957)
    at u (https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/static/main-chunk-ab5505283ddc025dfa57.min.js:1:123309)
    at https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/static/main-chunk-ab5505283ddc025dfa57.min.js:1:124936
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/api/console/knative-channels - Failed to load resource: the server responded with a status of 401 (Unauthorized)
[SEVERE] https://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/static/vendors~main-chunk-d7eaff6a7eb98f5b246e.min.js 87 WebSocket connection to 'wss://console-openshift-console.apps.ci-op-cnxvm8dw-75d12.**********************/api/graphql' failed: HTTP Authentication failed; no valid credentials available

@spadgett
Copy link
Member

@jhadvig Those are expected on initial console load since you're not logged in yet.

@jhadvig
Copy link
Member Author

jhadvig commented Jul 22, 2021

/test e2e-gcp-console

}
}

func (p *PluginsHandler) HandlePlugins(w http.ResponseWriter, r *http.Request) {
func (p *PluginsHandler) HandleLocales(w http.ResponseWriter, r *http.Request) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are resources, not locales.

Suggested change
func (p *PluginsHandler) HandleLocales(w http.ResponseWriter, r *http.Request) {
func (p *PluginsHandler) HandleI18nResources(w http.ResponseWriter, r *http.Request) {

Comment on lines 40 to 45
// In case of console app or static plugins, the localization namespace should contain name of the json file that contains the localized strings,
// since various console packages have different names for the localization file.
// eg. namespace query for the local-storage-operator-plugin locales - '&ns=lso-plugin'
// In case of the dynamic plugin the localization namespace should contain name of the plugin prefixed with 'plugin__' prefix.
// No file extension is needed since for the dynamic plugins we will fetch file from the plugin pod, based on the namespace.
// eg. 'plugin__helm' will fetch `/locales/{lang}/plugin__helm.json`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the important bit, so I'd trim the comment to just this:

Suggested change
// In case of console app or static plugins, the localization namespace should contain name of the json file that contains the localized strings,
// since various console packages have different names for the localization file.
// eg. namespace query for the local-storage-operator-plugin locales - '&ns=lso-plugin'
// In case of the dynamic plugin the localization namespace should contain name of the plugin prefixed with 'plugin__' prefix.
// No file extension is needed since for the dynamic plugins we will fetch file from the plugin pod, based on the namespace.
// eg. 'plugin__helm' will fetch `/locales/{lang}/plugin__helm.json`
// In case of the dynamic plugins, the namespace should contain name of the plugin prefixed with 'plugin__' prefix.
// eg. 'plugin__helm' will fetch `locales/{lang}/plugin__helm.json` from the plugin service

pkg/plugins/handlers.go Show resolved Hide resolved
Copy link
Member

@spadgett spadgett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
/hold for approvals
/assign @yapei @ahardin-rh @sferich888

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 22, 2021
@spadgett spadgett added this to the v4.9 milestone Jul 22, 2021
@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Jul 22, 2021
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jul 22, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jhadvig, spadgett

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 22, 2021
@ahardin-rh
Copy link

/label docs-approved

@openshift-ci openshift-ci bot added the docs-approved Signifies that Docs has signed off on this PR label Jul 22, 2021
@sferich888
Copy link

/label px-approved
/unassign @sferich888

@openshift-ci openshift-ci bot added the px-approved Signifies that Product Support has signed off on this PR label Jul 22, 2021
@yapei
Copy link
Contributor

yapei commented Jul 23, 2021

tested the changes and it is working well
/label qe-approved

@openshift-ci openshift-ci bot added the qe-approved Signifies that QE has signed off on this PR label Jul 23, 2021
@jhadvig
Copy link
Member Author

jhadvig commented Jul 23, 2021

/hold cancel

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 23, 2021
@openshift-merge-robot openshift-merge-robot merged commit 0871fcf into openshift:master Jul 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. component/backend Related to backend component/core Related to console core functionality docs-approved Signifies that Docs has signed off on this PR lgtm Indicates that a PR is ready to be merged. px-approved Signifies that Product Support has signed off on this PR qe-approved Signifies that QE has signed off on this PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants