diff --git a/.claude/commands/run-perses-dev.md b/.claude/commands/run-perses-dev.md index a538773b7..beb5d184e 100644 --- a/.claude/commands/run-perses-dev.md +++ b/.claude/commands/run-perses-dev.md @@ -22,11 +22,11 @@ Then go clockwise and split horitzontally. - Pane 2 - Path: monitoring-plugin (root of this repo) - Label: monitoring-console-plugin-console - - Run: make start-feature-console + - Run: make start-console - Pane 4 - Path: monitoring-plugin (root of this repo) - Label: monitoring-console-plugin-backend - - Run: make start-feature-backend + - Run: make start-coo-backend - Pane 6 - Path: monitoring-plugin (root of this repo) - Label: port-forward-promtheus-operator @@ -45,6 +45,4 @@ Then go clockwise and split horitzontally. - In bold output, tell the user the name of the session and tmux session tips like how to attach to sessions, how to move around the panels using prefix + arrows, how to delete a session, how to list session - Navigate to `{perses_path}/dev/config.yaml`. The spec `security.enable_auth` should be `false`. - Tell user that openshift console platform is located at http://localhost:9000 -- Tell user that perses is located at http://localhost:3000 - - +- Tell user that perses is located at http://localhost:3000 diff --git a/AGENTS.md b/AGENTS.md index f1298f843..84f07b04f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,14 +5,14 @@ - **What**: Dual frontend plugins for OpenShift observability (monitoring-plugin + monitoring-console-plugin) - **Purpose**: Alerts, Metrics, Targets, Dashboards + Perses, Incidents, ACM integration - **Tech Stack**: React + TypeScript + Webpack + i18next + Go -- **Key Files**: `web/console-extensions.json`, `web/src/components/` +- **Key Files**: `config/*.patch.json`, `web/src/components/` ## Common Tasks & Workflows ### Adding a New Feature 1. Check if it belongs in `monitoring-plugin` (core) or `monitoring-console-plugin` (extended) -2. Update console extensions in `web/console-extensions.json` +2. Add or update the relevant patch file in `config/` (e.g. `config/alerting.patch.json`) 3. Add React components in `web/src/components/` 4. Add translations in `public/locales/` 5. Test with `make lint-frontend && make test-backend` @@ -20,7 +20,7 @@ ### Debugging Issues - **Build failures**: Check `Makefile` targets -- **Console integration**: Verify `console-extensions.json` +- **Console integration**: Verify the relevant `config/*.patch.json` patch file - **Plugin loading**: Check OpenShift Console logs - **Perses dashboards**: Debug at `web/src/components/dashboards/perses/` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f74d2cf23..961adff7c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -547,11 +547,11 @@ grep "^\.PHONY" Makefile | sed 's/.PHONY: //' #### Port conflicts -If ports 9001 or 3000 are in use: +If ports 9443 or 3000 are in use: ```bash # Find and kill processes -lsof -ti:9001 | xargs kill -9 # Backend +lsof -ti:9443 | xargs kill -9 # Backend lsof -ti:3000 | xargs kill -9 # Frontend ``` diff --git a/Dockerfile.mcp b/Dockerfile.mcp index 12781d92d..343b18b44 100644 --- a/Dockerfile.mcp +++ b/Dockerfile.mcp @@ -48,4 +48,4 @@ COPY --from=web-builder /opt/app-root/web/dist /opt/app-root/web/dist COPY --from=go-builder /opt/app-root/plugin-backend /opt/app-root COPY --from=web-builder /opt/app-root/config /opt/app-root/config -ENTRYPOINT ["/opt/app-root/plugin-backend", "-static-path", "/opt/app-root/web/dist"] +ENTRYPOINT ["/opt/app-root/plugin-backend", "-static-path", "/opt/app-root/web/dist", "-config-path", "/opt/app-root/config"] diff --git a/Makefile b/Makefile index d9a06aac6..088f2abc1 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ PLATFORMS ?= linux/arm64,linux/amd64 ORG ?= openshift-observability-ui PLUGIN_NAME ?=monitoring-plugin IMAGE ?= quay.io/${ORG}/${PLUGIN_NAME}:${VERSION} -FEATURES ?=incidents,perses-dashboards,dev-config +MONITORING_FEATURES ?=alerting,targets,legacy-dashboards,metrics +ALL_FEATURES ?=$(MONITORING_FEATURES),incidents,perses-dashboards GOLANGCI_LINT = $(shell pwd)/_output/tools/bin/golangci-lint GOLANGCI_LINT_VERSION ?= v2.11.3 @@ -52,7 +53,11 @@ build-backend: .PHONY: start-backend start-backend: - go run ./cmd/plugin-backend.go -port='9001' -config-path='./config' -static-path='./web/dist' + go run ./cmd/plugin-backend.go -port='9443' -config-path='./config' -static-path='./web/dist' -features='${MONITORING_FEATURES}' + +.PHONY: start-coo-backend +start-coo-backend: + go run ./cmd/plugin-backend.go -port='9443' -config-path='./config' -static-path='./web/dist' -features='${ALL_FEATURES}' .PHONY: test-backend test-backend: @@ -107,17 +112,9 @@ build-mcp-image: build-dev-mcp-image: DOCKER_FILE_NAME="Dockerfile.dev-mcp" REPO="monitoring-console-plugin" scripts/build-image.sh -.PHONY: start-feature-console -start-feature-console: - PLUGIN_PORT=9443 ./scripts/start-console.sh - -.PHONY: start-feature-backend -start-feature-backend: - go run ./cmd/plugin-backend.go -port='9443' -config-path='./config' -static-path='./web/dist' -features='${FEATURES}' - .PHONY: start-devspace-backend start-devspace-backend: - /opt/app-root/plugin-backend -port='9443' -cert='/var/cert/tls.crt' -key='/var/cert/tls.key' -static-path='/opt/app-root/web/dist' -config-path='/opt/app-root/config' -features='${FEATURES}' + /opt/app-root/plugin-backend -port='9443' -cert='/var/cert/tls.crt' -key='/var/cert/tls.key' -static-path='/opt/app-root/web/dist' -config-path='/opt/app-root/config' -features='${ALL_FEATURES}' .PHONY: podman-cross-build podman-cross-build: diff --git a/README.md b/README.md index a62fb2a58..4281c17ff 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,21 @@ # OpenShift Monitoring Plugin -This plugin runs in one of two modes, with and without feature flags. When deployed without any feature flags enabled, it will add the monitoring UI to the OpenShift web console. This is most commonly seen in the [CMO](https://github.com/openshift/cluster-monitoring-operator) deployment of it, which is shipped by default with every OpenShift cluster. Documentation for this mode is located under the [monitoring-plugin](#monitoring-plugin) heading. +This plugin enables frontend UI based on feature flags passed to the backend. These features are generally grouped under two sets, those deployed by the [Cluster Monitoring Operator](https://github.com/openshift/cluster-monitoring-operator) (alerting, dashboards, metrics and targets) and those deployed by the [Cluster Observability Operator](https://github.com/rhobs/observability-operator) (ACM Alerting, Perses Dashboards, Incidents). CMO is included and enabled by default on most installations of OpenShift so observability signals needed for these features are expected to be present in any cluster, while the COO features utilize optional observability signals which are installed through COO. Information on running the plugin as it if were deployed through CMO can be found under the [monitoring-plugin](#monitoring-plugin) heading and the other set can be found under the [monitoring-console-plugin](#monitoring-console-plugin) heading. + +## Feature Flags + +Feature flags should be added to the Feature enum [here](pkg/server.go) and to the useFeature hook [here](web/src/components/hooks/useFeatures.ts). Whenever a feature is enabled, a set of related feature extension points is included in the plugin-manifest.json served by the backend. These feature extension points are created through the use of [json-patches](https://datatracker.ietf.org/doc/html/rfc6902), such as the `acm-alerting` patch [here](config/acm-alerting.patch.json). The server looks for a patch in the format of `{feature-flag-name}.patch.json` to apply. Some feature flags, such as `acm-alerting` require other flags to be set such as `alertmanager` and `thanos-querier` to instruct the backend how to communicate with the observability signals they utilize + +| Feature | OCP Version | +|-------------------|-------------| +| acm-alerting | 4.14+ | +| perses-dashboards | 4.14+ | +| incidents | 4.17+ | +| alerting | 5.0+ | +| legacy-dashboards | 5.0+ | +| metrics | 5.0+ | +| targets | 5.0+ | -When started with feature flag(s), it will instead only add functionality to the OpenShift web console related to the features. Documentation for this mode is located under the [monitoring-console-plugin](#monitoring-console-plugin) heading. ## monitoring-plugin @@ -30,7 +43,7 @@ Before you can deploy the plugin on a cluster, you must build an image and push docker push quay.io/my-repository/my-plugin:latest ``` -NOTE: If you have a Mac with Apple silicon, you will need to add the flag `--platform=linux/amd64` when building the image to target the correct platform to run in-cluster. +NOTE: If you have a Mac with Apple silicon, you will need to add the flag `--platform=linux/amd64` when building the image to target the correct platform to run in-cluster. We recommend utilizing the `make build-image` action to build and push the image. ### Deployment on cluster @@ -50,18 +63,12 @@ Install the chart into a new namespace or an existing namespace as specified by helm upgrade -i monitoring-plugin charts/openshift-console-plugin -n my-plugin-namespace --create-namespace --set plugin.image=my-plugin-image-location ``` -### Redux Store - -The monitoring-plugin is currently in a transitionary state as the remaining pages are moved from the [openshift/console](https://github.com/openshift/console) repo to this one. One such instance of this is the redux store [definition](https://github.com/openshift/console/blob/master/frontend/public/reducers/observe.ts), which lives within the `openshift/console` codebase. - -Changes to the store must be completed in the `openshift/console` codebase and are not backwards compatible unless cherry-picked with purpose. - ### Running using Devspace Install the [devspace](https://www.devspace.sh/docs/getting-started/installation) cli. 1. Install the frontend dependencies running `make install-frontend`. -2. Start the frontend `make start-feature-frontend`. +2. Start the frontend `make start-frontend`. 4. Select the namespace the monitoring-plugin is located in `devspace use namespace openshift-monitoring`. 5. In a different terminal start the devspace sync `devspace dev`. @@ -69,6 +76,8 @@ When running the `devspace dev` command, the pipeline will run the `scale_down_c After the pod has been "taken over" Devspace begins a sync process which will mirror changes from you local `./web/dist` folder into the `/opt/app-root/web/dist` folder in the devspace pod. You can then make changes to your frontend files locally which will trigger the locally running webpack dev server to rebuild the `./web/dist` folder, which will trigger Devspace to re-synced. You can then reload your console webpage to see your local changes running in the cluster. +The devspace command will enable all features from a single deployment for easy development, however it does not install other needed observability signals, which will need to be created through COO. + After development you can run `devspace purge` which will cleanup and then call the `scale_up_cmo` pipeline. ### Local Development @@ -93,9 +102,12 @@ $ podman machine start # Install dependencies $ make install -# Run the application +# Run the frontend $ make start-frontend # In a separate terminal +# Run the backend +$ make start-backend +# In a separate terminal $ make start-console ``` @@ -121,17 +133,6 @@ Images for the mcp can be built by running the following command. Due to the lim make build-dev-mcp-image ``` -### Feature Flags - -Feature flags are used by the mcp mode to dictate the specific features which are enabled when the server starts up. Feature flags should be added to the Feature enum [here](pkg/server.go) and to the useFeature hook [here](web/src/components/hooks/useFeatures.ts). When any feature flag is enabled the default extension points are overridden, including a new monitoring-console-plugin exclusive redux store and all extension points for the flags. These feature extension points are created through the use of [json-patches](https://datatracker.ietf.org/doc/html/rfc6902), such as the `acm-alerting` patch [here](config/acm-alerting.patch.json). The server looks for a patch in the format of `{feature-flag-name}.patch.json` to apply. - -| Feature | OCP Version | -|-------------------|-------------| -| acm-alerting | 4.14+ | -| perses-dashboards | 4.14+ | -| incidents | 4.17+ | -| dev-config | | - #### ACM Due to the extensive number of items which would need to be run to locally run the ACM perspective, the suggested development pattern is instead repeat installations with helm. A small number of scripts have been put together to help you deploy the monitoring-plugin in its `acm-alerting` configuration. REGISTRY_ORG and TAG variables are available to adjust the quay image generated and used for deployment. Certain build time changes to the codebase are created when running these scripts. @@ -163,13 +164,13 @@ $ make install $ make start-frontend # In a separate terminal -$ make start-feature-console +$ make start-console # In a separate terminal -$ make start-feature-backend +$ make start-coo-backend ``` -`make start-feature-backend` will inject the `perses-dashboards`, `incidents`, and `dev-config` features by default. Features such as `acm-alerting` which take in extra parameters will need to run the `make start-feature-backend` command with the appropriate environment variables, such as `MONITORING_PLUGIN_ALERTMANAGER`. +`make start-coo-backend` will inject the `alerting,targets,legacy-dashboards,metrics,incidents,perses-dashboards` features. #### Local Development with Perses Proxy The bridge script `start-console.sh` is configured to proxy to a local Perses instance running at port `:8080`. To run the local Perses instance you will need to clone the [perses/perses](https://github.com/perses/perses) repository and follow the start up instructions in [ui/README.md](https://github.com/perses/perses/blob/63601751674403f626d1dea3dec168bdad0ef1c7/ui/README.md) : diff --git a/cmd/plugin-backend.go b/cmd/plugin-backend.go index 71c38e024..66f7cf036 100644 --- a/cmd/plugin-backend.go +++ b/cmd/plugin-backend.go @@ -17,7 +17,7 @@ var ( portArg = flag.Int("port", 9443, "server port to listen on\nports 9444 and 9445 reserved for other use") certArg = flag.String("cert", "", "cert file path to enable TLS (disabled by default)") keyArg = flag.String("key", "", "private key file path to enable TLS (disabled by default)") - featuresArg = flag.String("features", "", "enabled features, comma separated.\noptions: ['acm-alerting', 'incidents', 'dev-config', 'perses-dashboards']") + featuresArg = flag.String("features", "", "enabled features, comma separated.\noptions: ['acm-alerting', 'alerting', 'incidents', 'legacy-dashboards', 'metrics', 'targets', 'perses-dashboards', 'cluster-health-analyzer']") staticPathArg = flag.String("static-path", "/opt/app-root/web/dist", "static files path to serve frontend") configPathArg = flag.String("config-path", "/opt/app-root/config", "config files path") pluginConfigArg = flag.String("plugin-config-path", "/etc/plugin/config.yaml", "plugin yaml configuration") diff --git a/config/acm-alerting.patch.json b/config/acm-alerting.patch.json index 81891116d..aa1392278 100644 --- a/config/acm-alerting.patch.json +++ b/config/acm-alerting.patch.json @@ -1,7 +1,7 @@ [ { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.navigation/section", "properties": { @@ -14,7 +14,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -28,7 +28,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -40,7 +40,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -52,7 +52,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -66,7 +66,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -80,7 +80,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -92,7 +92,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.navigation/href", "properties": { diff --git a/config/alerting.patch.json b/config/alerting.patch.json new file mode 100644 index 000000000..00a972698 --- /dev/null +++ b/config/alerting.patch.json @@ -0,0 +1,323 @@ +[ + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "alerting", + "name": "%plugin__monitoring-plugin~Alerting%", + "href": "/monitoring/alerts", + "perspective": "admin", + "section": "observe", + "startsWith": [ + "monitoring/alertrules", + "monitoring/silences", + "monitoring/incidents" + ] + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "alerting-virt", + "name": "%plugin__monitoring-plugin~Alerting%", + "href": "/virt-monitoring/alerts", + "perspective": "virtualization-perspective", + "section": "observe-virt-perspective", + "startsWith": [ + "virt-monitoring/alertrules", + "virt-monitoring/silences", + "virt-monitoring/incidents" + ] + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/monitoring", + "component": { + "$codeRef": "AlertingPage.MpCmoAlertingPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/monitoring/silences/~new", + "component": { + "$codeRef": "SilenceCreatePage.MpCmoCreateSilencePage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/monitoring/silences/:id", + "component": { + "$codeRef": "SilencesDetailsPage.MpCmoSilencesDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/monitoring/silences/:id/edit", + "component": { + "$codeRef": "SilenceEditPage.MpCmoSilenceEditPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/monitoring/alertrules/:id"], + "component": { + "$codeRef": "AlertRulesDetailsPage.MpCmoAlertRulesDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/monitoring/alerts/:ruleID"], + "component": { + "$codeRef": "AlertsDetailsPage.MpCmoAlertsDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/virt-monitoring"], + "component": { + "$codeRef": "AlertingPage.MpCmoAlertingPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/virt-monitoring/silences/~new", + "component": { + "$codeRef": "SilenceCreatePage.MpCmoCreateSilencePage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/virt-monitoring/silences/:id", + "component": { + "$codeRef": "SilencesDetailsPage.MpCmoSilencesDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/virt-monitoring/silences/:id/edit", + "component": { + "$codeRef": "SilenceEditPage.MpCmoSilenceEditPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/virt-monitoring/alertrules/:id"], + "component": { + "$codeRef": "AlertRulesDetailsPage.MpCmoAlertRulesDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/virt-monitoring/alerts/:ruleID"], + "component": { + "$codeRef": "AlertsDetailsPage.MpCmoAlertsDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/dev-monitoring/ns/:ns/alerts/:ruleID", + "component": { + "$codeRef": "AlertsDetailsPage.MpCmoAlertsDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/dev-monitoring/ns/:ns/rules/:id", + "component": { + "$codeRef": "AlertRulesDetailsPage.MpCmoAlertRulesDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/dev-monitoring/ns/:ns/silences/:id", + "component": { + "$codeRef": "SilencesDetailsPage.MpCmoSilencesDetailsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/dev-monitoring/ns/:ns/silences/:id/edit", + "component": { + "$codeRef": "SilenceEditPage.MpCmoSilenceEditPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": "/dev-monitoring/ns/:ns/silences/~new", + "component": { + "$codeRef": "SilenceCreatePage.MpCmoCreateSilencePage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.tab", + "properties": { + "contextId": "dev-console-observe", + "name": "%plugin__monitoring-plugin~Silences%", + "href": "silences", + "component": { + "$codeRef": "SilencesPage.MpCmoSilencesPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.tab", + "properties": { + "contextId": "dev-console-observe", + "name": "%plugin__monitoring-plugin~Alerts%", + "href": "alerts", + "component": { + "$codeRef": "AlertsPage.MpCmoAlertsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.tab", + "properties": { + "contextId": "dev-console-observe", + "name": "%plugin__monitoring-plugin~Alerting rules%", + "href": "alertrules", + "component": { + "$codeRef": "AlertRulesPage.MpCmoAlertRulesPage" + } + } + } + } +] diff --git a/config/clear-extensions.patch.json b/config/clear-extensions.patch.json deleted file mode 100644 index 32f2341d4..000000000 --- a/config/clear-extensions.patch.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "op": "replace", - "path": "/extensions", - "value": [ - { - "type": "console.redux-reducer", - "properties": { - "scope": "mcp", - "reducer": { "$codeRef": "MonitoringReducer" } - } - } - ] - } -] diff --git a/config/cluster-health-analyzer.patch.json b/config/cluster-health-analyzer.patch.json index fcb338fcd..0b475df6a 100644 --- a/config/cluster-health-analyzer.patch.json +++ b/config/cluster-health-analyzer.patch.json @@ -1,7 +1,7 @@ [ { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.tab", "properties": { diff --git a/config/legacy-dashboards.patch.json b/config/legacy-dashboards.patch.json new file mode 100644 index 000000000..597e6359d --- /dev/null +++ b/config/legacy-dashboards.patch.json @@ -0,0 +1,81 @@ +[ + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "dashboards", + "name": "%plugin__monitoring-plugin~Dashboards%", + "href": "/monitoring/dashboards", + "perspective": "admin", + "section": "observe", + "insertAfter": "metrics" + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "dashboards-virt", + "name": "%plugin__monitoring-plugin~Dashboards%", + "href": "/virt-monitoring/dashboards", + "perspective": "virtualization-perspective", + "section": "observe-virt-perspective", + "insertAfter": "metrics-virt" + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": [ + "/monitoring/dashboards", + "/monitoring/dashboards/:dashboardName" + ], + "component": { + "$codeRef": "LegacyDashboardsPage.MpCmoLegacyDashboardsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": [ + "/virt-monitoring/dashboards", + "/virt-monitoring/dashboards/:dashboardName" + ], + "component": { + "$codeRef": "LegacyDashboardsPage.MpCmoLegacyDashboardsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.tab", + "properties": { + "contextId": "dev-console-observe", + "name": "%plugin__monitoring-plugin~Dashboards%", + "href": "", + "component": { + "$codeRef": "LegacyDashboardsPage.MpCmoLegacyDevDashboardsPage" + } + } + } + } +] diff --git a/config/metrics.patch.json b/config/metrics.patch.json new file mode 100644 index 000000000..a6929b301 --- /dev/null +++ b/config/metrics.patch.json @@ -0,0 +1,103 @@ +[ + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "metrics", + "name": "%plugin__monitoring-plugin~Metrics%", + "href": "/monitoring/query-browser", + "perspective": "admin", + "section": "observe", + "insertAfter": "alerts" + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "metrics-virt", + "name": "%plugin__monitoring-plugin~Metrics%", + "href": "/virt-monitoring/query-browser", + "perspective": "virtualization-perspective", + "section": "observe-virt-perspective", + "insertAfter": "alerts" + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/monitoring/query-browser"], + "component": { + "$codeRef": "MetricsPage.MpCmoMetricsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/monitoring/graph"], + "component": { + "$codeRef": "PrometheusRedirectPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/virt-monitoring/query-browser"], + "component": { + "$codeRef": "MetricsPage.MpCmoMetricsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/virt-monitoring/graph"], + "component": { + "$codeRef": "PrometheusRedirectPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.tab", + "properties": { + "contextId": "dev-console-observe", + "name": "%plugin__monitoring-plugin~Metrics%", + "href": "metrics", + "component": { + "$codeRef": "MetricsPage.MpCmoDevMetricsPage" + } + } + } + } +] diff --git a/config/dev-config.patch.json b/config/monitoring-console-plugin.patch.json similarity index 100% rename from config/dev-config.patch.json rename to config/monitoring-console-plugin.patch.json diff --git a/config/monitoring-plugin.patch.json b/config/monitoring-plugin.patch.json new file mode 100644 index 000000000..7005e4a0e --- /dev/null +++ b/config/monitoring-plugin.patch.json @@ -0,0 +1,34 @@ +[ + { + "op": "add", + "path": "/extensions/0", + "value": { + "properties": { + "dataAttributes": { + "data-quickstart-id": "qs-nav-monitoring" + }, + "id": "observe-virt-perspective", + "insertBefore": [ + "compute-virt-perspective", + "usermanagement-virt-perspective" + ], + "name": "%console-app~Observe%", + "perspective": "virtualization-perspective" + }, + "type": "console.navigation/section" + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.redux-reducer", + "properties": { + "scope": "mp", + "reducer": { + "$codeRef": "MonitoringReducer" + } + } + } + } +] diff --git a/config/perses-dashboards.patch.json b/config/perses-dashboards.patch.json index 79d650595..e2d18b21a 100644 --- a/config/perses-dashboards.patch.json +++ b/config/perses-dashboards.patch.json @@ -1,7 +1,7 @@ [ { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -15,7 +15,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.navigation/href", "properties": { @@ -30,7 +30,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -42,7 +42,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.navigation/href", @@ -58,7 +58,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -70,7 +70,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.navigation/href", @@ -86,7 +86,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -98,7 +98,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -110,7 +110,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "console.page/route", "properties": { @@ -122,7 +122,7 @@ }, { "op": "add", - "path": "/extensions/1", + "path": "/extensions/0", "value": { "type": "ols.tool-ui", "properties": { diff --git a/config/targets.patch.json b/config/targets.patch.json new file mode 100644 index 000000000..784b827ec --- /dev/null +++ b/config/targets.patch.json @@ -0,0 +1,63 @@ +[ + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "targets", + "name": "%plugin__monitoring-plugin~Targets%", + "href": "/monitoring/targets", + "perspective": "admin", + "section": "observe", + "insertAfter": "dashboards" + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.navigation/href", + "properties": { + "id": "targets-virt", + "name": "%plugin__monitoring-plugin~Targets%", + "href": "/virt-monitoring/targets", + "perspective": "virtualization-perspective", + "section": "observe-virt-perspective", + "insertAfter": "dashboards-virt" + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": ["/monitoring/targets", "/monitoring/targets/:scrapeUrl"], + "component": { + "$codeRef": "TargetsPage.MpCmoTargetsPage" + } + } + } + }, + { + "op": "add", + "path": "/extensions/0", + "value": { + "type": "console.page/route", + "properties": { + "exact": false, + "path": [ + "/virt-monitoring/targets", + "/virt-monitoring/targets/:scrapeUrl" + ], + "component": { + "$codeRef": "TargetsPage.MpCmoTargetsPage" + } + } + } + } +] diff --git a/pkg/plugin_handler.go b/pkg/plugin_handler.go index 842bfa12b..51d4066c6 100644 --- a/pkg/plugin_handler.go +++ b/pkg/plugin_handler.go @@ -1,7 +1,6 @@ package server import ( - "fmt" "net/http" "os" "path/filepath" @@ -33,26 +32,27 @@ func manifestHandler(cfg *Config) http.HandlerFunc { } func patchManifest(baseManifestData []byte, cfg *Config) []byte { - if len(cfg.Features) == 0 { - return baseManifestData + features := cfg.Features + patches := []struct { + file string + enabled bool + }{ + {"monitoring-plugin.patch.json", features[Alerting] || features[LegacyDashboards] || features[Metrics] || features[Targets]}, + {"alerting.patch.json", features[Alerting]}, + {"metrics.patch.json", features[Metrics]}, + {"legacy-dashboards.patch.json", features[LegacyDashboards]}, + {"targets.patch.json", features[Targets]}, + {"monitoring-console-plugin.patch.json", features[Incidents] || features[ClusterHealthAnalyzer] || features[PersesDashboards] || features[AcmAlerting]}, + {"acm-alerting.patch.json", features[AcmAlerting]}, + {"cluster-health-analyzer.patch.json", features[Incidents] || features[ClusterHealthAnalyzer]}, + {"perses-dashboards.patch.json", features[PersesDashboards]}, } patchedManifest := baseManifestData - if !cfg.Features[DevConfig] { - // Don't clear the extensions when running in dev mode, so only 1 instance of the monitoring-plugin - // can be run as a development environment - patchedManifest = performPatch(baseManifestData, filepath.Join(cfg.ConfigPath, "clear-extensions.patch.json")) - } - - if cfg.Features[Incidents] || cfg.Features[ClusterHealthAnalyzer] { - patchedManifest = performPatch(patchedManifest, filepath.Join(cfg.ConfigPath, "cluster-health-analyzer.patch.json")) - } - - for feature := range cfg.Features { - if feature == ClusterHealthAnalyzer || feature == Incidents { - continue + for _, p := range patches { + if p.enabled { + patchedManifest = performPatch(patchedManifest, filepath.Join(cfg.ConfigPath, p.file)) } - patchedManifest = performPatch(patchedManifest, filepath.Join(cfg.ConfigPath, fmt.Sprintf("%s.patch.json", feature))) } return []byte(patchedManifest) diff --git a/pkg/server.go b/pkg/server.go index c3714b2c4..881b066b8 100644 --- a/pkg/server.go +++ b/pkg/server.go @@ -58,8 +58,11 @@ type Feature string const ( AcmAlerting Feature = "acm-alerting" + Alerting Feature = "alerting" Incidents Feature = "incidents" - DevConfig Feature = "dev-config" + LegacyDashboards Feature = "legacy-dashboards" + Metrics Feature = "metrics" + Targets Feature = "targets" PersesDashboards Feature = "perses-dashboards" ClusterHealthAnalyzer Feature = "cluster-health-analyzer" ) @@ -118,6 +121,14 @@ func createHTTPServer(ctx context.Context, cfg *Config) (*http.Server, error) { return nil, fmt.Errorf("cannot set default port to reserved port %d", cfg.Port) } + if len(cfg.Features) == 0 { + cfg.Features = make(map[Feature]bool) + cfg.Features[Alerting] = true + cfg.Features[LegacyDashboards] = true + cfg.Features[Metrics] = true + cfg.Features[Targets] = true + } + // Uncomment the following line for local development: // k8sconfig, err := clientcmd.BuildConfigFromFlags("", "$HOME/.kube/config") diff --git a/scripts/start-console.sh b/scripts/start-console.sh index 86e2b9289..5e2e65e1e 100755 --- a/scripts/start-console.sh +++ b/scripts/start-console.sh @@ -4,7 +4,7 @@ set -euo pipefail CONSOLE_IMAGE=${CONSOLE_IMAGE:="quay.io/openshift/origin-console:latest"} CONSOLE_PORT=${CONSOLE_PORT:=9000} -PLUGIN_PORT=${PLUGIN_PORT:=9001} +PLUGIN_PORT=${PLUGIN_PORT:=9443} CONSOLE_IMAGE_PLATFORM=${CONSOLE_IMAGE_PLATFORM:="linux/amd64"} npm_package_consolePlugin_name=${npm_package_consolePlugin_name:="monitoring-plugin"} diff --git a/web/console-extensions.json b/web/console-extensions.json deleted file mode 100644 index 1126fffd7..000000000 --- a/web/console-extensions.json +++ /dev/null @@ -1,420 +0,0 @@ -[ - { - "type": "console.navigation/href", - "properties": { - "id": "alerting", - "name": "%plugin__monitoring-plugin~Alerting%", - "href": "/monitoring/alerts", - "perspective": "admin", - "section": "observe", - "startsWith": ["monitoring/alertrules", "monitoring/silences", "monitoring/incidents"] - } - }, - { - "properties": { - "dataAttributes": { - "data-quickstart-id": "qs-nav-monitoring" - }, - "id": "observe-virt-perspective", - "insertBefore": ["compute-virt-perspective", "usermanagement-virt-perspective"], - "name": "%console-app~Observe%", - "perspective": "virtualization-perspective" - }, - "type": "console.navigation/section" - }, - { - "type": "console.navigation/href", - "properties": { - "id": "alerting-virt", - "name": "%plugin__monitoring-plugin~Alerting%", - "href": "/virt-monitoring/alerts", - "perspective": "virtualization-perspective", - "section": "observe-virt-perspective", - "startsWith": [ - "virt-monitoring/alertrules", - "virt-monitoring/silences", - "virt-monitoring/incidents" - ] - } - }, - { - "type": "console.navigation/href", - "properties": { - "id": "metrics", - "name": "%plugin__monitoring-plugin~Metrics%", - "href": "/monitoring/query-browser", - "perspective": "admin", - "section": "observe", - "insertAfter": "alerts" - } - }, - { - "type": "console.navigation/href", - "properties": { - "id": "metrics-virt", - "name": "%plugin__monitoring-plugin~Metrics%", - "href": "/virt-monitoring/query-browser", - "perspective": "virtualization-perspective", - "section": "observe-virt-perspective", - "insertAfter": "alerts" - } - }, - { - "type": "console.navigation/href", - "properties": { - "id": "dashboards", - "name": "%plugin__monitoring-plugin~Dashboards%", - "href": "/monitoring/dashboards", - "perspective": "admin", - "section": "observe", - "insertAfter": "metrics" - } - }, - { - "type": "console.navigation/href", - "properties": { - "id": "dashboards-virt", - "name": "%plugin__monitoring-plugin~Dashboards%", - "href": "/virt-monitoring/dashboards", - "perspective": "virtualization-perspective", - "section": "observe-virt-perspective", - "insertAfter": "metrics-virt" - } - }, - { - "type": "console.navigation/href", - "properties": { - "id": "targets", - "name": "%plugin__monitoring-plugin~Targets%", - "href": "/monitoring/targets", - "perspective": "admin", - "section": "observe", - "insertAfter": "dashboards" - } - }, - { - "type": "console.navigation/href", - "properties": { - "id": "targets-virt", - "name": "%plugin__monitoring-plugin~Targets%", - "href": "/virt-monitoring/targets", - "perspective": "virtualization-perspective", - "section": "observe-virt-perspective", - "insertAfter": "dashboards-virt" - } - }, - { - "type": "console.redux-reducer", - "properties": { - "scope": "mp", - "reducer": { - "$codeRef": "MonitoringReducer" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/monitoring", - "component": { - "$codeRef": "AlertingPage.MpCmoAlertingPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/monitoring/silences/~new", - "component": { - "$codeRef": "SilenceCreatePage.MpCmoCreateSilencePage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/monitoring/silences/:id", - "component": { - "$codeRef": "SilencesDetailsPage.MpCmoSilencesDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/monitoring/silences/:id/edit", - "component": { - "$codeRef": "SilenceEditPage.MpCmoSilenceEditPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/monitoring/targets", "/monitoring/targets/:scrapeUrl"], - "component": { - "$codeRef": "TargetsPage.MpCmoTargetsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/monitoring/query-browser"], - "component": { - "$codeRef": "MetricsPage.MpCmoMetricsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/monitoring/graph"], - "component": { - "$codeRef": "PrometheusRedirectPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/monitoring/dashboards", "/monitoring/dashboards/:dashboardName"], - "component": { - "$codeRef": "LegacyDashboardsPage.MpCmoLegacyDashboardsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/monitoring/alertrules/:id"], - "component": { - "$codeRef": "AlertRulesDetailsPage.MpCmoAlertRulesDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/monitoring/alerts/:ruleID"], - "component": { - "$codeRef": "AlertsDetailsPage.MpCmoAlertsDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/virt-monitoring"], - "component": { - "$codeRef": "AlertingPage.MpCmoAlertingPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/virt-monitoring/silences/~new", - "component": { - "$codeRef": "SilenceCreatePage.MpCmoCreateSilencePage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/virt-monitoring/silences/:id", - "component": { - "$codeRef": "SilencesDetailsPage.MpCmoSilencesDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/virt-monitoring/silences/:id/edit", - "component": { - "$codeRef": "SilenceEditPage.MpCmoSilenceEditPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/virt-monitoring/targets", "/virt-monitoring/targets/:scrapeUrl"], - "component": { - "$codeRef": "TargetsPage.MpCmoTargetsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/virt-monitoring/query-browser"], - "component": { - "$codeRef": "MetricsPage.MpCmoMetricsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/virt-monitoring/graph"], - "component": { - "$codeRef": "PrometheusRedirectPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/virt-monitoring/dashboards", "/virt-monitoring/dashboards/:dashboardName"], - "component": { - "$codeRef": "LegacyDashboardsPage.MpCmoLegacyDashboardsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/virt-monitoring/alertrules/:id"], - "component": { - "$codeRef": "AlertRulesDetailsPage.MpCmoAlertRulesDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": ["/virt-monitoring/alerts/:ruleID"], - "component": { - "$codeRef": "AlertsDetailsPage.MpCmoAlertsDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/dev-monitoring/ns/:ns/alerts/:ruleID", - "component": { - "$codeRef": "AlertsDetailsPage.MpCmoAlertsDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/dev-monitoring/ns/:ns/rules/:id", - "component": { - "$codeRef": "AlertRulesDetailsPage.MpCmoAlertRulesDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/dev-monitoring/ns/:ns/silences/:id", - "component": { - "$codeRef": "SilencesDetailsPage.MpCmoSilencesDetailsPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/dev-monitoring/ns/:ns/silences/:id/edit", - "component": { - "$codeRef": "SilenceEditPage.MpCmoSilenceEditPage" - } - } - }, - { - "type": "console.page/route", - "properties": { - "exact": false, - "path": "/dev-monitoring/ns/:ns/silences/~new", - "component": { - "$codeRef": "SilenceCreatePage.MpCmoCreateSilencePage" - } - } - }, - { - "type": "console.tab", - "properties": { - "contextId": "dev-console-observe", - "name": "%plugin__monitoring-plugin~Silences%", - "href": "silences", - "component": { - "$codeRef": "SilencesPage.MpCmoSilencesPage" - } - } - }, - { - "type": "console.tab", - "properties": { - "contextId": "dev-console-observe", - "name": "%plugin__monitoring-plugin~Metrics%", - "href": "metrics", - "component": { - "$codeRef": "MetricsPage.MpCmoDevMetricsPage" - } - } - }, - { - "type": "console.tab", - "properties": { - "contextId": "dev-console-observe", - "name": "%plugin__monitoring-plugin~Alerts%", - "href": "alerts", - "component": { - "$codeRef": "AlertsPage.MpCmoAlertsPage" - } - } - }, - { - "type": "console.tab", - "properties": { - "contextId": "dev-console-observe", - "name": "%plugin__monitoring-plugin~Alerting rules%", - "href": "alertrules", - "component": { - "$codeRef": "AlertRulesPage.MpCmoAlertRulesPage" - } - } - }, - { - "type": "console.tab", - "properties": { - "contextId": "dev-console-observe", - "name": "%plugin__monitoring-plugin~Dashboards%", - "href": "", - "component": { - "$codeRef": "LegacyDashboardsPage.MpCmoLegacyDevDashboardsPage" - } - } - } -] diff --git a/web/webpack.config.ts b/web/webpack.config.ts index 0b8b7b2c7..3c735f41f 100644 --- a/web/webpack.config.ts +++ b/web/webpack.config.ts @@ -91,6 +91,7 @@ const config: Configuration = { plugins: [ new ConsoleRemotePlugin({ validateExtensionIntegrity: false, + extensions: [], }), new CopyWebpackPlugin({ patterns: [{ from: path.resolve(__dirname, 'locales'), to: 'locales' }], @@ -111,6 +112,16 @@ const config: Configuration = { stats: { errorDetails: true, }, + ignoreWarnings: [ + (warning) => { + // Since we are adding all features in dynamically on the backend, we want to + // suppress the warning that what were are building does not have any extensions + if (warning.message === 'Plugin has no extensions') { + return true; + } + return false; + }, + ], }; if (process.env.NODE_ENV === 'production') {