diff --git a/graylog2-web-interface/src/components/datanode/DataNodeList/DataNodeActions.tsx b/graylog2-web-interface/src/components/datanode/DataNodeList/DataNodeActions.tsx
index 56aa564849648..5c726e8fd4700 100644
--- a/graylog2-web-interface/src/components/datanode/DataNodeList/DataNodeActions.tsx
+++ b/graylog2-web-interface/src/components/datanode/DataNodeList/DataNodeActions.tsx
@@ -26,7 +26,7 @@ import OverlayDropdownButton from 'components/common/OverlayDropdownButton';
import { MORE_ACTIONS_TITLE, MORE_ACTIONS_HOVER_TITLE } from 'components/common/EntityDataTable/Constants';
import Routes from 'routing/Routes';
-import { rejoinDataNode, removeDataNode } from '../hooks/useDataNodes';
+import { rejoinDataNode, removeDataNode, renewDatanodeCertificate } from '../hooks/useDataNodes';
type Props = {
dataNode: DataNode,
@@ -34,6 +34,7 @@ type Props = {
const DIALOG_TYPES = {
REJOIN: 'rejoin',
REMOVE: 'remove',
+ RENEW_CERT: 'renew',
};
const DIALOG_TEXT = {
[DIALOG_TYPES.REJOIN]: {
@@ -101,7 +102,7 @@ const DataNodeActions = ({ dataNode }: Props) => {
disabled={false}
dropdownZIndex={1000}>
-
+
diff --git a/graylog2-web-interface/src/components/datanode/hooks/useDataNodes.ts b/graylog2-web-interface/src/components/datanode/hooks/useDataNodes.ts
index a30275cad4457..e924d573ee622 100644
--- a/graylog2-web-interface/src/components/datanode/hooks/useDataNodes.ts
+++ b/graylog2-web-interface/src/components/datanode/hooks/useDataNodes.ts
@@ -19,7 +19,7 @@ import { useQuery } from '@tanstack/react-query';
import { qualifyUrl } from 'util/URLUtils';
import PaginationURL from 'util/PaginationURL';
import type { DataNode } from 'preflight/types';
-import UserNotification from 'preflight/util/UserNotification';
+import UserNotification from 'util/UserNotification';
import fetch from 'logic/rest/FetchProvider';
import type { Attribute, PaginatedListJSON, SearchParams } from 'stores/PaginationTypes';
@@ -47,6 +47,14 @@ type Options = {
enabled: boolean,
}
+export const renewDatanodeCertificate = (nodeId: string) => fetch('POST', qualifyUrl(`/certrenewal/${nodeId}`))
+ .then(() => {
+ UserNotification.success('Certificate renewed successfully');
+ })
+ .catch((error) => {
+ UserNotification.error(`Certificate renewal failed with error: ${error}`);
+ });
+
const fetchDataNodes = async (params?: SearchParams) => {
const url = PaginationURL('/system/cluster/datanodes', params?.page, params?.pageSize, params?.query, { sort: params?.sort?.attributeId, order: params?.sort?.direction });
diff --git a/graylog2-web-interface/src/pages/DataNodePage.tsx b/graylog2-web-interface/src/pages/DataNodePage.tsx
index 9e79b94fd2cd7..3fdfbc0d1bc25 100644
--- a/graylog2-web-interface/src/pages/DataNodePage.tsx
+++ b/graylog2-web-interface/src/pages/DataNodePage.tsx
@@ -27,6 +27,7 @@ import type { SearchParams } from 'stores/PaginationTypes';
const StyledHorizontalDl = styled.dl(({ theme }) => css`
margin: ${theme.spacings.md} 0;
+
> dt {
clear: left;
float: left;
@@ -36,6 +37,7 @@ const StyledHorizontalDl = styled.dl(({ theme }) => css`
white-space: nowrap;
width: 150px;
}
+
> *:not(dt) {
margin-bottom: ${theme.spacings.md};
margin-left: 140px;
@@ -85,7 +87,7 @@ const DataNodePage = () => {
title={datanode.data_node_status}
aria-label={datanode.data_node_status}
role="button">
- {datanode.status || 'N/A'}
+ {datanode.data_node_status || 'N/A'}