diff --git a/charts/heimdall-v2/Chart.yaml b/charts/heimdall-v2/Chart.yaml index d2b69454..cf31a4df 100644 --- a/charts/heimdall-v2/Chart.yaml +++ b/charts/heimdall-v2/Chart.yaml @@ -15,11 +15,11 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.0.4 +version: 0.0.5 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. # renovate: image=0xpolygon/heimdall-v2 -appVersion: "0.2.17" +appVersion: "0.3.0" diff --git a/charts/heimdall-v2/README.md b/charts/heimdall-v2/README.md index c5fcd456..2748b258 100644 --- a/charts/heimdall-v2/README.md +++ b/charts/heimdall-v2/README.md @@ -2,7 +2,7 @@ Deploy and scale [Heimdall-v2](https://github.com/0xPolygon/heimdall-v2) inside Kubernetes with ease -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ![Version: 0.0.4](https://img.shields.io/badge/Version-0.0.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.2.17](https://img.shields.io/badge/AppVersion-0.2.17-informational?style=flat-square) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ![Version: 0.0.5](https://img.shields.io/badge/Version-0.0.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square) ## Features @@ -12,6 +12,7 @@ Deploy and scale [Heimdall-v2](https://github.com/0xPolygon/heimdall-v2) inside - Readiness checks to ensure traffic only hits `Pod`s that are healthy and ready to serve requests - Support for `PodMonitor`s to configure Prometheus to scrape metrics ([prometheus-operator](https://github.com/prometheus-operator/prometheus-operator)) - Support for configuring Grafana dashboards for polygon ([grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana)) + - P2P exposure via NodePort or LoadBalancer with matching container ports ## Quickstart @@ -47,6 +48,14 @@ We do not recommend that you upgrade the application by overriding `image.tag`. | grafana.dashboards | Enable creation of Grafana dashboards. [Grafana chart](https://github.com/grafana/helm-charts/tree/main/charts/grafana#grafana-helm-chart) must be configured to search this namespace, see `sidecar.dashboards.searchNamespace` | bool | `false` | | grafana.dashboardsConfigMapLabel | Must match `sidecar.dashboards.label` value for the [Grafana chart](https://github.com/grafana/helm-charts/tree/main/charts/grafana#grafana-helm-chart) | string | `"grafana_dashboard"` | | grafana.dashboardsConfigMapLabelValue | Must match `sidecar.dashboards.labelValue` value for the [Grafana chart](https://github.com/grafana/helm-charts/tree/main/charts/grafana#grafana-helm-chart) | string | `""` | + | grafana.operatorDashboards | Create GrafanaDashboard CRDs via Grafana Operator from files in `dashboards/` | object | `{"allowCrossNamespaceImport":false,"annotations":{},"enabled":false,"extraSpec":{},"folder":"","folderUID":"","instanceSelector":{"matchLabels":{}},"labels":{},"namespace":"","resyncPeriod":"","suspend":false,"uid":""}` | + | grafana.operatorDashboards.allowCrossNamespaceImport | Allow matching Grafana instances outside current namespace | bool | `false` | + | grafana.operatorDashboards.extraSpec | Additional spec fields to merge into GrafanaDashboard.spec | object | `{}` | + | grafana.operatorDashboards.folder | Optional folder metadata | string | `""` | + | grafana.operatorDashboards.instanceSelector | Selector to match Grafana instances managed by the operator | object | `{"matchLabels":{}}` | + | grafana.operatorDashboards.labels | Extra labels and annotations on the GrafanaDashboard resources | object | `{}` | + | grafana.operatorDashboards.namespace | Optional target namespace for the GrafanaDashboard CRDs (defaults to release namespace) | string | `""` | + | grafana.operatorDashboards.resyncPeriod | Operator sync behavior | string | `""` | | heimdall.affinity | | object | `{}` | | heimdall.affinityPresets.antiAffinityByHostname | Configure anti-affinity rules to prevent multiple Heimdall instances on the same host | bool | `true` | | heimdall.config.borRpcUrl | Bor RPC address | string | `""` | @@ -72,6 +81,16 @@ We do not recommend that you upgrade the application by overriding `image.tag`. | heimdall.image.repository | Image for Heimdall | string | `"0xpolygon/heimdall-v2"` | | heimdall.image.tag | Overrides the image tag | string | Chart.appVersion | | heimdall.nodeSelector | | object | `{}` | + | heimdall.p2p.port | P2P listen port used by BOTH the container and the P2P Service (regardless of Service type). Notes: - LoadBalancer: the Service exposes this port and targets the container on the same port - NodePort: the Service uses this value as the nodePort; ensure it is allowed by cluster policy and available - Choose a value in your cluster’s NodePort range (typically 30000–32767) | int | `31000` | + | heimdall.p2p.service.advertiseIP | IP address to explicitly advertise on the P2P network (overrides autodetection and LB IP) | string | `""` | + | heimdall.p2p.service.annotations | Annotations to add to the P2P Service (useful for cloud LBs) | object | `{}` | + | heimdall.p2p.service.enabled | Enable creation of a P2P Service | bool | `false` | + | heimdall.p2p.service.externalIPs | Fixed external IPs to bind the Service to (works for NodePort or LoadBalancer; requires upstream routing) | list | `[]` | + | heimdall.p2p.service.externalTrafficPolicy | External traffic policy for NodePort/LoadBalancer | string | `"Local"` | + | heimdall.p2p.service.labels | Additional labels to add to the P2P Service | object | `{}` | + | heimdall.p2p.service.loadBalancerIP | When using a LoadBalancer and your cloud supports it, set a specific LB IP | string | `""` | + | heimdall.p2p.service.loadBalancerSourceRanges | Restrict which source ranges can access the LoadBalancer (CIDRs) | list | `[]` | + | heimdall.p2p.service.type | Service type for P2P exposure (NodePort or LoadBalancer) | string | `"NodePort"` | | heimdall.p2pNodePort.enabled | Expose P2P port via NodePort | bool | `false` | | heimdall.p2pNodePort.initContainer.image.pullPolicy | Container pull policy | string | `"IfNotPresent"` | | heimdall.p2pNodePort.initContainer.image.repository | Container image to fetch nodeport information | string | `"lachlanevenson/k8s-kubectl"` | diff --git a/charts/heimdall-v2/README.md.gotmpl b/charts/heimdall-v2/README.md.gotmpl index 510cd094..c6556bab 100644 --- a/charts/heimdall-v2/README.md.gotmpl +++ b/charts/heimdall-v2/README.md.gotmpl @@ -12,6 +12,7 @@ - Readiness checks to ensure traffic only hits `Pod`s that are healthy and ready to serve requests - Support for `PodMonitor`s to configure Prometheus to scrape metrics ([prometheus-operator](https://github.com/prometheus-operator/prometheus-operator)) - Support for configuring Grafana dashboards for polygon ([grafana](https://github.com/grafana/helm-charts/tree/main/charts/grafana)) + - P2P exposure via NodePort or LoadBalancer with matching container ports ## Quickstart diff --git a/charts/heimdall-v2/templates/_helpers.tpl b/charts/heimdall-v2/templates/_helpers.tpl index 4ad14749..24a21ac1 100644 --- a/charts/heimdall-v2/templates/_helpers.tpl +++ b/charts/heimdall-v2/templates/_helpers.tpl @@ -160,6 +160,51 @@ invalid network {{- end }} {{- end }} +{{/* +P2P helpers +*/}} +{{- define "heimdall.p2p.nodePortBase" -}} +{{- $v := . -}} +{{- if and $v.p2p $v.p2p.port -}} + {{- $v.p2p.port -}} +{{- else if and $v.p2pNodePort $v.p2pNodePort.port -}} + {{- $v.p2pNodePort.port -}} +{{- end -}} +{{- end -}} + +{{- define "heimdall.p2p.containerPort" -}} +{{- $v := . -}} +{{- if (include "heimdall.p2p.isNodePort" $v | trim | eq "true") -}} +{{- include "heimdall.p2p.nodePortBase" $v -}} +{{- else if and $v.p2p $v.p2p.port -}} +{{- $v.p2p.port -}} +{{- end -}} +{{- end -}} + +{{- define "heimdall.p2p.isNodePort" -}} +{{- $v := . -}} +{{- if and $v.p2p $v.p2p.service $v.p2p.service.enabled -}} + {{- if eq (default "NodePort" $v.p2p.service.type) "NodePort" -}} +true + {{- else -}} +false + {{- end -}} +{{- else if and $v.p2pNodePort $v.p2pNodePort.enabled -}} +true +{{- else -}} +false +{{- end -}} +{{- end -}} + +{{- define "heimdall.p2p.isLoadBalancer" -}} +{{- $v := . -}} +{{- if and $v.p2p $v.p2p.service $v.p2p.service.enabled (eq (default "" $v.p2p.service.type) "LoadBalancer") -}} +true +{{- else -}} +false +{{- end -}} +{{- end -}} + {{/* Generate the array of options for heimdall */}} @@ -167,12 +212,22 @@ Generate the array of options for heimdall {{- $args := list "--home=\"/storage\"" }} -{{- $args = concat $args (list (print "--rpc.laddr=" ( print "tcp://127.0.0.1:" ( index .service.ports "http-rpc" ) | quote ))) }} -{{- $args = concat $args (list (print "--api.address=" ( print "tcp://127.0.0.1:" ( index .service.ports "http-api" ) | quote ))) }} -{{- if .p2pNodePort.enabled }} -{{- $args = concat $args (list (print "--p2p.laddr=" ( print "tcp://0.0.0.0:" .p2pNodePort.port | quote ))) }} +{{- $args = concat $args (list (print "--rpc.laddr=" ( print "tcp://0.0.0.0:" ( index .service.ports "http-rpc" ) | quote ))) }} +{{- $args = concat $args (list (print "--api.address=" ( print "tcp://0.0.0.0:" ( index .service.ports "http-api" ) | quote ))) }} +{{- if (include "heimdall.p2p.isNodePort" . | trim | eq "true") }} +{{- $args = concat $args (list (print "--p2p.laddr=" ( print "tcp://0.0.0.0:" ( include "heimdall.p2p.nodePortBase" . ) | quote ))) }} +{{- $args = concat $args (list (print "--seeds=" ( include "heimdall.seeds" . | quote ) )) }} +{{- else if (include "heimdall.p2p.isLoadBalancer" . | trim | eq "true") }} +{{- $args = concat $args (list (print "--p2p.laddr=" ( print "tcp://0.0.0.0:" ( include "heimdall.p2p.containerPort" . ) | quote ))) }} {{- $args = concat $args (list (print "--seeds=" ( include "heimdall.seeds" . | quote ) )) }} {{- end }} + +{{- /* Prefer an explicit advertiseIP over LB IP for external-address */ -}} +{{- if and .p2p .p2p.service .p2p.service.advertiseIP }} +{{- $args = concat $args (list (print "--p2p.external-address=" ( print (printf "tcp://%s:%v" .p2p.service.advertiseIP (include "heimdall.p2p.containerPort" .)) | quote ))) }} +{{- else if and .p2p .p2p.service (eq .p2p.service.type "LoadBalancer") .p2p.service.loadBalancerIP }} +{{- $args = concat $args (list (print "--p2p.external-address=" ( print (printf "tcp://%s:%v" .p2p.service.loadBalancerIP (include "heimdall.p2p.containerPort" .)) | quote ))) }} +{{- end }} {{- with .config }} {{- $args = concat $args (list (print "--chain=" ( print .network | quote ) )) }} {{- $args = concat $args (list (print "--log_level=" ( print .logLevel | quote ) )) }} diff --git a/charts/heimdall-v2/templates/dashboards-operator.yaml b/charts/heimdall-v2/templates/dashboards-operator.yaml new file mode 100644 index 00000000..900ec303 --- /dev/null +++ b/charts/heimdall-v2/templates/dashboards-operator.yaml @@ -0,0 +1,52 @@ +{{- $g := $.Values.grafana -}} +{{- if and $g.operatorDashboards $g.operatorDashboards.enabled -}} +{{- $op := $g.operatorDashboards -}} +{{- $files := .Files.Glob "dashboards/*" -}} +{{- range $path, $_ := $files }} +--- +apiVersion: grafana.integreatly.org/v1beta1 +kind: GrafanaDashboard +metadata: + name: {{ include "heimdall.fullname" $ }}-{{ base $path | replace "." "-" | trunc 63 | trimSuffix "-" }} + {{- with $op.namespace }} + {{- if . }} + namespace: {{ . }} + {{- end }} + {{- end }} + labels: + {{- include "heimdall.labels" $ | nindent 4 }} + {{- with $op.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $op.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + allowCrossNamespaceImport: {{ default false $op.allowCrossNamespaceImport }} + {{- with $op.instanceSelector }} + instanceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $op.folder }} + folder: {{ . }} + {{- end }} + {{- with $op.folderUID }} + folderUID: {{ . }} + {{- end }} + {{- with $op.uid }} + uid: {{ . }} + {{- end }} + {{- with $op.resyncPeriod }} + resyncPeriod: {{ . }} + {{- end }} + {{- if hasKey $op "suspend" }} + suspend: {{ $op.suspend }} + {{- end }} + {{- with $op.extraSpec }} + {{- toYaml . | nindent 2 }} + {{- end }} + json: | + {{- $.Files.Get $path | nindent 4 }} +{{- end }} +{{- end }} diff --git a/charts/heimdall-v2/templates/heimdall/service.yaml b/charts/heimdall-v2/templates/heimdall/service.yaml index b73cf94d..ac5b5771 100644 --- a/charts/heimdall-v2/templates/heimdall/service.yaml +++ b/charts/heimdall-v2/templates/heimdall/service.yaml @@ -51,8 +51,9 @@ spec: {{- include "heimdall.selectorLabels" . | nindent 4 }} {{- $componentLabel | nindent 4 }} {{- end }} -{{- if $values.p2pNodePort.enabled }} -{{- $port := $values.p2pNodePort.port }} +{{/* P2P Service: NodePort (legacy or new style) */}} +{{- if (include "heimdall.p2p.isNodePort" $values | trim | eq "true") }} +{{- $port := (include "heimdall.p2p.nodePortBase" $values) | int }} --- apiVersion: v1 kind: Service @@ -63,9 +64,16 @@ metadata: {{- $componentLabel | nindent 4 }} pod: {{ include "heimdall.fullname" . }}-{{ $componentName }}-0 type: p2p # this label is used by the initContainer to select this service + {{- with $values.p2p.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: type: NodePort externalTrafficPolicy: Local + {{- with $values.p2p.service.externalIPs }} + externalIPs: + {{- toYaml . | nindent 2 }} + {{- end }} ports: - name: tcp-p2p port: {{ $port }} @@ -76,3 +84,46 @@ spec: {{- include "heimdall.selectorLabels" . | nindent 4 }} statefulset.kubernetes.io/pod-name: "{{ include "heimdall.fullname" $ }}-{{ $componentName }}-0" {{- end }} + +{{/* P2P Service: LoadBalancer */}} +{{- if (include "heimdall.p2p.isLoadBalancer" $values | trim | eq "true") }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "heimdall.fullname" . }}-{{ $componentName }}-p2p + labels: + {{- include "heimdall.labels" . | nindent 4 }} + {{- $componentLabel | nindent 4 }} + {{- with $values.p2p.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $values.p2p.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: LoadBalancer + {{- if $values.p2p.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ $values.p2p.service.externalTrafficPolicy }} + {{- end }} + {{- with $values.p2p.service.loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + {{- with $values.p2p.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with $values.p2p.service.externalIPs }} + externalIPs: + {{- toYaml . | nindent 2 }} + {{- end }} + ports: + - name: tcp-p2p + port: {{ include "heimdall.p2p.containerPort" $values }} + protocol: TCP + targetPort: tcp-p2p + selector: + {{- include "heimdall.selectorLabels" . | nindent 4 }} + {{- $componentLabel | nindent 4 }} +{{- end }} diff --git a/charts/heimdall-v2/templates/heimdall/statefulset.yaml b/charts/heimdall-v2/templates/heimdall/statefulset.yaml index 5b8dc643..ae798aab 100644 --- a/charts/heimdall-v2/templates/heimdall/statefulset.yaml +++ b/charts/heimdall-v2/templates/heimdall/statefulset.yaml @@ -129,6 +129,15 @@ spec: else sed -iE "s#^prometheus[[:space:]]*=.*#prometheus = false#" config.toml fi + + # Set external_address to advertise if provided + if [ -n "${EXTERNAL_P2P_ADDRESS:-}" ]; then + if grep -q "^external_address" config.toml; then + sed -iE "s#^external_address[[:space:]]*=.*#external_address = \"${EXTERNAL_P2P_ADDRESS}\"#" config.toml + else + printf '\nexternal_address = "%s"\n' "${EXTERNAL_P2P_ADDRESS}" >> config.toml + fi + fi volumeMounts: - name: storage mountPath: /storage @@ -147,6 +156,15 @@ spec: {{- else }} value: {{ .Release.Name }} {{- end }} + {{- if and $values.p2p $values.p2p.service }} + {{- if $values.p2p.service.advertiseIP }} + - name: EXTERNAL_P2P_ADDRESS + value: {{ printf "tcp://%s:%v" $values.p2p.service.advertiseIP (include "heimdall.p2p.containerPort" $values) | quote }} + {{- else if and (eq $values.p2p.service.type "LoadBalancer") $values.p2p.service.loadBalancerIP }} + - name: EXTERNAL_P2P_ADDRESS + value: {{ printf "tcp://%s:%v" $values.p2p.service.loadBalancerIP (include "heimdall.p2p.containerPort" $values) | quote }} + {{- end }} + {{- end }} {{- if $values.config.downloadGenesis.enabled }} - name: GENESIS value: "true" @@ -217,9 +235,9 @@ spec: - name: http-metrics containerPort: {{ index $values.service.ports "http-metrics" }} protocol: TCP - {{- if $values.p2pNodePort.enabled }} + {{- if or (include "heimdall.p2p.isNodePort" $values | trim | eq "true") (include "heimdall.p2p.isLoadBalancer" $values | trim | eq "true") }} - name: tcp-p2p - containerPort: {{ $values.p2pNodePort.port }} + containerPort: {{ include "heimdall.p2p.containerPort" $values }} protocol: TCP {{- end }} volumeMounts: diff --git a/charts/heimdall-v2/values.yaml b/charts/heimdall-v2/values.yaml index d1cd4041..13c0e680 100644 --- a/charts/heimdall-v2/values.yaml +++ b/charts/heimdall-v2/values.yaml @@ -29,6 +29,28 @@ grafana: dashboardsConfigMapLabel: grafana_dashboard # -- Must match `sidecar.dashboards.labelValue` value for the [Grafana chart](https://github.com/grafana/helm-charts/tree/main/charts/grafana#grafana-helm-chart) dashboardsConfigMapLabelValue: "" + # -- Create GrafanaDashboard CRDs via Grafana Operator from files in `dashboards/` + operatorDashboards: + enabled: false + # -- Optional target namespace for the GrafanaDashboard CRDs (defaults to release namespace) + namespace: "" + # -- Extra labels and annotations on the GrafanaDashboard resources + labels: {} + annotations: {} + # -- Selector to match Grafana instances managed by the operator + instanceSelector: + matchLabels: {} + # -- Allow matching Grafana instances outside current namespace + allowCrossNamespaceImport: false + # -- Optional folder metadata + folder: "" + folderUID: "" + uid: "" + # -- Operator sync behavior + resyncPeriod: "" + suspend: false + # -- Additional spec fields to merge into GrafanaDashboard.spec + extraSpec: {} heimdall: @@ -154,5 +176,33 @@ heimdall: # -- Container pull policy pullPolicy: IfNotPresent + # P2P configuration (supersedes p2pNodePort) + p2p: + # -- P2P listen port used by BOTH the container and the P2P Service (regardless of Service type). + # Notes: + # - LoadBalancer: the Service exposes this port and targets the container on the same port + # - NodePort: the Service uses this value as the nodePort; ensure it is allowed by cluster policy and available + # - Choose a value in your cluster’s NodePort range (typically 30000–32767) + port: 31000 + service: + # -- Enable creation of a P2P Service + enabled: false + # -- Service type for P2P exposure (NodePort or LoadBalancer) + type: NodePort + # -- Annotations to add to the P2P Service (useful for cloud LBs) + annotations: {} + # -- Additional labels to add to the P2P Service + labels: {} + # -- External traffic policy for NodePort/LoadBalancer + externalTrafficPolicy: Local + # -- IP address to explicitly advertise on the P2P network (overrides autodetection and LB IP) + advertiseIP: "" + # -- Fixed external IPs to bind the Service to (works for NodePort or LoadBalancer; requires upstream routing) + externalIPs: [] + # -- When using a LoadBalancer and your cloud supports it, set a specific LB IP + loadBalancerIP: "" + # -- Restrict which source ranges can access the LoadBalancer (CIDRs) + loadBalancerSourceRanges: [] + # -- Enable a readiness probe that checks if heimdall is synced readyAfterSync: false