Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pit plugin poc #1

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions config/opensearch_dashboards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@

# Set the value of this setting to true to enables the experimental multiple data source
# support feature. Use with caution.
#data_source.enabled: false
data_source.enabled: true
# Set the value of these settings to custermize crypto materials to encryption saved credentials
# in data sources.
#data_source.encryption.wrappingKeyName: 'changeme'
#data_source.encryption.wrappingKeyNamespace: 'changeme'
#data_source.encryption.wrappingKey: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
data_source.encryption.wrappingKeyName: 'changeme'
data_source.encryption.wrappingKeyNamespace: 'changeme'
data_source.encryption.wrappingKey: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"angular-elastic": "^2.5.1",
"angular-sanitize": "^1.8.0",
"bluebird": "3.5.5",
"caniuse-lite": "^1.0.30001397",
"chalk": "^4.1.0",
"chokidar": "^3.4.2",
"color": "1.0.3",
Expand Down Expand Up @@ -212,6 +213,7 @@
"type-detect": "^4.0.8",
"uuid": "3.3.2",
"whatwg-fetch": "^3.0.0",
"yarn": "^1.22.19",
"yauzl": "^2.10.0"
},
"devDependencies": {
Expand Down Expand Up @@ -461,4 +463,4 @@
"node": "14.20.0",
"yarn": "^1.21.1"
}
}
}
7 changes: 7 additions & 0 deletions plugins/my_plugin_name/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
root: true,
extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'],
rules: {
'@osd/eslint/require-license-header': 'off',
},
};
2 changes: 2 additions & 0 deletions plugins/my_plugin_name/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build
/target
7 changes: 7 additions & 0 deletions plugins/my_plugin_name/.i18nrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"prefix": "myPluginName",
"paths": {
"myPluginName": "."
},
"translations": ["translations/ja-JP.json"]
}
22 changes: 22 additions & 0 deletions plugins/my_plugin_name/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# my_plugin_name

A OpenSearch Dashboards plugin

---

## Development

See the [OpenSearch Dashboards contributing
guide](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/main/CONTRIBUTING.md) for instructions
setting up your development environment.

## Scripts
<dl>
<dt><code>yarn osd bootstrap</code></dt>
<dd>Execute this to install node_modules and setup the dependencies in your plugin and in OpenSearch Dashboards
</dd>

<dt><code>yarn plugin-helpers build</code></dt>
<dd>Execute this to create a distributable version of this plugin that can be installed in OpenSearch Dashboards
</dd>
</dl>
3 changes: 3 additions & 0 deletions plugins/my_plugin_name/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const PLUGIN_ID = 'myPluginName';
export const PLUGIN_NAME = 'my_plugin_name';
export const CREATE_POINT_IN_TIME_PATH = '/api/create_point_in_time';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { PointInTimeFlyout } from './point_in_time_flyout';

Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
import React, { Component, Fragment, ReactNode, useEffect, useState } from 'react';
import { take, get as getField } from 'lodash';
import {
EuiFlyout,
EuiFlyoutBody,
EuiFlyoutFooter,
EuiFlyoutHeader,
EuiButtonEmpty,
EuiButton,
EuiText,
EuiTitle,
EuiForm,
EuiFormRow,
EuiFilePicker,
EuiInMemoryTable,
EuiSelect,
EuiFlexGroup,
EuiFlexItem,
EuiLoadingSpinner,
EuiCallOut,
EuiSpacer,
EuiLink,
EuiCodeBlock,
EuiFieldText,
EuiTextArea,
EuiRange,
EuiCheckbox,
EuiFormLabel,
} from '@elastic/eui';
import { i18n } from '@osd/i18n';
import { FormattedMessage } from '@osd/i18n/react';
// import { IIndexPattern } from 'src/plugins/data/public';
// import { useOpenSearchDashboards } from '../../../../src/plugins/opensearch_dashboards_react/public';

export interface PointInTimeFlyoutItem {
id: string;
title: string;
sort: string;
};
// export async function getIndexPatterns(
// savedObjectsClient
// ) {
// return (
// savedObjectsClient
// .find({
// type: 'index-pattern',
// fields: ['title', 'type'],
// perPage: 10000,
// })
// .then((response) =>
// response.savedObjects
// .map((pattern) => {
// const id = pattern.id;
// const title = pattern.get('title');


// return {
// id,
// title,
// // the prepending of 0 at the default pattern takes care of prioritization
// // so the sorting will but the default index on top
// // or on bottom of a the table
// sort: `${title}`,
// };
// })
// .sort((a, b) => {
// if (a.sort < b.sort) {
// return -1;
// } else if (a.sort > b.sort) {
// return 1;
// } else {
// return 0;
// }
// })
// ) || []
// );
// }

export const PointInTimeFlyout = async () => {

const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
const [showErrors, setShowErrors] = useState(false);
const [value, setValue] = useState('24');
const [checked, setChecked] = useState(false);
// const [indexPatterns, setIndexPatterns] = useState([] as PointInTimeFlyoutItem[]);
const onChange = (e) => {
setValue(e.target.value);
};

// const {
// savedObjects,
// } = useOpenSearchDashboards().services;

// useEffect(() => {
// (async function () {
// const gettedIndexPatterns: PointInTimeFlyoutItem[] = await getIndexPatterns(
// savedObjects.client
// );
// setIndexPatterns(gettedIndexPatterns);

// console.log(gettedIndexPatterns);
// })();
// } , [
// savedObjects.client,
// ]);



const renderBody = ({ data, isLoading, hasPrivilegeToRead }: any) => {
if (isLoading) {
return (
<EuiFlexGroup justifyContent="spaceAround">
<EuiFlexItem grow={false}>
<EuiLoadingSpinner size="xl" />
</EuiFlexItem>
</EuiFlexGroup>
);
}

if (!hasPrivilegeToRead) {
return (
<EuiCallOut
title={
<FormattedMessage
id="telemetry.callout.errorUnprivilegedUserTitle"
defaultMessage="Error displaying cluster statistics"
/>
}
color="danger"
iconType="cross"
>
<FormattedMessage
id="telemetry.callout.errorUnprivilegedUserDescription"
defaultMessage="You do not have access to see unencrypted cluster statistics."
/>
</EuiCallOut>
);
}

if (data === null) {
return (
<EuiCallOut
title={
<FormattedMessage
id="telemetry.callout.errorLoadingClusterStatisticsTitle"
defaultMessage="Error loading cluster statistics"
/>
}
color="danger"
iconType="cross"
>
<FormattedMessage
id="telemetry.callout.errorLoadingClusterStatisticsDescription"
defaultMessage="An unexpected error occured while attempting to fetch the cluster statistics.
This can occur because OpenSearch failed, OpenSearch Dashboards failed, or there is a network error.
Check OpenSearch Dashboards, then reload the page and try again."
/>
</EuiCallOut>
);
}


const onButtonClick = () => {
setShowErrors(!showErrors);
};

// const button = (
// <EuiButton fill color="danger" onClick={onButtonClick}>
// Toggle errors
// </EuiButton>
// );


const onCheckboxChange = (e) => {
setChecked(e.target.checked);
};
let errors;
return <Fragment>
<EuiForm isInvalid={showErrors} error={errors} component="form">
<EuiFormRow isInvalid={showErrors} fullWidth>
<EuiText>
<p>
Create point in time search based on existing index pattern
</p>
</EuiText>
</EuiFormRow>

<EuiFormRow label="Data source" isInvalid={showErrors} fullWidth>
<EuiSelect
fullWidth
options={[
{ value: 'option_one', text: 'Option one' },
{ value: 'option_two', text: 'Option two' },
{ value: 'option_three', text: 'Option three' },
]}
isInvalid={showErrors}
/>
</EuiFormRow>
<EuiFormRow label="Custom Point in time name" isInvalid={showErrors} fullWidth>
<EuiFieldText fullWidth name="name" isInvalid={showErrors} />
</EuiFormRow>

<EuiFormRow
label="Expiration in"
isInvalid={showErrors}
fullWidth
>
<EuiRange
// min={100}
max={24}
step={0.05}
fullWidth
value={value}
onChange={onChange}
showLabels
showValue
aria-label="An example of EuiRange with showLabels prop"
/>
</EuiFormRow>

<EuiFormRow isInvalid={showErrors} fullWidth>
<EuiCheckbox
id="checkbox"
label="The PIT will be automatically deleted at the expiry time"
checked={checked}
onChange={(e) => onCheckboxChange(e)}
/>
</EuiFormRow>


<EuiSpacer />

{/* {button} */}
</EuiForm>
</Fragment>

//return <EuiCodeBlock language="js">{JSON.stringify(data, null, 2)}</EuiCodeBlock>;
}

let flyout;
if (isFlyoutVisible) {
flyout = (<EuiFlyout ownFocus onClose={() => setIsFlyoutVisible(false)} size="m" paddingSize="m" >
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2>
<FormattedMessage
id="savedObjectsManagement.objectsTable.flyout.importSavedObjectTitle"
defaultMessage="Create point in time"
/>
</h2>
</EuiTitle>
</EuiFlyoutHeader>

<EuiFlyoutBody>
{renderBody({ data: "", isLoading: false, hasPrivilegeToRead: true })}
</EuiFlyoutBody>
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty
iconType="cross"
onClick={() => setIsFlyoutVisible(false)}
flush="left"
>
Close
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton onClick={() => setIsFlyoutVisible(false)} fill>
Save
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>
{/* <EuiFlyoutFooter>{renderFooter()}</EuiFlyoutFooter> */}
{/* {confirmOverwriteModal} */}
</EuiFlyout>);
}

return (
<div>
<EuiButton
onClick={() => setIsFlyoutVisible(true)}
iconType="plusInCircle"
fill={true}
>
Create point in time
</EuiButton>
{flyout}
</div>
);
};

function useGeneratedHtmlId(arg0: { prefix: string; }) {
throw new Error('Function not implemented.');
}

Loading