Skip to content

Commit c4ac89e

Browse files
committed
feat: Configure Prometheus endpoint via Helm chart (#4562)
Signed-off-by: zyzzmohit <mohitray949@gmail.com>
1 parent 10316ab commit c4ac89e

File tree

8 files changed

+60
-16
lines changed

8 files changed

+60
-16
lines changed

backend/cmd/headlamp.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ const (
9797
type clientConfig struct {
9898
Clusters []Cluster `json:"clusters"`
9999
IsDynamicClusterEnabled bool `json:"isDynamicClusterEnabled"`
100+
PrometheusEndpoint string `json:"prometheusEndpoint"`
100101
}
101102

102103
type OauthConfig struct {
@@ -1749,7 +1750,7 @@ func parseClusterFromKubeConfig(kubeConfigs []string) ([]Cluster, []error) {
17491750
func (c *HeadlampConfig) getConfig(w http.ResponseWriter, r *http.Request) {
17501751
w.Header().Set("Content-Type", "application/json")
17511752

1752-
clientConfig := clientConfig{c.getClusters(), c.EnableDynamicClusters}
1753+
clientConfig := clientConfig{c.getClusters(), c.EnableDynamicClusters, c.PrometheusEndpoint}
17531754

17541755
if err := json.NewEncoder(w).Encode(&clientConfig); err != nil {
17551756
logger.Log(logger.LevelError, nil, err, "encoding config")

backend/cmd/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func buildHeadlampCFG(conf *config.Config, kubeConfigStore kubeconfig.ContextSto
100100
ProxyURLs: strings.Split(conf.ProxyURLs, ","),
101101
TLSCertPath: conf.TLSCertPath,
102102
TLSKeyPath: conf.TLSKeyPath,
103+
PrometheusEndpoint: *conf.PrometheusEndpoint,
103104
}
104105
}
105106

backend/cmd/stateless.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ func (c *HeadlampConfig) parseKubeConfig(w http.ResponseWriter, r *http.Request)
178178
return
179179
}
180180

181-
clientConfig := clientConfig{contexts, c.EnableDynamicClusters}
181+
clientConfig := clientConfig{contexts, c.EnableDynamicClusters, c.PrometheusEndpoint}
182182

183183
if err := json.NewEncoder(w).Encode(&clientConfig); err != nil {
184184
logger.Log(logger.LevelError, nil, err, "encoding config")

backend/pkg/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ type Config struct {
8383
// TLS config
8484
TLSCertPath string `koanf:"tls-cert-path"`
8585
TLSKeyPath string `koanf:"tls-key-path"`
86+
PrometheusEndpoint *string `koanf:"prometheus-endpoint"`
8687
}
8788

8889
func (c *Config) Validate() error {
@@ -434,6 +435,7 @@ func addGeneralFlags(f *flag.FlagSet) {
434435
f.Uint("port", defaultPort, "Port to listen from")
435436
f.String("proxy-urls", "", "Allow proxy requests to specified URLs")
436437
f.Bool("enable-helm", false, "Enable Helm operations")
438+
f.String("prometheus-endpoint", "", "Prometheus endpoint for the cluster")
437439
}
438440

439441
func addOIDCFlags(f *flag.FlagSet) {

charts/headlamp/templates/deployment.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,9 @@ spec:
316316
{{- with .Values.config.baseURL }}
317317
- "-base-url={{ . }}"
318318
{{- end }}
319+
{{- with .Values.config.prometheus.endpoint }}
320+
- "-prometheus-endpoint={{ . }}"
321+
{{- end }}
319322
{{- with .Values.config.tlsCertPath }}
320323
- "-tls-cert-path={{ . }}"
321324
{{- end }}

charts/headlamp/values.yaml

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ config:
3636
inClusterContextName: "main"
3737
# -- base url path at which headlamp should run
3838
baseURL: ""
39+
prometheus:
40+
# -- Prometheus endpoint for the cluster
41+
endpoint: ""
3942
oidc:
4043
# Option 1:
4144
# @param config.oidc.secret - OIDC secret configuration
@@ -159,8 +162,7 @@ podLabels: {}
159162
hostUsers: true
160163

161164
# -- Headlamp pod's Security Context
162-
podSecurityContext:
163-
{}
165+
podSecurityContext: {}
164166
# fsGroup: 2000
165167

166168
# -- Headlamp containers Security Context
@@ -182,7 +184,6 @@ securityContext:
182184
# drop:
183185
# - ALL
184186

185-
186187
service:
187188
# -- Annotations to add to the service
188189
annotations: {}
@@ -209,8 +210,7 @@ persistentVolumeClaim:
209210
# -- Enable Persistent Volume Claim
210211
enabled: false
211212
# -- Annotations to add to the persistent volume claim (if enabled)
212-
annotations:
213-
{}
213+
annotations: {}
214214
# -- accessModes for the persistent volume claim, eg: ReadWriteOnce, ReadOnlyMany, ReadWriteMany etc.
215215
accessModes: []
216216
# -- size of the persistent volume claim, eg: 10Gi. Required if enabled is true.
@@ -226,8 +226,7 @@ ingress:
226226
# -- Enable ingress controller resource
227227
enabled: false
228228
# -- Annotations for Ingress resource
229-
annotations:
230-
{}
229+
annotations: {}
231230
# kubernetes.io/tls-acme: "true"
232231

233232
# -- Additional labels to add to the Ingress resource
@@ -240,8 +239,7 @@ ingress:
240239

241240
# -- Hostname(s) for the Ingress resource
242241
# Please refer to https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec for more information.
243-
hosts:
244-
[]
242+
hosts: []
245243
# - host: chart-example.local
246244
# paths:
247245
# - path: /
@@ -286,8 +284,7 @@ httpRoute:
286284
# port: 80
287285

288286
# -- CPU/Memory resource requests/limits
289-
resources:
290-
{}
287+
resources: {}
291288
# We usually recommend not to specify default resources and to leave this as a conscious
292289
# choice for the user. This also increases chances charts run on environments with little
293290
# resources, such as Minikube. If you do want to specify resources, uncomment the following
@@ -351,8 +348,7 @@ pluginsManager:
351348
# cpu: "1000m"
352349
# memory: "4096Mi"
353350
# If omitted, the plugin manager will inherit the global securityContext
354-
securityContext:
355-
{}
351+
securityContext: {}
356352
# runAsUser: 1001
357353
# runAsNonRoot: true
358354
# allowPrivilegeEscalation: false

frontend/src/components/App/Layout.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { useCluster, useClustersConf } from '../../lib/k8s';
3232
import { request } from '../../lib/k8s/api/v1/clusterRequests';
3333
import { Cluster } from '../../lib/k8s/cluster';
3434
import { getSavedNamespaces } from '../../lib/storage';
35+
import { setPluginConfig } from '../../plugin/pluginConfigSlice';
3536
import { setConfig } from '../../redux/configSlice';
3637
import { ConfigState } from '../../redux/configSlice';
3738
import { setNamespaceFilter } from '../../redux/filterSlice';
@@ -178,6 +179,39 @@ const fetchConfig = (dispatch: Dispatch<UnknownAction>) => {
178179
fetchStatelessClusterKubeConfigs(dispatch);
179180
}
180181

182+
if (config?.prometheusEndpoint) {
183+
const currentPluginConfigs: { [key: string]: any } = store.getState().pluginConfigs || {};
184+
const prometheusConfig = currentPluginConfigs['prometheus'] || {};
185+
const newPrometheusConfig: { [key: string]: any } = { ...prometheusConfig };
186+
let hasChanges = false;
187+
188+
Object.keys(clustersToConfig).forEach(clusterName => {
189+
const currentClusterConfig = prometheusConfig[clusterName] || {};
190+
if (
191+
currentClusterConfig.address !== config.prometheusEndpoint ||
192+
!currentClusterConfig.isMetricsEnabled ||
193+
currentClusterConfig.autoDetect !== false
194+
) {
195+
newPrometheusConfig[clusterName] = {
196+
...currentClusterConfig,
197+
isMetricsEnabled: true,
198+
address: config.prometheusEndpoint,
199+
autoDetect: false,
200+
};
201+
hasChanges = true;
202+
}
203+
});
204+
205+
if (hasChanges) {
206+
dispatch(
207+
setPluginConfig({
208+
configKey: 'prometheus',
209+
payload: newPrometheusConfig,
210+
})
211+
);
212+
}
213+
}
214+
181215
return configToStore;
182216
});
183217
};

frontend/src/redux/configSlice.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { createSlice } from '@reduxjs/toolkit';
1919
import type { Cluster } from '../lib/k8s/cluster';
2020

2121
export interface ConfigState {
22+
prometheusEndpoint?: string;
2223
/**
2324
* Clusters is a map of cluster names to cluster objects.
2425
* Null indicates that the clusters have not been loaded yet.
@@ -89,8 +90,14 @@ const configSlice = createSlice({
8990
* @param state - The current state.
9091
* @param action - The payload action containing the config.
9192
*/
92-
setConfig(state, action: PayloadAction<{ clusters: ConfigState['clusters'] }>) {
93+
setConfig(
94+
state,
95+
action: PayloadAction<{ clusters: ConfigState['clusters']; prometheusEndpoint?: string }>
96+
) {
9397
state.clusters = action.payload.clusters;
98+
if (action.payload.prometheusEndpoint) {
99+
state.prometheusEndpoint = action.payload.prometheusEndpoint;
100+
}
94101
},
95102
/**
96103
* Save the config. To both the store, and localStorage.

0 commit comments

Comments
 (0)