You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by "hanahmily (via GitHub)" <gi...@apache.org> on 2026/08/02 07:45:51 UTC
[PR] feat(chart): add the canopy web console [skywalking-banyandb-helm]
hanahmily opened a new pull request, #69:
URL: https://github.com/apache/skywalking-banyandb-helm/pull/69
## Summary
Adds the [canopy](https://github.com/apache/skywalking-banyandb/tree/main/canopy) web console to the chart as an optional component for **both standalone and cluster modes** (test/verification included — see below).
**Templates & values** (new top-level `canopy.*` section, mirroring the `plugins:` pattern)
- `canopy_deployment.yaml` / `canopy_service.yaml` / `canopy_ingress.yaml` / `canopy_secret.yaml`, plus `banyandb.canopy*` helpers (`_helpers.tpl`).
- Image resolves to `<image.repository>:<image.tag>-canopy` in lockstep with the BanyanDB image (same suffix pattern as `-plugins-carrier`).
- `BANYANDB_TARGET` computes to the `<release>-http` service in either mode; the HTTP services now also expose the **2121 observability port** for `MONITOR_TARGET`.
- When BanyanDB basic auth is on, the first declared `auth.users` entry is wired as the console's upstream credential (overridable via `canopy.env`).
**Default admin user**
- No credentials provided → the chart generates a strong random 24-char password (stored bcrypt-hashed for canopy) + a random session secret. `lookup()` keeps both **stable across upgrades**; the password rotates only if the Secret is deleted.
- `helm install/upgrade` NOTES print exactly how to retrieve it (`kubectl get secret <release>-canopy-auth -o jsonpath='{.data.password}' | base64 -d`).
- Alternatives: `canopy.auth.password`/`canopy.auth.users` (bcrypt), or `canopy.auth.existingSecret` with `session-secret` + `users.yaml` keys.
**Test & verification (the gate)**
- New e2e scenarios `e2e-canopy-standalone.yaml` / `e2e-canopy-cluster.yaml` added to the `e2e.ci.yaml` matrix, asserting via `verify-canopy.sh`: healthz, **generated-default-admin login with the password read from the Secret**, `/api/meta` reachable through the BFF, SPA index, and a registry read through the proxy.
- Verified locally on kind before opening: `helm template`/lint across the mode×auth matrix; standalone install → **VERIFY PASS**; password **stable across `helm upgrade`**; cluster install (liaison ×2, data ×2, DB auth on) → **VERIFY PASS**.
**Docs**: README "Canopy console" section, `doc/parameters.md` rows (hand-appended — the bitnami generator package wasn't installable locally; a regeneration pass will normalize), `CHANGES.md` entry.
## Notes
- `canopy.image.tag` in the e2e values is a `REPLACE_WITH_MAIN_SHA-canopy` placeholder: the first `-canopy` image is only published once apache/skywalking-banyandb#1239 merges (the buildx-driver fix for the main push). I'll pin the real sha here as soon as it lands; the scenarios are blocked on that either way.
- `helm lint` reports a pre-existing parse error in `cluster_data_statefulset.yaml` on master (reproduces without this change; left untouched).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(chart): add the canopy web console [skywalking-banyandb-helm]
Posted by "hanahmily (via GitHub)" <gi...@apache.org>.
hanahmily merged PR #69:
URL: https://github.com/apache/skywalking-banyandb-helm/pull/69
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] feat(chart): add the canopy web console [skywalking-banyandb-helm]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #69:
URL: https://github.com/apache/skywalking-banyandb-helm/pull/69#discussion_r3709683367
##########
chart/templates/canopy_service.yaml:
##########
@@ -0,0 +1,54 @@
+{{/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{- if .Values.canopy.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "banyandb.fullname" . }}-canopy
+ labels: {{ include "banyandb.labels" . | nindent 4 }}
+ app.kubernetes.io/component: canopy
+ {{- range $key, $value := .Values.canopy.service.labels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ annotations:
+ {{- range $key, $value := .Values.canopy.service.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ type: {{ .Values.canopy.service.type }}
+ ports:
+ - port: {{ .Values.canopy.service.port }}
+ name: http
Review Comment:
`canopy.service.port` is configurable, but the Service does not set `targetPort`. If a user changes the service port, Kubernetes will default `targetPort` to the same number and route traffic to a container port that the canopy pod is not listening on (the Deployment hard-codes 4000). Add `targetPort: http` (or 4000) so changing the Service port doesn’t break routing.
##########
chart/templates/canopy_secret.yaml:
##########
@@ -0,0 +1,51 @@
+{{/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{/*
+Canopy console auth Secret. When the user provides no credentials, the chart
+generates a default admin user with a strong random password (24 alphanumeric
+chars) and a random session secret. lookup() keeps both stable across
+upgrades — the password rotates only when the Secret is deleted.
+*/}}
+{{- if and .Values.canopy.enabled (not .Values.canopy.auth.existingSecret) }}
+{{- $secretName := printf "%s-canopy-auth" (include "banyandb.fullname" .) -}}
+{{- $existing := lookup "v1" "Secret" .Release.Namespace $secretName | default dict -}}
+{{- $existingData := get $existing "data" | default dict -}}
+{{- $password := .Values.canopy.auth.password | default (get $existingData "password" | b64dec | default (randAlphaNum 24)) -}}
+{{- $session := .Values.canopy.auth.sessionSecret | default (get $existingData "session-secret" | b64dec | default (randAlphaNum 48)) -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ $secretName }}
+ labels: {{ include "banyandb.labels" . | nindent 4 }}
+ app.kubernetes.io/component: canopy
+type: Opaque
+stringData:
+ # plaintext, read-once via kubectl (see NOTES.txt) — bcrypt form is what
+ # canopy actually consumes below.
+ password: {{ $password | quote }}
+ session-secret: {{ $session | quote }}
+ users.yaml: |
+ - username: {{ .Values.canopy.auth.username }}
Review Comment:
The generated `users.yaml` always includes a default admin entry, but `canopy.auth.username` is not validated. If a user sets it to an empty string, the Secret will render an invalid/empty username entry and canopy will likely fail to load users. Require a non-empty username when generating the Secret.
##########
chart/templates/_helpers.tpl:
##########
@@ -517,3 +517,60 @@ Ki/Mi/Gi/Ti (also KiB/MiB/GiB/TiB). No suffix -> plain byte count. Empty or 0 ->
{{- mul $num $mult -}}
{{- end -}}
{{- end }}
+
+{{/*
+Canopy console image. Repository/pullPolicy default to the main image config;
+the tag defaults to "<image.tag>-canopy" (lockstep, mirroring the plugins
+carrier pattern) since the console ships in the same repo with a tag suffix.
+*/}}
+{{- define "banyandb.canopyImage" -}}
+{{- $repo := .Values.canopy.image.repository | default .Values.image.repository -}}
+{{- $tag := .Values.canopy.image.tag | default (printf "%s-canopy" (required "banyandb.image.tag is required" .Values.image.tag)) -}}
+{{- printf "%s:%s" $repo $tag -}}
+{{- end }}
+
+{{/*
+Canopy image pullPolicy (defaults to the main image pullPolicy).
+*/}}
+{{- define "banyandb.canopyImagePullPolicy" -}}
+{{- .Values.canopy.image.pullPolicy | default .Values.image.pullPolicy -}}
+{{- end }}
+
+{{/*
+The BanyanDB HTTP service port canopy proxies to: liaison's in cluster mode,
+standalone's otherwise.
+*/}}
+{{- define "banyandb.canopyHttpPort" -}}
+{{- if .Values.cluster.enabled -}}
+{{- .Values.cluster.liaison.httpSvc.port -}}
+{{- else -}}
+{{- .Values.standalone.httpSvc.port -}}
+{{- end -}}
+{{- end }}
+
+{{/*
+BANYANDB_TARGET for the canopy container. The <fullname>-http service exists
+in both modes (standalone -> standalone pods, cluster -> liaison pods).
+*/}}
+{{- define "banyandb.canopyTarget" -}}
+{{- printf "http://%s-http:%v" (include "banyandb.fullname" .) (include "banyandb.canopyHttpPort" .) -}}
+{{- end }}
Review Comment:
`banyandb.canopyTarget` always uses `http://...` even when BanyanDB HTTP TLS is enabled (e.g., `standalone.tls.httpSecretName` / `cluster.liaison.tls.httpSecretName`), which would make canopy’s BFF proxy calls fail against an HTTPS-only BanyanDB endpoint. Consider switching the scheme to `https` when HTTP TLS is configured for the selected mode.
##########
chart/templates/canopy_ingress.yaml:
##########
@@ -0,0 +1,65 @@
+{{/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{/* Canopy proxies /api and /monitoring too, so this single ingress exposes
+ both the console and the BanyanDB HTTP API. */}}
+{{- if and .Values.canopy.enabled .Values.canopy.ingress.enabled }}
+{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }}
+apiVersion: networking.k8s.io/v1
+{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress" }}
+apiVersion: networking.k8s.io/v1beta1
+{{- else }}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+ labels: {{ include "banyandb.labels" . | nindent 4 }}
+ app.kubernetes.io/component: canopy
+ {{- range $key, $value := .Values.canopy.ingress.labels }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+ name: {{ template "banyandb.fullname" . }}-canopy
+ annotations:
+ {{- range $key, $value := .Values.canopy.ingress.annotations }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
+spec:
+ rules:
+ {{- range .Values.canopy.ingress.rules }}
+ - host: {{ .host }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ pathType: Prefix
Review Comment:
This template renders `pathType: Prefix` even when using `networking.k8s.io/v1beta1` or `extensions/v1beta1`. `pathType` is only valid for `networking.k8s.io/v1` Ingress, so this will produce an invalid manifest on older clusters. Conditionally emit `pathType` only for the v1 API.
##########
.github/workflows/e2e.ci.yaml:
##########
@@ -95,12 +83,12 @@ jobs:
du -sh $dir
done
docker images
- - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+ - uses: actions/upload-artifact@v4
if: ${{ failure() }}
name: Upload Logs
with:
- name: logs-${{ github.run_id }}-${{ strategy.job-index }}
- path: "${{ runner.temp }}/skywalking-infra-e2e/logs"
+ name: logs
+ path: "${{ env.SW_INFRA_E2E_LOG_DIR }}"
Review Comment:
The artifact `with.name` is now a constant (`logs`). If more than one matrix leg fails in the same workflow run, multiple jobs will try to upload an artifact with the same name, which can fail or overwrite depending on the action’s behavior. Use a unique name per matrix leg/job (as the previous config did).
##########
.github/workflows/e2e.ci.yaml:
##########
@@ -95,12 +83,12 @@ jobs:
du -sh $dir
done
docker images
- - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+ - uses: actions/upload-artifact@v4
Review Comment:
This repo’s contribution rules prefer SHA-pinned GitHub Actions for supply-chain safety. Switching `actions/upload-artifact` to the floating `@v4` tag loses that pin and can unexpectedly change behavior over time; pin to a specific commit SHA instead.
##########
chart/values.yaml:
##########
@@ -132,6 +132,101 @@ auth:
##
users: []
+## @section Canopy web console configuration
+## Canopy is the standalone web console for BanyanDB (SPA + BFF), intended to
+## replace the legacy embedded UI. It proxies /api and /monitoring to BanyanDB,
+## so a single ingress to canopy covers both the console and the HTTP API.
+##
+canopy:
+ ## @param canopy.enabled Deploy the canopy console (Deployment + Service).
+ enabled: false
+
+ image:
+ ## @param canopy.image.repository Canopy image repository. Empty defaults to image.repository (the console ships in the same repo with a "-canopy" tag suffix).
+ repository: ""
+ ## @param canopy.image.tag Canopy image tag. Empty defaults to "<image.tag>-canopy" (lockstep with the BanyanDB image, mirroring the plugins carrier pattern).
+ tag: ""
+ ## @param canopy.image.pullPolicy Canopy image pull policy. Empty defaults to image.pullPolicy.
+ pullPolicy: ""
+
+ ## @param canopy.replicas Number of canopy replicas
+ replicas: 1
+
+ ## @param canopy.env Extra environment variables appended to the canopy container
+ env: []
+
+ ## Console authentication. Canopy always runs with NODE_ENV=production, which
+ ## forbids the dev no-auth mode — it needs a users file and a session secret.
+ ## When nothing is provided the chart generates a default admin user with a
+ ## strong random password (stable across upgrades); retrieve it from NOTES or:
+ ## kubectl get secret <release>-canopy-auth -o jsonpath='{.data.password}' | base64 -d
+ ##
+ auth:
+ ## @param canopy.auth.username Default admin username (generated user only)
+ username: admin
+ ## @param canopy.auth.password Default admin password. Empty generates a strong random one on install (reused on upgrades via the generated Secret).
+ password: ""
+ ## @param canopy.auth.sessionSecret Session signing secret (>= 32 chars). Empty generates a random one (also reused on upgrades).
+ sessionSecret: ""
+ ## @param canopy.auth.users Extra console users appended after the default admin, each {username, passwordHash (bcrypt), role (admin|readonly)}
+ users: []
+ ## @param canopy.auth.existingSecret Use an existing Secret instead of the generated one. Must contain keys "session-secret" and "users.yaml" (canopy users file format); may also carry "password" for NOTES output.
+ existingSecret: ""
+
+ service:
+ ## @param canopy.service.labels Labels for the canopy service
+ labels: {}
+ ## @param canopy.service.annotations Annotations for the canopy service
+ annotations: {}
+ ## @param canopy.service.port Canopy service port
+ port: 4000
+ ## @param canopy.service.type Canopy service type
+ type: ClusterIP
+ ## @param canopy.service.externalIPs External IPs for the canopy service
+ externalIPs: []
+ ## @param canopy.service.loadBalancerIP Load balancer IP for the canopy service
+ loadBalancerIP: ""
+ ## @param canopy.service.loadBalancerSourceRanges Load balancer source ranges
+ loadBalancerSourceRanges: []
+
+ ## @param canopy.updateStrategy.type Update strategy type for canopy pods
+ ## @param canopy.updateStrategy.rollingUpdate.maxUnavailable Maximum unavailable pods for canopy update
+ ## @param canopy.updateStrategy.rollingUpdate.maxSurge Maximum surge pods for canopy update
+ updateStrategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxUnavailable: 1
+ maxSurge: 1
+
+ ## @param canopy.podAnnotations Pod annotations for canopy
+ podAnnotations: {}
+ ## @param canopy.securityContext Security context for canopy pods
+ securityContext: {}
+ ## @param canopy.priorityClassName Priority class name for canopy pods
+ priorityClassName: ""
+ ## @param canopy.podDisruptionBudget Pod disruption budget for canopy
+ podDisruptionBudget: {}
Review Comment:
`canopy.podDisruptionBudget` is documented and exposed in values, but there is no template that consumes it (no `.Values.canopy.podDisruptionBudget` usage in `chart/templates/*`). As-is, user configuration here has no effect; either add a canopy PDB to `chart/templates/pdb.yaml` or remove this value+doc until it’s implemented.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org