/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import { EuiFormRowProps } from "@elastic/eui"; import { merge, isEmpty } from "lodash"; import { FieldInstance, transformNameToString } from "../../lib/field"; import { IFormGeneratorRef } from "../../components/FormGenerator"; import { IndexForm } from "../../containers/IndexForm"; import { IRolloverRequestBody } from "./interface"; import { IndexItemRemote } from "../../../models/interfaces"; import { BrowserServices } from "../../models/interfaces"; import { Alias } from "../../../server/models/interfaces"; import { ServerResponse } from "../../../server/models/types"; export type TypeSourceType = "dataStreams" | "alias" | undefined; export const getCommonFormRowProps = (name: string | string[], field: FieldInstance): Partial => { return { isInvalid: !!field.getError(name), error: field.getError(name), "data-test-subj": `form-row-${transformNameToString(name)}`, }; }; export const onSubmit = async (props: { sourceRef: React.RefObject; sourceType: TypeSourceType; writingIndex: string; indexFormRef: React.RefObject; tempValue: IRolloverRequestBody; services: BrowserServices; }): Promise< ServerResponse<{ new_index: string; }> > => { const { sourceRef, sourceType, writingIndex, indexFormRef, tempValue, services } = props; const formGeneratersRes = await Promise.all([ sourceRef.current?.validatePromise(), sourceType === "alias" && !writingIndex.match(/^.*-\d+$/) ? (new Promise(async (resolve) => { const result = await indexFormRef.current?.validate(); if (result) { resolve({ errors: { targetIndex: [result] }, values: {} }); } else { resolve({ errors: null, values: { targetIndex: indexFormRef.current?.getValue() || {}, }, }); } }) as Promise<{ errors: Record | null; values: Record }>) : Promise.resolve({ errors: null, values: { targetIndex: indexFormRef.current?.getValue() || {}, }, }), ]); const hasError = formGeneratersRes.some((item) => item?.errors); if (hasError) { return { ok: false, error: "Some fields does not pass validation, please check fields with red underline.", }; } const finalValues: IRolloverRequestBody = merge({}, tempValue); formGeneratersRes.forEach((item) => merge(finalValues, item?.values)); const payload: { alias: string; newIndex?: string; body: Omit & { conditions?: IRolloverRequestBody["conditions"] }; } = { alias: finalValues.source || "", body: {}, }; if (sourceType === "alias" && !isEmpty(finalValues.targetIndex || {})) { const { index, ...others } = (finalValues.targetIndex || {}) as IndexItemRemote; if (index) { payload.newIndex = index; } payload.body = others; } const result = await services.commonService.apiCaller<{ new_index: string; }>({ endpoint: "indices.rollover", data: payload, }); return result; }; export const submitWriteIndex = async (props: { services: BrowserServices; writeIndexValue: string; sourceRef: React.RefObject; }) => { const { services, writeIndexValue, sourceRef } = props; return await services.commonService.apiCaller({ endpoint: "indices.updateAliases", data: { body: { actions: [ { add: { index: writeIndexValue, alias: sourceRef.current?.getValue("source"), is_write_index: true, }, }, ], }, }, }); }; export const getOptions = async (props: { services: BrowserServices }) => { const { services } = props; return Promise.all([ services.commonService.apiCaller({ endpoint: "cat.aliases", data: { format: "json", }, }), services.indexService.getDataStreams({}), ]).then(([aliases, dataStreams]) => { if (aliases.ok && dataStreams.ok) { const allAlias: { label: string; aliases: Alias[] }[] = []; aliases.response.forEach((item) => { let findIndex; if (allAlias.find((alias) => alias.label === item.alias)) { findIndex = allAlias.findIndex((alias) => alias.label === item.alias); } else { findIndex = allAlias.length; allAlias.push({ label: item.alias, aliases: [], }); } allAlias[findIndex].aliases.push(item); }); return { ok: true, response: { alias: allAlias, dataStreams: dataStreams.response?.dataStreams.map((item) => ({ label: item.name })) || [], }, }; } return { ok: false, error: aliases.error || dataStreams.error, }; }); }; export const getRolloveredIndex = async (props: { alias: string; services: BrowserServices }): Promise> => { const { alias, services } = props; const result = await services.commonService.apiCaller<{ new_index: string; }>({ endpoint: "indices.rollover", data: { alias, dry_run: true, }, hideLog: true, }); if (result.ok) { return { ok: true, response: result.response.new_index, }; } else if (result && result.body && result.body.error && result.body.error.index) { return { ok: true, response: result.body.error.index, }; } return { ok: false, error: result.error, }; }; export const getIndexDetail = async ({ services, indexName, newIndexName, }: { services: BrowserServices; indexName: string; newIndexName: string; }) => { const response = await services.commonService.apiCaller>({ endpoint: "indices.get", data: { index: indexName, flat_settings: true, }, }); if (response.ok) { return { ...response.response[indexName], index: newIndexName, }; } throw new Error(response.error); };