Skip to content

Commit

Permalink
[Search][Connectors] Create connector via try in console (#197757)
Browse files Browse the repository at this point in the history
## Summary

This PR enables the possibility of creating a connector opening the
embedded console in the start step.

![CleanShot 2024-10-28 at 10 00
04](https://github.com/user-attachments/assets/bf2c0a89-1c18-4fcd-8c2b-4fbbe3ef80a9)

---------

Co-authored-by: Liam Thompson <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
3 people authored Oct 29, 2024
1 parent aec93bf commit 248119e
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 45 deletions.
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

0 comments on commit 248119e

Please sign in to comment.