From edf1e4079be4ada1471a6eee1fb3454a63adb8e9 Mon Sep 17 00:00:00 2001 From: Sandeep Kumawat <2025sandeepkumawat@gmail.com> Date: Tue, 16 Jul 2024 04:54:25 +0530 Subject: [PATCH] Add MDS support to snapshot pages (#1084) Signed-off-by: Sandeep Kumawat Co-authored-by: Sandeep Kumawat --- .../CreateSnapshotPolicy.tsx | 74 ++++++++- public/pages/Main/Main.tsx | 23 +++ .../CreateRepositoryFlyout.tsx | 35 +++- .../containers/Repositories/Repositories.tsx | 33 +++- .../SnapshotPolicies/SnapshotPolicies.tsx | 37 ++++- .../SnapshotPolicyDetails.tsx | 18 ++- .../CreateSnapshotFlyout.tsx | 33 +++- .../RestoreSnapshotFlyout.tsx | 151 ++++++++++-------- .../SnapshotFlyout/SnapshotFlyout.tsx | 23 ++- .../containers/Snapshots/Snapshots.tsx | 32 +++- public/services/SnapshotManagementService.ts | 77 ++++++--- server/plugin.ts | 4 +- server/routes/snapshotManagement.ts | 53 +++++- server/services/SnapshotManagementService.ts | 95 ++++++----- 14 files changed, 508 insertions(+), 180 deletions(-) diff --git a/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx b/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx index aa9674ae8..02c73fac8 100644 --- a/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx +++ b/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx @@ -27,7 +27,7 @@ import { EuiButtonIcon, EuiLink, } from "@elastic/eui"; -import React, { ChangeEvent, Component } from "react"; +import React, { ChangeEvent, Component, useContext } from "react"; import { RouteComponentProps } from "react-router-dom"; import { CoreServicesContext } from "../../../../components/core_services"; import { CatRepository, CreateRepositoryBody, CreateRepositorySettings, FeatureChannelList } from "../../../../../server/models/interfaces"; @@ -52,15 +52,18 @@ import SnapshotIndicesRepoInput from "../../components/SnapshotIndicesRepoInput" import CronSchedule from "../../components/CronSchedule"; import SnapshotAdvancedSettings from "../../components/SnapshotAdvancedSettings"; import Notification from "../../components/Notification"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; +import { useUpdateUrlWithDataSourceProperties } from "../../../../components/MDSEnabledComponent"; -interface CreateSMPolicyProps extends RouteComponentProps { +interface CreateSMPolicyProps extends RouteComponentProps, DataSourceMenuProperties { snapshotManagementService: SnapshotManagementService; isEdit: boolean; notificationService: NotificationService; indexService: IndexService; } -interface CreateSMPolicyState { +interface CreateSMPolicyState extends DataSourceMenuProperties { policy: SMPolicy; policyId: string; policySeqNo: number | undefined; @@ -96,13 +99,14 @@ interface CreateSMPolicyState { timezoneError: string; } -export default class CreateSnapshotPolicy extends Component { +export class CreateSnapshotPolicy extends MDSEnabledComponent { static contextType = CoreServicesContext; constructor(props: CreateSMPolicyProps) { super(props); this.state = { + ...this.state, policy: getDefaultSMPolicy(), policyId: "", policySeqNo: undefined, @@ -160,11 +164,67 @@ export default class CreateSnapshotPolicy extends Component => { try { const { snapshotManagementService } = this.props; @@ -877,3 +937,9 @@ export default class CreateSnapshotPolicy extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + useUpdateUrlWithDataSourceProperties(); + return ; +} diff --git a/public/pages/Main/Main.tsx b/public/pages/Main/Main.tsx index e56e4460d..b36430bc9 100644 --- a/public/pages/Main/Main.tsx +++ b/public/pages/Main/Main.tsx @@ -177,6 +177,16 @@ const dataSourceEnabledPaths: string[] = [ ROUTES.CREATE_TRANSFORM, ROUTES.EDIT_TRANSFORM, ROUTES.TRANSFORM_DETAILS, + ROUTES.SNAPSHOT_POLICIES, + ROUTES.SNAPSHOT_POLICY_DETAILS, + ROUTES.CREATE_SNAPSHOT_POLICY, + ROUTES.EDIT_SNAPSHOT_POLICY, + ROUTES.SNAPSHOTS, + ROUTES.CREATE_SNAPSHOT, + ROUTES.EDIT_SNAPSHOT, + ROUTES.REPOSITORIES, + ROUTES.CREATE_REPOSITORY, + ROUTES.EDIT_REPOSITORY, ]; export default class Main extends Component { @@ -241,6 +251,7 @@ export default class Main extends Component { services.notificationService = new NotificationService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); services.rollupService = new RollupService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); services.transformService = new TransformService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); + services.snapshotManagementService = new SnapshotManagementService(http, this.state.dataSourceId, this.props.multiDataSourceEnabled); } return services; } @@ -447,6 +458,8 @@ export default class Main extends Component { ROUTES.ROLLUP_DETAILS, ROUTES.TRANSFORM_DETAILS, ROUTES.EDIT_TRANSFORM, + ROUTES.EDIT_SNAPSHOT_POLICY, + ROUTES.SNAPSHOT_POLICY_DETAILS, ]} render={() => ( { ROUTES.CHANGE_POLICY, ROUTES.ROLLUPS, ROUTES.TRANSFORMS, + ROUTES.SNAPSHOT_POLICIES, + ROUTES.SNAPSHOT_POLICY_DETAILS, + ROUTES.CREATE_SNAPSHOT_POLICY, + ROUTES.EDIT_SNAPSHOT_POLICY, + ROUTES.SNAPSHOTS, + ROUTES.CREATE_SNAPSHOT, + ROUTES.EDIT_SNAPSHOT, + ROUTES.REPOSITORIES, + ROUTES.CREATE_REPOSITORY, + ROUTES.EDIT_REPOSITORY, ]} render={() => ( void; createRepo: (repoName: string, repoType: string, settings: CreateRepositorySettings) => void; } -interface CreateRepositoryState { +interface CreateRepositoryState extends DataSourceMenuProperties { repoName: string; location: string; // repoTypeOptions: EuiComboBoxOptionOption[]; @@ -59,13 +61,14 @@ interface CreateRepositoryState { locationError: string; } -export default class CreateRepositoryFlyout extends Component { +export class CreateRepositoryFlyout extends MDSEnabledComponent { static contextType = CoreServicesContext; constructor(props: CreateRepositoryProps) { super(props); this.state = { + ...this.state, repoName: "", location: "", // repoTypeOptions: [], @@ -85,6 +88,25 @@ export default class CreateRepositoryFlyout extends Component { const { service } = this.props; try { @@ -291,3 +313,8 @@ export default class CreateRepositoryFlyout extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + return ; +} diff --git a/public/pages/Repositories/containers/Repositories/Repositories.tsx b/public/pages/Repositories/containers/Repositories/Repositories.tsx index 12986972c..bebe19e59 100644 --- a/public/pages/Repositories/containers/Repositories/Repositories.tsx +++ b/public/pages/Repositories/containers/Repositories/Repositories.tsx @@ -13,7 +13,7 @@ import { EuiTextColor, } from "@elastic/eui"; import { getErrorMessage } from "../../../../utils/helpers"; -import React, { Component } from "react"; +import React, { Component, useContext } from "react"; import { RouteComponentProps } from "react-router-dom"; import { CatRepository, CreateRepositoryBody, CreateRepositorySettings } from "../../../../../server/models/interfaces"; import { CoreServicesContext } from "../../../../components/core_services"; @@ -24,12 +24,15 @@ import { FieldValueSelectionFilterConfigType } from "@elastic/eui/src/components import { BREADCRUMBS } from "../../../../utils/constants"; import DeleteModal from "../../components/DeleteModal"; import { truncateSpan } from "../../../Snapshots/helper"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; +import { useUpdateUrlWithDataSourceProperties } from "../../../../components/MDSEnabledComponent"; -interface RepositoriesProps extends RouteComponentProps { +interface RepositoriesProps extends RouteComponentProps, DataSourceMenuProperties { snapshotManagementService: SnapshotManagementService; } -interface RepositoriesState { +interface RepositoriesState extends DataSourceMenuProperties { repositories: CatRepository[]; loading: boolean; selectedItems: CatRepository[]; @@ -43,7 +46,7 @@ interface RepositoriesState { isDeleteModalVisible: boolean; } -export default class Repositories extends Component { +export class Repositories extends MDSEnabledComponent { static contextType = CoreServicesContext; columns: EuiTableFieldDataColumnType[]; @@ -51,6 +54,7 @@ export default class Repositories extends Component { this.setState({ loading: true }); @@ -177,7 +195,6 @@ export default class Repositories extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + useUpdateUrlWithDataSourceProperties(); + return ; +} diff --git a/public/pages/SnapshotPolicies/containers/SnapshotPolicies/SnapshotPolicies.tsx b/public/pages/SnapshotPolicies/containers/SnapshotPolicies/SnapshotPolicies.tsx index 68ab334c0..789fb89ab 100644 --- a/public/pages/SnapshotPolicies/containers/SnapshotPolicies/SnapshotPolicies.tsx +++ b/public/pages/SnapshotPolicies/containers/SnapshotPolicies/SnapshotPolicies.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { Component } from "react"; +import React, { Component, useContext } from "react"; import _ from "lodash"; import queryString from "query-string"; import { RouteComponentProps } from "react-router-dom"; @@ -39,12 +39,15 @@ import DeleteModal from "../../../PolicyDetails/components/DeleteModal"; import { OnSearchChangeArgs } from "../../../../models/interfaces"; import { humanCronExpression, parseCronExpression } from "../../../CreateSnapshotPolicy/components/CronSchedule/helper"; import { truncateSpan } from "../../../Snapshots/helper"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; +import { useUpdateUrlWithDataSourceProperties } from "../../../../components/MDSEnabledComponent"; -interface SnapshotPoliciesProps extends RouteComponentProps { +interface SnapshotPoliciesProps extends RouteComponentProps, DataSourceMenuProperties { snapshotManagementService: SnapshotManagementService; } -interface SnapshotPoliciesState { +interface SnapshotPoliciesState extends DataSourceMenuProperties { policies: SMPolicy[]; totalPolicies: number; loadingPolicies: boolean; @@ -66,7 +69,7 @@ interface SnapshotPoliciesState { isDeleteModalVisible: boolean; } -export default class SnapshotPolicies extends Component { +export class SnapshotPolicies extends MDSEnabledComponent { static contextType = CoreServicesContext; columns: EuiTableFieldDataColumnType[]; @@ -75,6 +78,7 @@ export default class SnapshotPolicies extends Component { @@ -472,3 +491,9 @@ export default class SnapshotPolicies extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + useUpdateUrlWithDataSourceProperties(); + return ; +} diff --git a/public/pages/SnapshotPolicyDetails/containers/SnapshotPolicyDetails/SnapshotPolicyDetails.tsx b/public/pages/SnapshotPolicyDetails/containers/SnapshotPolicyDetails/SnapshotPolicyDetails.tsx index 70a75feef..11e7701bb 100644 --- a/public/pages/SnapshotPolicyDetails/containers/SnapshotPolicyDetails/SnapshotPolicyDetails.tsx +++ b/public/pages/SnapshotPolicyDetails/containers/SnapshotPolicyDetails/SnapshotPolicyDetails.tsx @@ -5,7 +5,7 @@ import _ from "lodash"; import { RouteComponentProps } from "react-router-dom"; -import React, { Component } from "react"; +import React, { Component, useContext } from "react"; import queryString from "query-string"; import { EuiAccordion, @@ -36,13 +36,16 @@ import InfoModal from "../../components/InfoModal"; import { getAllowPartial, getIgnoreUnavailabel, getIncludeGlobalState } from "../../../CreateSnapshotPolicy/containers/helper"; import { truncateSpan } from "../../../Snapshots/helper"; import { NotificationConfig } from "../../../../../server/models/interfaces"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; +import { useUpdateUrlWithDataSourceProperties } from "../../../../components/MDSEnabledComponent"; -interface SnapshotPolicyDetailsProps extends RouteComponentProps { +interface SnapshotPolicyDetailsProps extends RouteComponentProps, DataSourceMenuProperties { snapshotManagementService: SnapshotManagementService; notificationService: NotificationService; } -interface SnapshotPolicyDetailsState { +interface SnapshotPolicyDetailsState extends DataSourceMenuProperties { policyId: string; policy: SMPolicy | null; @@ -53,7 +56,7 @@ interface SnapshotPolicyDetailsState { channel: NotificationConfig | null; } -export default class SnapshotPolicyDetails extends Component { +export class SnapshotPolicyDetails extends MDSEnabledComponent { static contextType = CoreServicesContext; columns: EuiTableFieldDataColumnType[]; @@ -61,6 +64,7 @@ export default class SnapshotPolicyDetails extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + useUpdateUrlWithDataSourceProperties(); + return ; +} diff --git a/public/pages/Snapshots/components/CreateSnapshotFlyout/CreateSnapshotFlyout.tsx b/public/pages/Snapshots/components/CreateSnapshotFlyout/CreateSnapshotFlyout.tsx index 4657ad5f6..7e125a81e 100644 --- a/public/pages/Snapshots/components/CreateSnapshotFlyout/CreateSnapshotFlyout.tsx +++ b/public/pages/Snapshots/components/CreateSnapshotFlyout/CreateSnapshotFlyout.tsx @@ -17,7 +17,7 @@ import { } from "@elastic/eui"; import _ from "lodash"; -import React, { Component } from "react"; +import React, { Component, useContext } from "react"; import FlyoutFooter from "../../../VisualCreatePolicy/components/FlyoutFooter"; import { CoreServicesContext } from "../../../../components/core_services"; import { IndexService, SnapshotManagementService } from "../../../../services"; @@ -30,15 +30,17 @@ import SnapshotIndicesRepoInput from "../../../CreateSnapshotPolicy/components/S import { ChangeEvent } from "react"; import { getEmptySnapshot } from "./constants"; import { ERROR_PROMPT } from "../../../CreateSnapshotPolicy/constants"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; -interface CreateSnapshotProps { +interface CreateSnapshotProps extends DataSourceMenuProperties { snapshotManagementService: SnapshotManagementService; indexService: IndexService; onCloseFlyout: () => void; createSnapshot: (snapshotId: string, repository: string, snapshot: Snapshot) => void; } -interface CreateSnapshotState { +interface CreateSnapshotState extends DataSourceMenuProperties { indexOptions: EuiComboBoxOptionOption[]; selectedIndexOptions: EuiComboBoxOptionOption[]; @@ -52,12 +54,13 @@ interface CreateSnapshotState { snapshotIdError: string; } -export default class CreateSnapshotFlyout extends Component { +export class CreateSnapshotFlyout extends MDSEnabledComponent { static contextType = CoreServicesContext; constructor(props: CreateSnapshotProps) { super(props); this.state = { + ...this.state, indexOptions: [], selectedIndexOptions: [], repositories: [], @@ -74,6 +77,23 @@ export default class CreateSnapshotFlyout extends Component { const { createSnapshot } = this.props; const { snapshotId, selectedRepoValue, snapshot } = this.state; @@ -250,3 +270,8 @@ export default class CreateSnapshotFlyout extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + return ; +} diff --git a/public/pages/Snapshots/components/RestoreSnapshotFlyout/RestoreSnapshotFlyout.tsx b/public/pages/Snapshots/components/RestoreSnapshotFlyout/RestoreSnapshotFlyout.tsx index 32528ad2a..491f5660e 100644 --- a/public/pages/Snapshots/components/RestoreSnapshotFlyout/RestoreSnapshotFlyout.tsx +++ b/public/pages/Snapshots/components/RestoreSnapshotFlyout/RestoreSnapshotFlyout.tsx @@ -17,18 +17,18 @@ import { EuiAccordion, EuiCheckbox, EuiCallOut, - EuiText + EuiText, } from "@elastic/eui"; import _ from "lodash"; -import React, { Component, ChangeEvent } from "react"; +import React, { Component, ChangeEvent, useContext } from "react"; import FlyoutFooter from "../../../VisualCreatePolicy/components/FlyoutFooter"; import { CoreServicesContext } from "../../../../components/core_services"; import { IndexService, SnapshotManagementService } from "../../../../services"; import { RESTORE_OPTIONS } from "../../../../models/interfaces"; import { getErrorMessage } from "../../../../utils/helpers"; -import { checkBadJSON, checkBadRegex, checkBadReplacement, checkCustomIgnoreConflict, checkNoSelectedIndices } from "../../helper" -import { browseIndicesCols } from "../../../../utils/constants" -import { ERROR_TOAST_TITLE } from "../../constants" +import { checkBadJSON, checkBadRegex, checkBadReplacement, checkCustomIgnoreConflict, checkNoSelectedIndices } from "../../helper"; +import { browseIndicesCols } from "../../../../utils/constants"; +import { ERROR_TOAST_TITLE } from "../../constants"; import { IndexItem } from "../../../../../models/interfaces"; import { CatRepository, GetSnapshot } from "../../../../../server/models/interfaces"; import CustomLabel from "../../../../components/CustomLabel"; @@ -40,18 +40,20 @@ import RenameInput from "../RenameInput"; import SnapshotIndicesInput from "../SnapshotIndicesInput"; import IndexList from "../IndexList"; import { ERROR_PROMPT } from "../../../CreateSnapshotPolicy/constants"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; -interface RestoreSnapshotProps { +interface RestoreSnapshotProps extends DataSourceMenuProperties { snapshotManagementService: SnapshotManagementService; indexService: IndexService; onCloseFlyout: () => void; - getRestoreTime: (time: number) => void + getRestoreTime: (time: number) => void; restoreSnapshot: (snapshotId: string, repository: string, options: object) => void; snapshotId: string; repository: string; } -interface RestoreSnapshotState { +interface RestoreSnapshotState extends DataSourceMenuProperties { indexOptions: EuiComboBoxOptionOption[]; selectedIndexOptions: EuiComboBoxOptionOption[]; renameIndices: string; @@ -70,17 +72,18 @@ interface RestoreSnapshotState { badPattern: boolean; badRename: boolean; badJSON: boolean; - badIgnore: boolean + badIgnore: boolean; repoError: string; noIndicesSelected: boolean; snapshotIdError: string; } -export default class RestoreSnapshotFlyout extends Component { +export class RestoreSnapshotFlyout extends MDSEnabledComponent { static contextType = CoreServicesContext; constructor(props: RestoreSnapshotProps) { super(props); this.state = { + ...this.state, indexOptions: [], selectedIndexOptions: [], renameIndices: "add_prefix", @@ -110,6 +113,12 @@ export default class RestoreSnapshotFlyout extends Component { const { restoreSnapshot, snapshotId, repository, onCloseFlyout, getRestoreTime } = this.props; const { @@ -156,14 +165,15 @@ export default class RestoreSnapshotFlyout extends Component { @@ -226,11 +236,11 @@ export default class RestoreSnapshotFlyout extends Component - @@ -387,12 +400,17 @@ export default class RestoreSnapshotFlyout extends Component - {status} + + {" "} + {status} + - {snapshot?.indices.length} + + {snapshot?.indices.length} + @@ -408,20 +426,18 @@ export default class RestoreSnapshotFlyout extends Component - { - restoreSpecific && ( - - ) - } + {restoreSpecific && ( + + )} @@ -436,15 +452,14 @@ export default class RestoreSnapshotFlyout extends Component {renameIndices === add_prefix && } - { - renameIndices === rename_indices && ( - - ) - } + {renameIndices === rename_indices && ( + + )} @@ -470,24 +485,22 @@ export default class RestoreSnapshotFlyout extends Component - {snapshot?.failed_shards && -

- You are about to restore a partial snapshot. One or more shards may be missing in this -
- snapshot. Do you want to continue? -

- - Allow restore partial snapshots} - checked={String(_.get(snapshot, partial, false)) == "true"} - onChange={this.onToggle} - /> -
} - + {snapshot?.failed_shards && ( + +

+ You are about to restore a partial snapshot. One or more shards may be missing in this +
+ snapshot. Do you want to continue? +

+ + Allow restore partial snapshots} + checked={String(_.get(snapshot, partial, false)) == "true"} + onChange={this.onToggle} + /> +
+ )}
@@ -497,7 +510,8 @@ export default class RestoreSnapshotFlyout extends Component + disabledAction={!!restoreDisabled} + /> )} @@ -505,3 +519,8 @@ export default class RestoreSnapshotFlyout extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + return ; +} diff --git a/public/pages/Snapshots/components/SnapshotFlyout/SnapshotFlyout.tsx b/public/pages/Snapshots/components/SnapshotFlyout/SnapshotFlyout.tsx index bf3542a36..3141edd0d 100644 --- a/public/pages/Snapshots/components/SnapshotFlyout/SnapshotFlyout.tsx +++ b/public/pages/Snapshots/components/SnapshotFlyout/SnapshotFlyout.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { Component } from "react"; +import React, { Component, useContext } from "react"; import { EuiButtonEmpty, EuiFlexGrid, @@ -25,8 +25,10 @@ import * as H from "history"; import { ROUTES } from "../../../../utils/constants"; import InfoModal from "../../../SnapshotPolicyDetails/components/InfoModal"; import { ModalConsumer } from "../../../../components/Modal"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; -interface SnapshotFlyoutProps { +interface SnapshotFlyoutProps extends DataSourceMenuProperties { snapshotId: string; repository: string; snapshotManagementService: SnapshotManagementService; @@ -34,17 +36,18 @@ interface SnapshotFlyoutProps { history: H.History; } -interface SnapshotFlyoutState { +interface SnapshotFlyoutState extends DataSourceMenuProperties { snapshot: GetSnapshot | null; } -export default class SnapshotFlyout extends Component { +export class SnapshotFlyout extends MDSEnabledComponent { static contextType = CoreServicesContext; constructor(props: SnapshotFlyoutProps) { super(props); this.state = { + ...this.state, snapshot: null, }; } @@ -54,6 +57,13 @@ export default class SnapshotFlyout extends Component { const { snapshotManagementService } = this.props; try { @@ -153,3 +163,8 @@ export default class SnapshotFlyout extends Component) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + return ; +} diff --git a/public/pages/Snapshots/containers/Snapshots/Snapshots.tsx b/public/pages/Snapshots/containers/Snapshots/Snapshots.tsx index 11855028c..ff98d7784 100644 --- a/public/pages/Snapshots/containers/Snapshots/Snapshots.tsx +++ b/public/pages/Snapshots/containers/Snapshots/Snapshots.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { Component } from "react"; +import React, { Component, useContext } from "react"; import _ from "lodash"; import { RouteComponentProps } from "react-router-dom"; import { @@ -36,13 +36,16 @@ import ErrorModal from "../../../Snapshots/components/ErrorModal/ErrorModal"; import DeleteModal from "../../../Repositories/components/DeleteModal/DeleteModal"; import { getToasts } from "../../helper"; import { snapshotStatusRender, truncateSpan } from "../../helper"; +import { DataSourceMenuContext, DataSourceMenuProperties } from "../../../../services/DataSourceMenuContext"; +import MDSEnabledComponent from "../../../../components/MDSEnabledComponent"; +import { useUpdateUrlWithDataSourceProperties } from "../../../../components/MDSEnabledComponent"; -interface SnapshotsProps extends RouteComponentProps { +interface SnapshotsProps extends RouteComponentProps, DataSourceMenuProperties { snapshotManagementService: SnapshotManagementService; indexService: IndexService; } -interface SnapshotsState { +interface SnapshotsState extends DataSourceMenuProperties { snapshots: SnapshotsWithRepoAndPolicy[]; existingPolicyNames: string[]; loadingSnapshots: boolean; @@ -67,7 +70,7 @@ interface SnapshotsState { isDeleteModalVisible: boolean; } -export default class Snapshots extends Component { +export class Snapshots extends MDSEnabledComponent { static contextType = CoreServicesContext; columns: EuiTableFieldDataColumnType[]; private tabsRef; @@ -76,6 +79,7 @@ export default class Snapshots extends Component super(props); this.state = { + ...this.state, snapshots: [], existingPolicyNames: [], loadingSnapshots: false, @@ -161,6 +165,20 @@ export default class Snapshots extends Component await this.getSnapshots(); } + async componentDidUpdate(prevProps: SnapshotsProps, prevState: SnapshotsState) { + const prevQuery = Snapshots.getQueryObjectFromState(prevState); + const currQuery = Snapshots.getQueryObjectFromState(this.state); + if (!_.isEqual(prevQuery, currQuery)) { + await this.getSnapshots(); + } + } + + static getQueryObjectFromState({ dataSourceId, multiDataSourceEnabled }: SnapshotsState) { + return { + ...(multiDataSourceEnabled ? { dataSourceId } : {}), + }; + } + getSnapshots = async () => { this.setState({ loadingSnapshots: true, message: "Loading snapshots..." }); @@ -558,3 +576,9 @@ export default class Snapshots extends Component .join(", "); }; } + +export default function (props: Omit) { + const dataSourceMenuProps = useContext(DataSourceMenuContext); + useUpdateUrlWithDataSourceProperties(); + return ; +} diff --git a/public/services/SnapshotManagementService.ts b/public/services/SnapshotManagementService.ts index 74d35b10d..6873fb36c 100644 --- a/public/services/SnapshotManagementService.ts +++ b/public/services/SnapshotManagementService.ts @@ -19,59 +19,68 @@ import { } from "../../server/models/interfaces"; import { ServerResponse } from "../../server/models/types"; import { DocumentSMPolicy, DocumentSMPolicyWithMetadata, SMPolicy, Snapshot } from "../../models/interfaces"; +import { MDSEnabledClientService } from "./MDSEnabledClientService"; -export default class SnapshotManagementService { - httpClient: HttpSetup; - - constructor(httpClient: HttpSetup) { - this.httpClient = httpClient; - } - +export default class SnapshotManagementService extends MDSEnabledClientService { getAllSnapshotsWithPolicy = async (): Promise> => { let url = `..${NODE_API._SNAPSHOTS}`; - const response = (await this.httpClient.get(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; + const response = (await this.httpClient.get(url, params)) as ServerResponse; return response; }; getSnapshot = async (snapshotId: string, repository: string): Promise> => { let url = `..${NODE_API._SNAPSHOTS}/${snapshotId}`; - const response = (await this.httpClient.get(url, { query: { repository } })) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({ repository }); + const params = query ? { query } : {}; + const response = (await this.httpClient.get(url, params)) as ServerResponse; return response; }; deleteSnapshot = async (snapshotId: string, repository: string): Promise> => { let url = `..${NODE_API._SNAPSHOTS}/${snapshotId}`; - const response = (await this.httpClient.delete(url, { query: { repository } })) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({ repository }); + const params = query ? { query } : {}; + const response = (await this.httpClient.delete(url, params)) as ServerResponse; return response; }; createSnapshot = async (snapshotId: string, repository: string, snapshot: Snapshot): Promise> => { let url = `..${NODE_API._SNAPSHOTS}/${snapshotId}`; + const query = this.patchQueryObjectWithDataSourceId({ repository }); + const params = query ? { query } : {}; const response = (await this.httpClient.put(url, { - query: { repository }, body: JSON.stringify(snapshot), + ...params, })) as ServerResponse; return response; }; restoreSnapshot = async (snapshotId: string, repository: string, options: object): Promise> => { let url = `..${NODE_API._SNAPSHOTS}/${snapshotId}`; + const query = this.patchQueryObjectWithDataSourceId({ repository }); + const params = query ? { query } : {}; const response = (await this.httpClient.post(url, { - query: { repository }, body: JSON.stringify(options), + ...params, })) as ServerResponse; return response; }; getIndexRecovery = async (): Promise> => { const url = NODE_API._RECOVERY; - const response = (await this.httpClient.get(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; + const response = (await this.httpClient.get(url, params)) as ServerResponse; return response; }; createPolicy = async (policyId: string, policy: SMPolicy): Promise> => { let url = `..${NODE_API.SMPolicies}/${policyId}`; - const response = (await this.httpClient.post(url, { body: JSON.stringify(policy) })) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; + const response = (await this.httpClient.post(url, { body: JSON.stringify(policy), ...params })) as ServerResponse; return response; }; @@ -82,70 +91,92 @@ export default class SnapshotManagementService { primaryTerm: number ): Promise> => { let url = `..${NODE_API.SMPolicies}/${policyId}`; + const query = this.patchQueryObjectWithDataSourceId({ seqNo, primaryTerm }); + const params = query ? { query } : {}; const response = (await this.httpClient.put(url, { - query: { seqNo, primaryTerm }, body: JSON.stringify(policy), + ...params, })) as ServerResponse; return response; }; getPolicies = async (queryObject: HttpFetchQuery): Promise> => { let url = `..${NODE_API.SMPolicies}`; - const response = (await this.httpClient.get(url, { query: queryObject })) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId(queryObject); + const params = query ? { query } : {}; + const response = (await this.httpClient.get(url, params)) as ServerResponse; return response; }; getPolicy = async (policyId: string): Promise> => { const url = `..${NODE_API.SMPolicies}/${policyId}`; - const response = (await this.httpClient.get(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; + const response = (await this.httpClient.get(url, params)) as ServerResponse; return response; }; deletePolicy = async (policyId: string): Promise> => { const url = `..${NODE_API.SMPolicies}/${policyId}`; - const response = (await this.httpClient.delete(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId(); + const params = query ? { query } : {}; + const response = (await this.httpClient.delete(url, params)) as ServerResponse; return response; }; startPolicy = async (policyId: string): Promise> => { const url = `..${NODE_API.SMPolicies}/${policyId}/_start`; - const response = (await this.httpClient.post(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId(); + const params = query ? { query } : {}; + const response = (await this.httpClient.post(url, params)) as ServerResponse; return response; }; stopPolicy = async (policyId: string): Promise> => { const url = `..${NODE_API.SMPolicies}/${policyId}/_stop`; - const response = (await this.httpClient.post(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId(); + const params = query ? { query } : {}; + const response = (await this.httpClient.post(url, params)) as ServerResponse; return response; }; catRepositories = async (): Promise> => { const url = `..${NODE_API._REPOSITORIES}`; - const response = (await this.httpClient.get(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; + const response = (await this.httpClient.get(url, params)) as ServerResponse; return response; }; catSnapshotIndices = async (indices: string): Promise> => { const url = `..${NODE_API._INDICES}/${indices}`; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; const response = (await this.httpClient.get(url)) as ServerResponse; return response; }; getRepository = async (repo: string): Promise> => { const url = `..${NODE_API._REPOSITORIES}/${repo}`; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; const response = (await this.httpClient.get(url)) as ServerResponse; return response; }; createRepository = async (repo: string, createRepoBody: CreateRepositoryBody): Promise> => { const url = `..${NODE_API._REPOSITORIES}/${repo}`; - const response = (await this.httpClient.put(url, { body: JSON.stringify(createRepoBody) })) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; + const response = (await this.httpClient.put(url, { body: JSON.stringify(createRepoBody), ...params })) as ServerResponse; return response; }; deleteRepository = async (repo: string): Promise> => { const url = `..${NODE_API._REPOSITORIES}/${repo}`; - const response = (await this.httpClient.delete(url)) as ServerResponse; + const query = this.patchQueryObjectWithDataSourceId({}); + const params = query ? { query } : {}; + const response = (await this.httpClient.delete(url, params)) as ServerResponse; return response; }; } diff --git a/server/plugin.ts b/server/plugin.ts index 387fada15..af0b69706 100644 --- a/server/plugin.ts +++ b/server/plugin.ts @@ -55,7 +55,7 @@ export class IndexPatternManagementPlugin implements Plugin>> => { try { - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const res: CatRepository[] = await callWithRequest("cat.repositories", { + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const res: CatRepository[] = (await callWithRequest("cat.repositories", { format: "json", - }); + })) as CatRepository[]; return response.custom({ statusCode: 200, body: { @@ -493,10 +488,10 @@ export default class SnapshotManagementService { response: OpenSearchDashboardsResponseFactory ): Promise>> => { try { - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const res: GetIndexRecoveryResponse = await callWithRequest("indices.recovery", { + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const res: GetIndexRecoveryResponse = (await callWithRequest("indices.recovery", { format: "json", - }); + })) as GetIndexRecoveryResponse; return response.custom({ statusCode: 200, body: { @@ -515,10 +510,10 @@ export default class SnapshotManagementService { response: OpenSearchDashboardsResponseFactory ): Promise>> => { try { - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const res: CatSnapshotIndex[] = await callWithRequest("cat.indices", { + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const res: CatSnapshotIndex[] = (await callWithRequest("cat.indices", { format: "json", - }); + })) as CatSnapshotIndex[]; return response.custom({ statusCode: 200, @@ -538,17 +533,17 @@ export default class SnapshotManagementService { response: OpenSearchDashboardsResponseFactory ): Promise>> => { try { - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const res: CatRepository[] = await callWithRequest("cat.repositories", { + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const res: CatRepository[] = (await callWithRequest("cat.repositories", { format: "json", - }); + })) as CatRepository[]; for (let i = 0; i < res.length; i++) { - const getSnapshotRes: GetSnapshotResponse = await callWithRequest("snapshot.get", { + const getSnapshotRes: GetSnapshotResponse = (await callWithRequest("snapshot.get", { repository: res[i].id, snapshot: "_all", ignore_unavailable: true, - }); + })) as GetSnapshotResponse; res[i].snapshotCount = getSnapshotRes.snapshots.length; } @@ -571,10 +566,10 @@ export default class SnapshotManagementService { ): Promise>> => { try { const { id } = request.params as { id: string }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const res: AcknowledgedResponse = await callWithRequest("snapshot.deleteRepository", { + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const res: AcknowledgedResponse = (await callWithRequest("snapshot.deleteRepository", { repository: id, - }); + })) as AcknowledgedResponse; return response.custom({ statusCode: 200, body: { @@ -594,10 +589,10 @@ export default class SnapshotManagementService { ): Promise>> => { try { const { id } = request.params as { id: string }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const res: GetRepositoryResponse = await callWithRequest("snapshot.getRepository", { + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const res: GetRepositoryResponse = (await callWithRequest("snapshot.getRepository", { repository: id, - }); + })) as GetRepositoryResponse; return response.custom({ statusCode: 200, body: { @@ -621,8 +616,8 @@ export default class SnapshotManagementService { repository: id, body: JSON.stringify(request.body), }; - const { callAsCurrentUser: callWithRequest } = this.osDriver.asScoped(request); - const res: AcknowledgedResponse = await callWithRequest("snapshot.createRepository", params); + const callWithRequest = this.getClientBasedOnDataSource(context, request); + const res: AcknowledgedResponse = (await callWithRequest("snapshot.createRepository", params)) as AcknowledgedResponse; return response.custom({ statusCode: 200, body: {