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

[8.x] [Search][Connectors] Create connector via try in console (#197757) #198225

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 0 additions & 44 deletions x-pack/plugins/enterprise_search/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,50 +218,6 @@ export const CREATE_CONNECTOR_PLUGIN = {
--index-language en
--from-file config.yml
`,
CONSOLE_SNIPPET: dedent`# Create an index
PUT /my-index-000001
{
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
}

# Create an API key
POST /_security/api_key
{
"name": "my-api-key",
"expiration": "1d",
"role_descriptors":
{
"role-a": {
"cluster": ["all"],
"indices": [
{
"names": ["index-a*"],
"privileges": ["read"]
}
]
},
"role-b": {
"cluster": ["all"],
"indices": [
{
"names": ["index-b*"],
"privileges": ["all"]
}]
}
}, "metadata":
{ "application": "my-application",
"environment": {
"level": 1,
"trusted": true,
"tags": ["dev", "staging"]
}
}
}`,
};

export const LICENSED_SUPPORT_URL = 'https://support.elastic.co';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,27 @@
*/
import React, { useState } from 'react';

import { css } from '@emotion/react';
import dedent from 'dedent';

import { useValues } from 'kea';

import {
EuiButtonIcon,
EuiContextMenuItem,
EuiContextMenuPanel,
EuiPopover,
useGeneratedHtmlId,
useEuiTheme,
} from '@elastic/eui';

import { i18n } from '@kbn/i18n';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { NATIVE_CONNECTOR_DEFINITIONS, NativeConnector } from '@kbn/search-connectors';
import { TryInConsoleButton } from '@kbn/try-in-console';

import { KibanaDeps } from '../../../../../../../common/types';
import { NewConnectorLogic } from '../../../new_index/method_connector/new_connector_logic';
import { SelfManagePreference } from '../create_connector';

import { ManualConfigurationFlyout } from './manual_configuration_flyout';
Expand All @@ -25,10 +36,18 @@ export interface ManualConfigurationProps {
selfManagePreference: SelfManagePreference;
}

interface ConnectorConfiguration {
[key: string]: {
value: string;
};
}

export const ManualConfiguration: React.FC<ManualConfigurationProps> = ({
isDisabled,
selfManagePreference,
}) => {
const { euiTheme } = useEuiTheme();
const { services } = useKibana<KibanaDeps>();
const [isPopoverOpen, setPopover] = useState(false);
const splitButtonPopoverId = useGeneratedHtmlId({
prefix: 'splitButtonPopover',
Expand All @@ -40,9 +59,104 @@ export const ManualConfiguration: React.FC<ManualConfigurationProps> = ({
const closePopover = () => {
setPopover(false);
};

const { selectedConnector, rawName } = useValues(NewConnectorLogic);
const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
const [flyoutContent, setFlyoutContent] = useState<'manual_config' | 'client'>();
const getCodeSnippet = (): string => {
const connectorInfo: NativeConnector | undefined = selectedConnector?.serviceType
? NATIVE_CONNECTOR_DEFINITIONS[selectedConnector.serviceType]
: undefined;
if (!connectorInfo) {
return '';
}

const dynamicConfigValues = Object.entries(
connectorInfo.configuration as ConnectorConfiguration
)
.map(([key, config]) => {
const defaultValue = config ? JSON.stringify(config.value) : null;
return ` "${key}": ${defaultValue}`;
})
.join(',\n');
const CONSOLE_SNIPPET = dedent` # Example of how to create a ${connectorInfo?.name} connector using the API
# This also creates related resources like an index and an API key.
# This is an alternative to using the UI creation flow.

# 1. Create an index
PUT connector-${rawName}
{
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
}
# 2. Create a connector
PUT _connector/${rawName}
{
"name": "My ${connectorInfo?.name} connector",
"index_name": "connector-${rawName}",
"service_type": "${selectedConnector?.serviceType}"
}
# 3. Create an API key
POST /_security/api_key
{
"name": "${rawName}-api-key",
"role_descriptors": {
"${selectedConnector?.serviceType}-api-key-role": {
"cluster": [
"monitor",
"manage_connector"
],
"indices": [
{
"names": [
"connector-${rawName}",
".search-acl-filter-connector-${rawName}",
".elastic-connectors*"
],
"privileges": [
"all"
],
"allow_restricted_indices": false
}
]
}
}
}

# 🔧 Configure your connector
# NOTE: Configuration keys differ per service type.
PUT _connector/${rawName}/_configuration
{
"values": {
${dynamicConfigValues}
}
}

# 🔌 Verify your connector is connected
GET _connector/${rawName}

# 🔄 Sync data
POST _connector/_sync_job
{
"id": "${rawName}",
"job_type": "full"
}

# ⏳ Check sync status
GET _connector/_sync_job?connector_id=${rawName}&size=1

# Once the job completes, the status should return completed
# 🎉 Verify that data is present in the index with the following API call
GET connector-${rawName}/_count

# 🔎 Elasticsearch stores data in documents, which are JSON objects. List the individual documents with the following API call
GET connector-${rawName}/_search
`;
return CONSOLE_SNIPPET;
};

const items = [
<EuiContextMenuItem
Expand All @@ -59,6 +173,33 @@ export const ManualConfiguration: React.FC<ManualConfigurationProps> = ({
{ defaultMessage: 'Manual configuration' }
)}
</EuiContextMenuItem>,
<EuiContextMenuItem
key="edit"
icon="console"
onClick={() => {
closePopover();
}}
css={css`
.euiLink {
color: ${euiTheme.colors.text};
font-weight: ${euiTheme.font.weight.regular};
}
`}
>
<TryInConsoleButton
application={services.application}
sharePlugin={services.share}
consolePlugin={services.console}
content={i18n.translate(
'xpack.enterpriseSearch.createConnector.flyoutManualConfigContent.TryInConsoleLabel',
{
defaultMessage: 'Run in Console',
}
)}
type="link"
request={getCodeSnippet()}
/>
</EuiContextMenuItem>,
<EuiContextMenuItem
key="share"
icon="console"
Expand Down