diff --git a/x-pack/plugins/snapshot_restore/public/application/constants/index.ts b/x-pack/plugins/snapshot_restore/public/application/constants/index.ts index 830af3c77f769..7ca0e3181aea0 100644 --- a/x-pack/plugins/snapshot_restore/public/application/constants/index.ts +++ b/x-pack/plugins/snapshot_restore/public/application/constants/index.ts @@ -19,6 +19,12 @@ export enum SNAPSHOT_STATE { PARTIAL = 'PARTIAL', } +export enum SLM_STATE { + RUNNING = 'RUNNING', + STOPPING = 'STOPPING', + STOPPED = 'STOPPED', +} + const INDEX_SETTING_SUGGESTIONS: string[] = [ 'index.number_of_shards', 'index.shard.check_on_startup', diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx index aa7a35bb2c0b2..d4be83fe633c0 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx @@ -25,13 +25,18 @@ import { SlmPolicy } from '../../../../../common/types'; import { APP_SLM_CLUSTER_PRIVILEGES } from '../../../../../common'; import { BASE_PATH, UIM_POLICY_LIST_LOAD } from '../../../constants'; import { useDecodedParams } from '../../../lib'; -import { useLoadPolicies, useLoadRetentionSettings } from '../../../services/http'; +import { + useLoadPolicies, + useLoadRetentionSettings, + useLoadSlmStatus, +} from '../../../services/http'; import { linkToAddPolicy, linkToPolicy } from '../../../services/navigation'; import { useAppContext, useServices } from '../../../app_context'; import { PolicyDetails } from './policy_details'; import { PolicyTable } from './policy_table'; import { PolicyRetentionSchedule } from './policy_retention_schedule'; +import { SlmStatus } from './slm_status'; interface MatchParams { policyName?: SlmPolicy['name']; @@ -61,6 +66,8 @@ export const PolicyList: React.FunctionComponent { return linkToPolicy(newPolicyName); }; @@ -190,6 +197,8 @@ export const PolicyList: React.FunctionComponent ) : null} + + = ({ status }) => { + const { i18n } = useServices(); + + const statusMap: any = { + [SLM_STATE.RUNNING]: { + icon: , + label: i18n.translate('xpack.snapshotRestore.slmstatus.runninglable', { + defaultMessage: 'Running', + }), + }, + [SLM_STATE.STOPPING]: { + icon: , + label: i18n.translate('xpack.snapshotRestore.slmstatus.stoppinglable', { + defaultMessage: 'Stopping', + }), + }, + [SLM_STATE.STOPPED]: { + icon: , + label: i18n.translate('xpack.snapshotRestore.slmstatus.stoppedlable', { + defaultMessage: 'Stopped', + }), + }, + }; + + if (!statusMap[status]) { + // Returns empty if no status + return <>; + } + + const { icon, label } = statusMap[status]; + + return ( + <> + + + + + + + {icon} + {label} + + ), + }} + /> + + + + + + + + ); +}; diff --git a/x-pack/plugins/snapshot_restore/public/application/services/http/policy_requests.ts b/x-pack/plugins/snapshot_restore/public/application/services/http/policy_requests.ts index f4e8abc34e993..945ceff724aef 100644 --- a/x-pack/plugins/snapshot_restore/public/application/services/http/policy_requests.ts +++ b/x-pack/plugins/snapshot_restore/public/application/services/http/policy_requests.ts @@ -131,3 +131,10 @@ export const executeRetention = async () => { uiMetricService.trackUiMetric(UIM_RETENTION_EXECUTE); return result; }; + +export const useLoadSlmStatus = () => { + return useRequest({ + path: `${API_BASE_PATH}policies/slm_status`, + method: 'get', + }); +}; diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts b/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts index 51bdf96361a24..9f948d0d2524a 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts @@ -304,4 +304,20 @@ export function registerPolicyRoutes({ return res.ok({ body: response }); }) ); + + // Get snapshot lifecycle management status + router.get( + { path: addBasePath('policies/slm_status'), validate: false }, + license.guardApiRoute(async (ctx, req, res) => { + const { client: clusterClient } = (await ctx.core).elasticsearch; + + try { + const response = await clusterClient.asCurrentUser.slm.getStatus(); + + return res.ok({ body: response }); + } catch (e) { + return handleEsError({ error: e, response: res }); + } + }) + ); }