Skip to content

Commit e9d77d5

Browse files
feature: fix all remaining locations where tenancy is used within alerts
1 parent 3d11da5 commit e9d77d5

9 files changed

Lines changed: 66 additions & 37 deletions

File tree

web/src/components/Incidents/IncidentsPage.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ import IncidentFilterToolbarItem, {
6565
useStateOptions,
6666
} from './ToolbarItemFilter';
6767
import { MonitoringProvider } from '../../contexts/MonitoringContext';
68-
import { ALL_NAMESPACES_KEY } from '../utils';
6968
import { isEmpty } from 'lodash-es';
7069
import { DataTestIDs } from '../data-test';
7170
import { DocumentTitle } from '@openshift-console/dynamic-plugin-sdk';
@@ -75,7 +74,7 @@ const IncidentsPage = () => {
7574
const dispatch = useDispatch();
7675
const location = useLocation();
7776
const urlParams = useMemo(() => parseUrlParams(location.search), [location.search]);
78-
const { rules } = useAlerts({ overrideNamespace: ALL_NAMESPACES_KEY });
77+
const { rules } = useAlerts({ dontUseTenancy: true });
7978
const { theme } = usePatternFlyTheme();
8079
// loading states
8180
const [incidentsAreLoading, setIncidentsAreLoading] = useState(true);

web/src/components/alerting/AlertsPage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ import useSelectedFilters from './useSelectedFilters';
3232
import { MonitoringProvider } from '../../contexts/MonitoringContext';
3333
import { useAlerts } from '../../hooks/useAlerts';
3434
import { AccessDenied } from '../console/console-shared/src/components/empty-state/AccessDenied';
35+
import { useMonitoring } from '../../hooks/useMonitoring';
3536

3637
const AlertsPage_: FC = () => {
38+
const { useAlertsTenancy } = useMonitoring();
3739
const { t } = useTranslation(process.env.I18N_NAMESPACE);
3840
const [namespace] = useActiveNamespace();
3941
const { defaultAlertTenant, perspective } = usePerspective();
@@ -104,7 +106,7 @@ const AlertsPage_: FC = () => {
104106
fuzzyCaseInsensitive(clusterName, alert.labels?.cluster),
105107
type: 'alert-cluster',
106108
} as RowFilter);
107-
} else if (namespace && namespace !== ALL_NAMESPACES_KEY) {
109+
} else if (useAlertsTenancy && namespace && namespace !== ALL_NAMESPACES_KEY) {
108110
rowFilters = rowFilters.filter((filter) => filter.type !== 'alert-source');
109111
}
110112

web/src/components/alerting/SilenceCreatePage.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import { SilenceForm } from './SilenceForm';
55
import { MonitoringProvider } from '../../contexts/MonitoringContext';
66
import { ALL_NAMESPACES_KEY } from '../utils';
77
import { useQueryNamespace } from '../hooks/useQueryNamespace';
8+
import { useMonitoring } from '../../hooks/useMonitoring';
89

9-
const CreateSilencePage = ({ isNamespaced }: { isNamespaced: boolean }) => {
10+
const CreateSilencePage = ({ allowNamespace }: { allowNamespace: boolean }) => {
11+
const { namespace } = useQueryNamespace();
12+
const { useAlertsTenancy } = useMonitoring();
1013
const { t } = useTranslation(process.env.I18N_NAMESPACE);
1114

1215
const matchers = _.map(getAllQueryArguments(), (value, name) => ({
@@ -15,6 +18,8 @@ const CreateSilencePage = ({ isNamespaced }: { isNamespaced: boolean }) => {
1518
isRegex: false,
1619
}));
1720

21+
const isNamespaced = allowNamespace && useAlertsTenancy && namespace !== ALL_NAMESPACES_KEY;
22+
1823
return _.isEmpty(matchers) ? (
1924
<SilenceForm defaults={{}} title={t('Create silence')} isNamespaced={isNamespaced} />
2025
) : (
@@ -23,11 +28,9 @@ const CreateSilencePage = ({ isNamespaced }: { isNamespaced: boolean }) => {
2328
};
2429

2530
export const MpCmoCreateSilencePage = () => {
26-
const { namespace } = useQueryNamespace();
27-
2831
return (
2932
<MonitoringProvider monitoringContext={{ plugin: 'monitoring-plugin', prometheus: 'cmo' }}>
30-
<CreateSilencePage isNamespaced={namespace !== ALL_NAMESPACES_KEY} />
33+
<CreateSilencePage allowNamespace={true} />
3134
</MonitoringProvider>
3235
);
3336
};
@@ -37,7 +40,7 @@ export const McpAcmCreateSilencePage = () => {
3740
<MonitoringProvider
3841
monitoringContext={{ plugin: 'monitoring-console-plugin', prometheus: 'acm' }}
3942
>
40-
<CreateSilencePage isNamespaced={false} />
43+
<CreateSilencePage allowNamespace={false} />
4144
</MonitoringProvider>
4245
);
4346
};

web/src/components/alerting/SilenceForm.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ const NegativeMatcherHelp = () => {
134134
const SilenceForm_: FC<SilenceFormProps> = ({ defaults, Info, title, isNamespaced }) => {
135135
const { t } = useTranslation(process.env.I18N_NAMESPACE);
136136
const { namespace } = useQueryNamespace();
137-
const { prometheus } = useMonitoring();
137+
const { prometheus, useAlertsTenancy } = useMonitoring();
138138
const navigate = useNavigate();
139139

140140
const durations = useMemo(() => {
@@ -248,7 +248,11 @@ const SilenceForm_: FC<SilenceFormProps> = ({ defaults, Info, title, isNamespace
248248
return;
249249
}
250250

251-
const url = getAlertmanagerSilencesUrl({ prometheus, namespace });
251+
const url = getAlertmanagerSilencesUrl({
252+
prometheus,
253+
namespace,
254+
useTenancyPath: useAlertsTenancy,
255+
});
252256
if (!url) {
253257
setError('Alertmanager URL not set');
254258
return;
@@ -279,7 +283,10 @@ const SilenceForm_: FC<SilenceFormProps> = ({ defaults, Info, title, isNamespace
279283
};
280284

281285
consoleFetchJSON
282-
.post(getAlertmanagerSilencesUrl({ prometheus, namespace }), body)
286+
.post(
287+
getAlertmanagerSilencesUrl({ prometheus, namespace, useTenancyPath: useAlertsTenancy }),
288+
body,
289+
)
283290
.then(({ silenceID }) => {
284291
setError(undefined);
285292
refetchSilencesAndAlerts();

web/src/components/dashboards/legacy/graph.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const Graph: FC<Props> = ({
3535
onDataChange,
3636
}) => {
3737
const dispatch = useDispatch();
38-
const { plugin } = useMonitoring();
38+
const { plugin, useMetricsTenancy } = useMonitoring();
3939
const endTime = useSelector(
4040
(state: MonitoringState) => getObserveState(plugin, state).dashboards.endTime,
4141
);
@@ -67,6 +67,7 @@ const Graph: FC<Props> = ({
6767
timespan={timespan}
6868
units={units as GraphUnits}
6969
onDataChange={onDataChange}
70+
useTenancy={useMetricsTenancy}
7071
isPlain
7172
/>
7273
);

web/src/components/hooks/useQueryNamespace.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ export const useQueryNamespace = () => {
1313
if (queryNamespace && activeNamespace !== queryNamespace) {
1414
setActiveNamespace(queryNamespace);
1515
}
16-
if (!queryNamespace) {
17-
setQueryNamespace(activeNamespace);
18-
}
1916
}, [queryNamespace, activeNamespace, setActiveNamespace, setQueryNamespace]);
2017

2118
return {

web/src/components/utils.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,21 @@ export const buildPrometheusUrl = ({
246246
prometheusUrlProps: PrometheusURLProps;
247247
basePath: string;
248248
}): string | null => {
249+
if (
250+
basePath !== PROMETHEUS_TENANCY_BASE_PATH ||
251+
prometheusUrlProps.namespace === ALL_NAMESPACES_KEY
252+
) {
253+
prometheusUrlProps.namespace = undefined;
254+
}
249255
if (prometheusUrlProps.endpoint !== PrometheusEndpoint.RULES && !prometheusUrlProps.query) {
250256
// Empty query provided, skipping API call
251257
return null;
252258
}
253259

254260
const params = getSearchParams(prometheusUrlProps);
255-
return `${basePath}/${prometheusUrlProps.endpoint}?${params.toString()}`;
261+
return `${basePath}/${prometheusUrlProps.endpoint}${
262+
params.size > 0 ? '?' + params.toString() : ''
263+
}`;
256264
};
257265

258266
type PrometheusURLProps = {
@@ -267,14 +275,16 @@ type PrometheusURLProps = {
267275

268276
export const getAlertmanagerSilencesUrl = ({
269277
prometheus,
278+
useTenancyPath,
270279
namespace,
271280
}: {
272281
prometheus: Prometheus;
282+
useTenancyPath: boolean;
273283
namespace?: string;
274284
}) => {
275285
if (prometheus === 'acm') {
276286
return `${ALERTMANAGER_PROXY_PATH}/api/v2/silences`;
277-
} else if (namespace && namespace !== ALL_NAMESPACES_KEY) {
287+
} else if (useTenancyPath && namespace && namespace !== ALL_NAMESPACES_KEY) {
278288
return `${ALERTMANAGER_TENANCY_BASE_PATH}/api/v2/silences?namespace=${namespace}`;
279289
} else {
280290
return `${ALERTMANAGER_BASE_PATH}/api/v2/silences`;

web/src/hooks/useAlerts.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,24 @@ import {
2626
getAdditionalSources,
2727
} from '../components/alerting/AlertUtils';
2828
import { MonitoringState } from '../store/store';
29-
import { getObserveState, usePerspective } from '../components/hooks/usePerspective';
29+
import { getObserveState } from '../components/hooks/usePerspective';
3030

3131
const POLLING_INTERVAL_MS = 15 * 1000; // 15 seconds
3232

33-
export const useAlerts = (props?: { overrideNamespace?: string }) => {
33+
export const useAlerts = (props?: { dontUseTenancy?: boolean }) => {
3434
// Retrieve external information which dictates which alerts to load and use
3535
const { plugin } = useMonitoring();
3636
const [namespace] = useActiveNamespace();
37-
const { prometheus, useAlertsTenancy } = useMonitoring();
38-
const { perspective } = usePerspective();
39-
const overriddenNamespace = props?.overrideNamespace ? props.overrideNamespace : namespace;
37+
const { prometheus, useAlertsTenancy, accessCheckLoading } = useMonitoring();
38+
const overriddenNamespace =
39+
props?.dontUseTenancy || !useAlertsTenancy ? ALL_NAMESPACES_KEY : namespace;
4040

4141
// Start polling for alerts, rules, and silences
4242
const { trigger } = useAlertsPoller({
4343
namespace: overriddenNamespace,
4444
prometheus,
4545
useAlertsTenancy,
46+
accessCheckLoading,
4647
});
4748

4849
// Retrieve alerts, rules and silences from the store, which is populated in the poller
@@ -97,16 +98,6 @@ export const useAlerts = (props?: { overrideNamespace?: string }) => {
9798
return clusterArray.sort();
9899
}, [silences]);
99100

100-
// When a user with cluster scoped alerts retrieves alerts from the tenancy API endpoint
101-
// the API will still retrun ALL alerts, not just the ones which are available at that tenant
102-
// As such we manually filter down the alerts on the frontend
103-
const namespacedAlerts = useMemo(() => {
104-
if (perspective === 'acm' || namespace === ALL_NAMESPACES_KEY) {
105-
return alerts;
106-
}
107-
return alerts?.filter((alert) => alert.labels?.namespace === namespace);
108-
}, [alerts, perspective, namespace]);
109-
110101
return {
111102
trigger,
112103
additionalAlertSourceLabels,
@@ -116,18 +107,20 @@ export const useAlerts = (props?: { overrideNamespace?: string }) => {
116107
rulesAlertLoading,
117108
rules,
118109
silences,
119-
alerts: namespacedAlerts,
110+
alerts,
120111
};
121112
};
122113

123114
const useAlertsPoller = ({
124115
namespace,
125116
prometheus,
126117
useAlertsTenancy,
118+
accessCheckLoading,
127119
}: {
128120
namespace?: string;
129121
prometheus: Prometheus;
130122
useAlertsTenancy: boolean;
123+
accessCheckLoading: boolean;
131124
}) => {
132125
const dispatch = useDispatch();
133126
const [customExtensions] =
@@ -148,14 +141,27 @@ const useAlertsPoller = ({
148141
prometheusUrlProps: { endpoint: PrometheusEndpoint.RULES, namespace },
149142
basePath: getPrometheusBasePath({ prometheus, useTenancyPath: useAlertsTenancy }),
150143
});
151-
const silencesUrl = getAlertmanagerSilencesUrl({ prometheus, namespace });
144+
const silencesUrl = getAlertmanagerSilencesUrl({
145+
prometheus,
146+
namespace,
147+
useTenancyPath: useAlertsTenancy,
148+
});
152149

153150
const fetchDispatch = () =>
154-
dispatch(fetchAlertingData(prometheus, namespace, rulesUrl, alertsSource, silencesUrl));
151+
dispatch(
152+
fetchAlertingData(
153+
prometheus,
154+
namespace,
155+
rulesUrl,
156+
alertsSource,
157+
silencesUrl,
158+
!accessCheckLoading, // Wait to poll until we know which endpoint to use
159+
),
160+
);
155161

156162
const dependencies = useMemo(
157-
() => [namespace, rulesUrl, silencesUrl],
158-
[namespace, rulesUrl, silencesUrl],
163+
() => [namespace, rulesUrl, silencesUrl, useAlertsTenancy, accessCheckLoading],
164+
[namespace, rulesUrl, silencesUrl, useAlertsTenancy, accessCheckLoading],
159165
);
160166

161167
usePoll(fetchDispatch, POLLING_INTERVAL_MS, dependencies);

web/src/store/thunks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ export const fetchAlertingData =
2222
rulesUrl: string,
2323
alertsSource: any,
2424
silencesUrl: string,
25+
active: boolean,
2526
): ThunkAction<void, RootState, unknown, Action<string>> =>
2627
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2728
async (dispatch, getState) => {
29+
if (!active) {
30+
return;
31+
}
2832
dispatch(alertingSetLoading(prometheus, namespace));
2933

3034
const [rulesResponse, silencesResponse] = await Promise.allSettled([

0 commit comments

Comments
 (0)