Skip to content

Commit bed75df

Browse files
committed
MK8S-197 - Add PrometheusAuthProvider
1 parent 0c90d1a commit bed75df

File tree

4 files changed

+89
-6
lines changed

4 files changed

+89
-6
lines changed

ui/src/FederableApp.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { applyMiddleware, compose, createStore, Store } from 'redux';
66
import createSagaMiddleware from 'redux-saga';
77
import 'regenerator-runtime/runtime';
88
import App from './containers/App';
9+
import PrometheusAuthProvider from './containers/PrometheusAuthProvider';
910
import { authErrorAction } from './ducks/app/authError';
1011
import { setApiConfigAction } from './ducks/config';
1112
import { setHistory as setReduxHistory } from './ducks/history';
@@ -125,11 +126,13 @@ export default function FederableApp(props: FederatedAppProps) {
125126
>
126127
<Provider store={store}>
127128
<AppConfigProvider>
128-
<ToastProvider>
129-
<RouterWithBaseName>
130-
<App />
131-
</RouterWithBaseName>
132-
</ToastProvider>
129+
<PrometheusAuthProvider>
130+
<ToastProvider>
131+
<RouterWithBaseName>
132+
<App />
133+
</RouterWithBaseName>
134+
</ToastProvider>
135+
</PrometheusAuthProvider>
133136
</AppConfigProvider>
134137
</Provider>
135138
</ShellHooksProvider>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Loader } from '@scality/core-ui';
2+
import { ReactNode, useEffect, useState } from 'react';
3+
import YAML from 'yaml';
4+
import { useAuth } from './PrivateRoute';
5+
import { useTypedSelector } from '../hooks';
6+
import { setHeaders } from '../services/prometheus/api';
7+
8+
type PrometheusConfig = {
9+
apiVersion: string;
10+
kind: string;
11+
spec: {
12+
config?: {
13+
enable_oidc_authentication?: boolean;
14+
};
15+
};
16+
};
17+
18+
async function fetchPrometheusOidcEnabled(
19+
k8sApiUrl: string,
20+
token: string,
21+
): Promise<boolean> {
22+
try {
23+
const response = await fetch(
24+
`${k8sApiUrl}/api/v1/namespaces/metalk8s-monitoring/configmaps/metalk8s-prometheus-config`,
25+
{
26+
method: 'GET',
27+
headers: {
28+
'Content-Type': 'application/json',
29+
Authorization: `Bearer ${token}`,
30+
},
31+
},
32+
);
33+
34+
if (response.status !== 200) {
35+
return false;
36+
}
37+
38+
const configMap = await response.json();
39+
const rawConfig = configMap.data?.['config.yaml'] || '';
40+
const config: PrometheusConfig = YAML.parse(rawConfig);
41+
return config.spec?.config?.enable_oidc_authentication === true;
42+
} catch (error) {
43+
console.error('Failed to fetch Prometheus OIDC config:', error);
44+
return false;
45+
}
46+
}
47+
48+
export default function PrometheusAuthProvider({
49+
children,
50+
}: {
51+
children: ReactNode;
52+
}) {
53+
const { userData } = useAuth();
54+
const api = useTypedSelector((state) => state.config.api);
55+
const [oidcEnabled, setOidcEnabled] = useState<boolean | null>(null);
56+
57+
// Fetch the OIDC config and set headers before rendering children
58+
useEffect(() => {
59+
if (api?.url && userData?.token) {
60+
fetchPrometheusOidcEnabled(api.url, userData.token).then((enabled) => {
61+
if (enabled) {
62+
setHeaders({ Authorization: `Bearer ${userData.token}` });
63+
}
64+
setOidcEnabled(enabled);
65+
});
66+
}
67+
}, [api?.url, userData?.token]);
68+
69+
if (oidcEnabled === null) {
70+
return <Loader size="massive" centered={true} aria-label="loading" />;
71+
}
72+
73+
return <>{children}</>;
74+
}

ui/src/services/ApiClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class ApiClient {
1212

1313
setHeaders = (headers) => {
1414
// @ts-expect-error - FIXME when you are working on it
15-
this.headers = headers;
15+
this.headers = { ...this.headers, ...headers };
1616
};
1717

1818
async get(endpoint, params = {}, opts = {}) {

ui/src/services/prometheus/api.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ export function initialize(apiUrl: string) {
5151
prometheusApiClient = new ApiClient({ apiUrl });
5252
}
5353

54+
export function setHeaders(headers: Record<string, string>) {
55+
if (prometheusApiClient) {
56+
prometheusApiClient.setHeaders(headers);
57+
}
58+
}
59+
5460
export function getAlerts() {
5561
if (prometheusApiClient) {
5662
return prometheusApiClient.get('/api/v1/alerts');

0 commit comments

Comments
 (0)