Add Elasticsearch guide (#128190)

* Add basic elasticsearch card and page

* Add more content and styles

* Update content

* Add language client select

* Get client language from URL

* Add language instructions

* Make designs close to pixel perfect

* Add i18n strings

* Add elasticsearch_cloud_id component and tests

Co-authored-by: joemcelroy <joseph.mcelroy@elastic.co>

* Fix linter errors

* Use i18n instead of FormattedMessage for consistency

* Remove redundant FormattedMessage

* include cloud deployment link in UI

* Add instructions for all language clients

* Rewrite language selector with switch

* Add missing target blank

* Remove trailing whitespace in code blocks

* Fix i18n

* Invert ruby instructions

* Update page layout

* Add syntax highlighting

* Remove PERL

* Reorder languages

* Add placeholder for elasticsearch version

* Change docs version to current

* Add missing links

* Add target="_blank" to links

* Simplify strong prop

* Fix column stretching from Kibana PR Cloud ID in code blocks

* Fix page keeping the scroll position

* Fix typo

* Adhere to writing guidelines

* Use docLinks service

* Update dotnet guide

* Use elasticsearch query dsl link instead of creating a new one for Ruby client

* Update php connecting link

Looks like it was fixed in `master`, but not in `current` docs. Since the PR is going to master, we could use the corrected link

Co-authored-by: joemcelroy <joseph.mcelroy@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Vadim Yakhin 2022-03-28 17:06:33 -07:00 committed by GitHub
parent 8d117ca349
commit ecd2a50c19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 1782 additions and 1 deletions

View file

@ -243,6 +243,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
dataStreams: `${ELASTICSEARCH_DOCS}data-streams.html`,
deprecationLogging: `${ELASTICSEARCH_DOCS}logging.html#deprecation-logging`,
frozenIndices: `${ELASTICSEARCH_DOCS}frozen-indices.html`,
gettingStarted: `${ELASTICSEARCH_DOCS}getting-started.html`,
hiddenIndices: `${ELASTICSEARCH_DOCS}multi-index.html#hidden`,
ilm: `${ELASTICSEARCH_DOCS}index-lifecycle-management.html`,
ilmForceMerge: `${ELASTICSEARCH_DOCS}ilm-forcemerge.html`,
@ -598,15 +599,31 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
clients: {
/** Changes to these URLs must also be synched in src/plugins/custom_integrations/server/language_clients/index.ts */
guide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/index.html`,
goIndex: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/go-api/${DOC_LINK_VERSION}/index.html`,
goOverview: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/go-api/${DOC_LINK_VERSION}/overview.html`,
javaBasicAuthentication: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/java-api-client/${DOC_LINK_VERSION}/_basic_authentication.html`,
javaIndex: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/java-api-client/${DOC_LINK_VERSION}/index.html`,
javaInstallation: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/java-api-client/${DOC_LINK_VERSION}/installation.html`,
javaIntroduction: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/java-api-client/${DOC_LINK_VERSION}/introduction.html`,
javaRestLow: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/java-api-client/${DOC_LINK_VERSION}/java-rest-low.html`,
jsClientConnecting: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/javascript-api/${DOC_LINK_VERSION}/client-connecting.html`,
jsIntro: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/javascript-api/${DOC_LINK_VERSION}/introduction.html`,
netGuide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/net-api/${DOC_LINK_VERSION}/index.html`,
netIntroduction: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/net-api/${DOC_LINK_VERSION}/introduction.html`,
netNest: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/net-api/${DOC_LINK_VERSION}/nest.html`,
netSingleNode: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/net-api/${DOC_LINK_VERSION}/connecting.html#single-node`,
perlGuide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/perl-api/${DOC_LINK_VERSION}/index.html`,
phpConnecting: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/php-api/${DOC_LINK_VERSION}/connecting.html`,
phpInstallation: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/php-api/${DOC_LINK_VERSION}/installation.html`,
phpGuide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/php-api/${DOC_LINK_VERSION}/index.html`,
phpOverview: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/php-api/${DOC_LINK_VERSION}/overview.html`,
pythonAuthentication: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/python-api/${DOC_LINK_VERSION}/connecting.html#authentication`,
pythonGuide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/python-api/${DOC_LINK_VERSION}/index.html`,
pythonOverview: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/python-api/${DOC_LINK_VERSION}/overview.html`,
rubyAuthentication: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/ruby-api/${DOC_LINK_VERSION}/connecting.html#client-auth`,
rubyOverview: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/ruby-api/${DOC_LINK_VERSION}/ruby_client.html`,
rustGuide: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/rust-api/${DOC_LINK_VERSION}/index.html`,
rustOverview: `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/client/rust-api/${DOC_LINK_VERSION}/overview.html`,
},
endpoints: {
troubleshooting: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/ts-management.html#ts-endpoints`,

View file

@ -359,15 +359,31 @@ export interface DocLinks {
};
readonly clients: {
readonly guide: string;
readonly goIndex: string;
readonly goOverview: string;
readonly javaBasicAuthentication: string;
readonly javaIndex: string;
readonly javaInstallation: string;
readonly javaIntroduction: string;
readonly javaRestLow: string;
readonly jsClientConnecting: string;
readonly jsIntro: string;
readonly netGuide: string;
readonly netIntroduction: string;
readonly netNest: string;
readonly netSingleNode: string;
readonly perlGuide: string;
readonly phpGuide: string;
readonly phpConnecting: string;
readonly phpInstallation: string;
readonly phpOverview: string;
readonly pythonAuthentication: string;
readonly pythonGuide: string;
readonly pythonOverview: string;
readonly rubyAuthentication: string;
readonly rubyOverview: string;
readonly rustGuide: string;
readonly rustOverview: string;
};
readonly endpoints: {
readonly troubleshooting: string;

View file

@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { EuiButtonTo } from '../../../shared/react_router_helpers';
import { ELASTICSEARCH_GUIDE_PATH } from '../../routes';
import { ElasticsearchResources } from '../elasticsearch_resources';
export const ElasticsearchCard: React.FC = () => {
return (
<EuiPanel paddingSize="l">
<EuiFlexGroup gutterSize="xl" alignItems="center" justifyContent="spaceBetween">
<EuiFlexItem>
<EuiTitle size="s">
<h3>
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchCard.heading', {
defaultMessage: 'Get started with Elasticsearch',
})}
</h3>
</EuiTitle>
<EuiSpacer size="s" />
<EuiText size="s">
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchCard.description', {
defaultMessage:
'Design and build performant, relevant search-powered applications or large-scale search implementations directly in Elasticsearch',
})}
</EuiText>
<EuiSpacer size="s" />
<EuiSpacer size="xs" />
{/* div is needed to prevent button from stretching */}
<div>
<EuiButtonTo to={ELASTICSEARCH_GUIDE_PATH}>
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchCard.button', {
defaultMessage: 'Get started',
})}
</EuiButtonTo>
</div>
</EuiFlexItem>
<EuiFlexItem>
<ElasticsearchResources />
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
);
};

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { ElasticsearchCard } from './elasticsearch_card';

View file

@ -0,0 +1,51 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { useValues } from 'kea';
import { KibanaLogic } from '../../../shared/kibana';
import { ElasticsearchDotnet } from './elasticsearch_dotnet';
import { ElasticsearchGo } from './elasticsearch_go';
import { ElasticsearchJava } from './elasticsearch_java';
import { ElasticsearchJavascript } from './elasticsearch_javascript';
import { ElasticsearchPhp } from './elasticsearch_php';
import { ElasticsearchPython } from './elasticsearch_python';
import { ElasticsearchRuby } from './elasticsearch_ruby';
import { ElasticsearchRust } from './elasticsearch_rust';
const useCloudId = (): string | undefined => {
const { cloud } = useValues(KibanaLogic);
return cloud?.cloudId;
};
export const ElasticsearchClientInstructions: React.FC<{ language: string }> = ({ language }) => {
const cloudId = useCloudId();
switch (language) {
case 'dotnet':
return <ElasticsearchDotnet />;
case 'go':
return <ElasticsearchGo cloudId={cloudId} />;
case 'java':
return <ElasticsearchJava />;
case 'javascript':
return <ElasticsearchJavascript cloudId={cloudId} />;
case 'php':
return <ElasticsearchPhp cloudId={cloudId} />;
case 'python':
return <ElasticsearchPython cloudId={cloudId} />;
case 'ruby':
return <ElasticsearchRuby cloudId={cloudId} />;
case 'rust':
return <ElasticsearchRust />;
default:
return null;
}
};

View file

@ -0,0 +1,155 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchDotnet: React.FC<{ cloudId?: string }> = ({ cloudId }) => {
return (
<>
<EuiText>
<p>
The official .Net client for Elasticsearch includes all the features you need to add
search to a .Net application:
</p>
<ul>
<li>One-to-one mapping with REST API.</li>
<li>Strongly typed requests and responses for Elasticsearch APIs.</li>
<li>Fluent API for building requests.</li>
<li>Helpers for common tasks such as bulk indexing of documents.</li>
<li>Pluggable serialization of requests and responses based on System.Text.Json.</li>
<li>Diagnostics, auditing, and .NET activity integration.</li>
</ul>
<p>
The .NET Elasticsearch client is built upon the Elastic Transport library which provides:
</p>
<ul>
<li>Connection management and load balancing across all available nodes.</li>
<li>Request retries and dead connections handling.</li>
</ul>
<EuiLink target="_blank" href={docLinks.clientsNetIntroduction}>
Learn more about the official .NET clients for Elasticsearch
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/elasticsearch-net">
The official Elasticsearch .NET clients on Github
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>
For SDK style projects, you can install the Elasticsearch client by running the following
.NET CLI command in your terminal:
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="shell">
{dedent`
dotnet add package Elastic.Clients.Elasticsearch
`}
</EuiCodeBlock>
<EuiSpacer size="s" />
<EuiText>
<p>
This command adds a package reference to your project (csproj) file for the latest stable
version of the client.
</p>
<p>
If you prefer, you may also manually add a package reference inside your project file:
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="shell">
{dedent`
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="ELASTICSAERCH VERSION" />
`}
</EuiCodeBlock>
<EuiSpacer />
<EuiText>
<p>
For Visual Studio users, the .NET client can also be installed from the Package Manager
Console inside Visual Studio using the following command:
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="shell">
{dedent`
Install-Package Elastic.Clients.Elasticsearch
`}
</EuiCodeBlock>
<EuiSpacer />
<EuiText>
<p>
Alternatively, search for Elastic.Clients.Elasticsearch in the NuGet Package Manager UI.
</p>
</EuiText>
<EuiSpacer />
{cloudId ? (
<>
<EuiText>
<h4>Connecting to Elastic Cloud</h4>
<p>
Connecting to an Elasticsearch Service deployment is achieved by providing the unique
Cloud ID for your deployment when configuring the ElasticsearchClient instance. You
can retrieve the Cloud ID from the homepage of the deployment in Elasticsearch
Service. You also require suitable credentials that your application uses to
authenticate with your deployment.
</p>
<p>
As a security best practice, it is recommended to create a dedicated API key per
application, with permissions limited to only those required for any API calls the
application is authorized to make.
</p>
<p>
The following snippet shows you how to create a client instance that connects to an
Elasticsearch deployment in the cloud.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="python">
{dedent`
using Elastic.Clients.Elasticsearch;
using Elastic.Transport;
var client = new ElasticsearchClient("${cloudId}", new ApiKey("<API_KEY>"));
`}
</EuiCodeBlock>
</>
) : (
<>
<EuiText>
<h4>Connecting to Elasticsearch</h4>
<p>
The .Net client for Elasticsearch supports connecting to single nodes as well as
multiple nodes utilizing a node pool.{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsNetSingleNode}>
Visit the documentation to learn more about connecting to Elasticsearch.
</a>
</p>
</EuiText>
</>
)}
</>
);
};

View file

@ -0,0 +1,139 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchGo: React.FC<{ cloudId?: string }> = ({ cloudId }) => {
return (
<>
<EuiText>
<p>
The official Go client for Elasticsearch includes all the features you need to add search
to a Go application:
</p>
<ul>
<li>One-to-one mapping with the Elasticsearch REST API</li>
<li>Generalized, pluggable architecture</li>
<li>Helpers for convenience</li>
<li>A rich set of examples in the documentation</li>
</ul>
<EuiLink target="_blank" href={docLinks.clientsGoIndex}>
Learn more about the Go client for Elasticsearch
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/go-elasticsearch">
The Go client for Elasticsearch on Github
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://godoc.org/github.com/elastic/go-elasticsearch">
View the documentation on GoDoc
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>Add the package to your go.mod file:</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="go-module">
{dedent`
require github.com/elastic/go-elasticsearch/v8 main
`}
</EuiCodeBlock>
<EuiSpacer />
<EuiText>
<h4>Getting started</h4>
<p>
The <code>elasticsearch</code> package ties together two separate packages for calling the
Elasticsearch APIs and transferring data over HTTP: <code>esapi</code> and{' '}
<code>elastictransport</code>.
</p>
<p>
Use the <code>elasticsearch.NewDefaultClient()</code> function to create the client with
the default settings.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="go">
{dedent`
es, err := elasticsearch.NewDefaultClient()
if err != nil {
log.Fatalf("Error creating the client: %s", err)
}
res, err := es.Info()
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
defer res.Body.Close()
log.Println(res)
`}
</EuiCodeBlock>
<EuiSpacer />
{cloudId ? (
<>
<EuiText>
<h4>Connecting to Elastic Cloud</h4>
<p>
If you are using Elastic Cloud, the client offers an easy way to connect to it. You
must pass your Cloud ID to the client, which is found in the Cloud console, as well as
a corresponding API key.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="go">
{dedent`
cfg := elasticsearch.Config{
CloudID: "${cloudId}",
APIKey: "API_KEY"
}
es, err := elasticsearch.NewClient(cfg)
`}
</EuiCodeBlock>
</>
) : (
<>
<EuiText>
<h4>Connecting to Elasticsearch</h4>
<p>
To set the cluster endpoint(s) programmatically, pass a configuration object to the{' '}
<code>elasticsearch.NewClient()</code> function. To set the username and password,
include them in the endpoint URL, or use the corresponding configuration options.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="go">
{dedent`
cfg := elasticsearch.Config{
Addresses: []string{
"http://localhost:9200",
"http://localhost:9201",
},
Username: "<username>",
Password: "<password>",
}
es, err := elasticsearch.NewClient(cfg)
`}
</EuiCodeBlock>
</>
)}
</>
);
};

View file

@ -0,0 +1,107 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchJava: React.FC = () => {
return (
<>
<EuiText>
<p>
The Elasticsearch Java API Client includes all the features you need to add search to a
Java application:
</p>
<ul>
<li>Strongly typed requests and responses for all Elasticsearch APIs.</li>
<li>Blocking and asynchronous versions of all APIs.</li>
<li>
Use of fluent builders and functional patterns to allow writing concise yet readable
code when creating complex nested structures.
</li>
<li>
Seamless integration of application classes by using an object mapper such as Jackson or
any JSON-B implementation.
</li>
</ul>
<EuiLink target="_blank" href={docLinks.clientsJavaIntroduction}>
Learn more about the Elasticsearch JAVA API client
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/elasticsearch-java">
The Elasticsearch JAVA API client on Github
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>
There are several ways to install the Java API client.{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsJavaInstallation}>
Visit the client documentation to learn more
</a>
.
</p>
<h4>Connecting to Elasticsearch</h4>
<p>The client is structured around three main components:</p>
<ul>
<li>
<strong>API client classes.</strong> These provide strongly typed data structures and
methods for Elasticsearch APIs. Since the Elasticsearch API is large, it is structured
in feature groups (also called namespaces), each having its own client class.
Elasticsearch core features are implemented in the ElasticsearchClient class.
</li>
<li>
<strong>A JSON object mapper.</strong> This maps your application classes to JSON and
seamlessly integrates them with the API client.
</li>
<li>
<strong>A transport layer implementation.</strong> This is where all HTTP request
handling takes place.
</li>
</ul>
<p>The code snippet below creates and wires these three components together:</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="java">
{dedent`
// Create the low-level client
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200)).build();
// Create the transport with a Jackson mapper
ElasticsearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
// And create the API client
ElasticsearchClient client = new ElasticsearchClient(transport);
`}
</EuiCodeBlock>
<EuiSpacer size="s" />
<EuiText>
<p>
Authentication is managed by the{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsJavaRestLow}>
Java Low Level REST Client
</a>
. For further details on configuring authentication, refer to{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsJavaBasicAuthentication}>
its documentation
</a>
.
</p>
</EuiText>
</>
);
};

View file

@ -0,0 +1,97 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchJavascript: React.FC<{ cloudId?: string }> = ({ cloudId }) => {
return (
<>
<EuiText>
<p>
This is the official Node.js client for Elasticsearch includes all the features you need
to add search to any Node.js application:
</p>
<ul>
<li>One-to-one mapping with REST API.</li>
<li>Generalized, pluggable architecture.</li>
<li>Configurable, automatic discovery of cluster nodes.</li>
<li>Persistent, Keep-Alive connections.</li>
<li>Load balancing across all available nodes.</li>
<li>Child client support.</li>
<li>TypeScript support out of the box.</li>
</ul>
<EuiLink target="_blank" href={docLinks.clientsJsIntro}>
Learn more about the official Node.js client for Elasticsearch
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/elasticsearch-js">
The official Node.js client for Elasticsearch on Github
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>To install the latest version of the client, run the following command:</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="shell">
npm install @elastic/elasticsearch
</EuiCodeBlock>
<EuiSpacer />
{cloudId ? (
<>
<EuiText>
<h4>Connecting to Elastic Cloud</h4>
<p>
If you are using Elastic Cloud, the client offers an easy way to connect to it via the
cloud option. You must pass the Cloud ID that you can find in the cloud console, then
your username and password inside the auth option.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="javascript">
{dedent`
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
cloud: {
id: '${cloudId}',
},
auth: {
username: '<username>',
password: '<password>'
}
})`}
</EuiCodeBlock>
</>
) : (
<>
<EuiText>
<h4>Connecting to Elasticsearch</h4>
<p>
There are several ways to connect and authenticate to Elasticsearch running outside of
Cloud, including API keys, bearer tokens, and basic authentication.{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsJsClientConnecting}>
Visit the clients documentation to learn more
</a>
.
</p>
</EuiText>
</>
)}
</>
);
};

View file

@ -0,0 +1,113 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchPhp: React.FC<{ cloudId?: string }> = ({ cloudId }) => {
return (
<>
<EuiText>
<p>
This official PHP client for Elasticsearch is designed to be a low-level client that does
not stray from the Elasticsearch REST API.
</p>
<EuiLink target="_blank" href={docLinks.clientsPhpOverview}>
Learn more about the official PHP client for Elasticsearch
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/elasticsearch-php">
The official PHP client for Elasticsearch on Github
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>To install the latest version of the client, run the following command:</p>
<p>Elasticsearch-php only has four requirements that you need to pay attention:</p>
<ul>
<li>PHP 7.1.0 or higher</li>
<li>
<a target="_blank" rel="noopener" href="http://getcomposer.org/">
Composer
</a>
</li>
<li>
<a target="_blank" rel="noopener" href="http://php.net/manual/en/book.curl.php">
ext-curl
</a>
: the Libcurl extension for PHP
</li>
<li>Native JSON Extensions (ext-json) 1.3.7 or higher</li>
</ul>
<p>
The rest of the dependencies are automatically downloaded and installed by Composer.
Composer is a package and dependency manager for PHP and makes it easy to install
Elasticsearch-php.
</p>
<a target="_blank" rel="noopener" href={docLinks.clientsPhpInstallation}>
Visit the documentation for more information.
</a>
</EuiText>
<EuiSpacer />
{cloudId ? (
<>
<EuiText>
<h4>Connecting to Elastic Cloud</h4>
<p>
You can connect to Elastic Cloud using <strong>Basic authentication</strong> or an{' '}
<strong>API key</strong>. Where {'<cloud-id>'} is reported in the Deployment UI. For
basic authentication, {'<username>'} and {'<password>'} are generated when you deploy
a new cloud instance. Youll need to store the {'<username>'} and {'<password>'} since
they will not be available via UI.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="php">
{dedent`
// Connect via basic authentication
$client = ClientBuilder::create()
->setElasticCloudId('${cloudId}')
->setBasicAuthentication('<username>', '<password>')
->build();
// Connect with an API key
$client = ClientBuilder::create()
->setElasticCloudId('${cloudId}')
->setApiKey('<id>', '<key>')
->build();
`}
</EuiCodeBlock>
</>
) : (
<>
<EuiText>
<h4>Connecting to Elasticsearch</h4>
<p>
There are several ways to connect and authenticate to Elasticsearch running outside of
Cloud, including API keys, bearer tokens, and basic authentication.{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsPhpConnecting}>
Visit the clients documentation to learn more
</a>
.
</p>
</EuiText>
</>
)}
</>
);
};

View file

@ -0,0 +1,163 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchPython: React.FC<{ cloudId?: string }> = ({ cloudId }) => {
return (
<>
<EuiText>
<p>
elasticsearch-py, the official Python client for Elasticsearch, is a low-level client for
interacting with Elasticsearchs REST API. Its designed to be unopinionated and
extendable.
</p>
<EuiLink target="_blank" href={docLinks.clientsPythonOverview}>
Learn more about the Python client for Elasticsearch
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://elasticsearch-py.readthedocs.io/">
The Python client for Elasticsearch on Read the Docs
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/elasticsearch-py">
elasticsearch-py on Github
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>
Install the <code>elasticsearch</code> package with{' '}
<a target="_blank" rel="noopener" href="https://pypi.org/project/elasticsearch">
pip
</a>
:
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="shell">
{dedent`
$ python -m pip install elasticsearch
`}
</EuiCodeBlock>
<EuiSpacer />
<EuiText>
<p>
If your application uses async/await in Python you can install the client with the async
extra:
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="shell">
{dedent`
$ python -m pip install elasticsearch[async]
`}
</EuiCodeBlock>
<EuiSpacer size="s" />
<EuiText>
<p>
Learn more about{' '}
<a target="_blank" rel="noopener" href="https://pypi.org/project/elasticsearch">
using asyncio with this project
</a>
.
</p>
</EuiText>
<EuiSpacer />
{cloudId ? (
<>
<EuiText>
<h4>Connecting to Elastic Cloud</h4>
<p>
Cloud ID is an easy way to configure your client to work with your Elastic Cloud
deployment. Combine the cloud_id with either basic_auth or api_key to authenticate
with your Elastic Cloud deployment.
</p>
<p>
Using cloud_id enables TLS verification and HTTP compression by default and sets the
port to 443 unless otherwise overwritten via the port parameter or the port value
encoded within cloud_id. Using Cloud ID also disables sniffing as a proxy is in use.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="python">
{dedent`
from elasticsearch import Elasticsearch
es = Elasticsearch(
cloud_id="${cloudId}"
)
`}
</EuiCodeBlock>
</>
) : (
<>
<EuiText>
<h4>Connecting to Elasticsearch</h4>
<p>
A single node can be specified via a <code>scheme</code>, <code>host</code>,{' '}
<code>port</code>, and optional <code>path_prefix</code>. These values can either be
specified manually via a URL in a string, dictionary,
<code>NodeConfig</code>, or a list of these values. You must specify at least{' '}
<code>scheme</code>, <code>host</code> and <code>port</code>
for each node. All of the following are valid configurations:
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="python">
{dedent`
from elasticsearch import Elasticsearch
# Single node via URL
es = Elasticsearch("http://localhost:9200")
# Multiple nodes via URL
es = Elasticsearch([
"http://localhost:9200",
"http://localhost:9201",
"http://localhost:9202"
])
# Single node via dictionary
es = Elasticsearch({"scheme": "http", "host": "localhost", "port": 9200})
# Multiple nodes via dictionary
es = Elasticsearch([
{"scheme": "http", "host": "localhost", "port": 9200},
{"scheme": "http", "host": "localhost", "port": 9201},
])
`}
</EuiCodeBlock>
<EuiSpacer size="s" />
<EuiText>
<p>
There are several ways to authenticate to Elasticsearch running outside of Cloud,
including API keys, bearer tokens, and basic authentication.{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsPythonAuthentication}>
Visit the clients documentation to learn more
</a>
.
</p>
</EuiText>
</>
)}
</>
);
};

View file

@ -0,0 +1,161 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchRuby: React.FC<{ cloudId?: string }> = ({ cloudId }) => {
return (
<>
<EuiText>
<p>
The <code>elasticsearch</code>{' '}
<a target="_blank" rel="noopener" href="http://rubygems.org/gems/elasticsearch">
Rubygem
</a>{' '}
provides a low-level client for communicating with an Elasticsearch cluster, fully
compatible with other official clients.
</p>
<EuiLink target="_blank" href={docLinks.clientsRubyOverview}>
Learn more about the Ruby client for Elasticsearch
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/elasticsearch-ruby">
The Elasticsearch Ruby client on Github
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="http://rubydoc.info/gems/elasticsearch">
The Elasticsearch Ruby client on RubyDoc
</EuiLink>
<EuiSpacer />
<p>Check out these other official Ruby libraries for working with Elasticsearch:</p>
<ul>
<li>
<a
target="_blank"
rel="noopener"
href="https://github.com/elasticsearch/elasticsearch-rails"
>
elasticsearch-rails
</a>{' '}
- integration with Ruby models and Rails applications.
</li>
<li>
<a
target="_blank"
rel="noopener"
href="https://github.com/elastic/elasticsearch-ruby/tree/7.17/elasticsearch-extensions"
>
elasticsearch-extensions
</a>
, deprecated.
</li>
<li>
<a
target="_blank"
rel="noopener"
href="https://github.com/elastic/elasticsearch-dsl-ruby"
>
elasticsearch-dsl
</a>{' '}
which provides a Ruby API for the{' '}
<a target="_blank" rel="noopener" href={docLinks.queryDsl}>
Elasticsearch Query DSL
</a>
.
</li>
</ul>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>
Install the <code>elasticsearch</code> gem from Rubygems:
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="shell">
{dedent`
$ gem install elasticsearch
`}
</EuiCodeBlock>
<EuiSpacer size="s" />
<EuiText>
<p>Or add it to your projects Gemfile:</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable>
{dedent`
gem 'elasticsearch', '<ELASTICSEARCH_VERSION>'
`}
</EuiCodeBlock>
<EuiSpacer />
{cloudId ? (
<>
<EuiText>
<h4>Connecting to Elastic Cloud</h4>
<p>
If you are using Elastic Cloud, the client offers an easy way to connect to it. You
must pass the Cloud ID that you can find in the cloud console.
</p>
<p>
You can connect to Elastic Cloud using <strong>Basic authentication</strong> or an{' '}
<strong>API key</strong>. Where {'<cloud-id>'} is reported in the Deployment UI. For
basic authentication, {'<username>'} and {'<password>'} are generated when you deploy
a new cloud instance. Youll need to store the {'<username>'} and {'<password>'} since
they will not be available via UI.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable language="ruby">
{dedent`
require 'elasticsearch'
// Connect via basic authentication
client = Elasticsearch::Client.new(
cloud_id: '${cloudId}'
user: '<Username>',
password: '<Password>',
)
// Connect via API key
client = Elasticsearch::Client.new(
cloud_id: '${cloudId}',
api_key: {id: '<Id>', api_key: '<APIKey>'}
)
`}
</EuiCodeBlock>
</>
) : (
<>
<EuiText>
<h4>Connecting to Elasticsearch</h4>
<p>
There are several ways to authenticate to Elasticsearch running outside of Cloud,
including API keys, bearer tokens, and basic authentication.{' '}
<a target="_blank" rel="noopener" href={docLinks.clientsRubyAuthentication}>
Visit the clients documentation to learn more
</a>
.
</p>
</EuiText>
</>
)}
</>
);
};

View file

@ -0,0 +1,89 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import dedent from 'dedent';
import { EuiCodeBlock, EuiLink, EuiText, EuiSpacer } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchRust: React.FC = () => {
return (
<>
<EuiText>
<p>
The official Rust client for Elasticsearch includes all the features you need to add
search to a Rust application:
</p>
<ul>
<li>Fluent builders for all Elasticsearch REST API endpoints</li>
<li>Persistent keep-alive connections</li>
<li>TLS support with system or custom certificates</li>
<li>Proxy support with authentication</li>
<li>Async support with Tokio</li>
</ul>
<EuiLink target="_blank" href={docLinks.clientsRustOverview}>
Learn more about the Rust client for Elasticsearch
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://github.com/elastic/elasticsearch-rs">
The official Rust client for Elasticsearch on Github
</EuiLink>
<EuiSpacer size="m" />
<EuiLink target="_blank" href="https://docs.rs/elasticsearch">
View the documentation on docs.rs
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiText>
<h4>Installation</h4>
<p>
Add <code>elasticsearch</code> crate and version to Cargo.toml.
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable>
{dedent`
[dependencies]
elasticsearch = "<ELASTICSEARCH_VERSION>"
`}
</EuiCodeBlock>
<EuiSpacer size="s" />
<EuiText>
<p>
The following optional dependencies may also be useful to create requests and read
responses
</p>
</EuiText>
<EuiSpacer size="s" />
<EuiCodeBlock fontSize="m" isCopyable>
{dedent`
serde = "~1"
serde_json = "~1"
`}
</EuiCodeBlock>
<EuiSpacer size="s" />
<EuiText>
<p>
The client also includes{' '}
<a
target="_blank"
rel="noopener"
href="https://github.com/elastic/elasticsearch-rs#async-support-with-tokio"
>
async support with tokio
</a>
.
</p>
</EuiText>
</>
);
};

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { ElasticsearchClientInstructions } from './elasticsearch_client_instructions';

View file

@ -0,0 +1,99 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { setMockValues, mockTelemetryActions } from '../../../__mocks__/kea_logic';
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { EuiButtonIcon, EuiCopy, EuiFieldText } from '@elastic/eui';
import { ElasticsearchCloudId } from './';
const execCommandMock = (global.document.execCommand = jest.fn());
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
describe('Elasticsearch Cloud Id', () => {
let wrapper: ShallowWrapper;
beforeEach(() => {
setMockValues({
cloud: {
cloudId: 'example-cloud-id',
deploymentUrl: 'https://cloud.elastic.co/deployments/fake-deployment-id',
},
});
wrapper = shallow(<ElasticsearchCloudId />);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('Visibility conditions', () => {
it('renders panel when cloud id is provided', () => {
expect(wrapper.find('[data-test-subj="CloudIdPanel"]')).toHaveLength(1);
});
it('is hidden when cloud id isnt available', () => {
setMockValues({ cloud: { cloudId: null } });
wrapper = shallow(<ElasticsearchCloudId />);
expect(wrapper.find('[data-test-subj="CloudIdPanel"]')).toHaveLength(0);
});
});
describe('Cloud Id Interactions', () => {
it('should be able copy cloud id', () => {
const field = wrapper.find(EuiFieldText).dive();
expect(field.props()).toEqual(
expect.objectContaining({
readOnly: true,
})
);
expect(field.find('input').props()).toEqual(
expect.objectContaining({
value: 'example-cloud-id',
})
);
const euiCopyHOC = field.dive().find(EuiCopy);
expect(euiCopyHOC.props().textToCopy).toEqual('example-cloud-id');
const copyButton = euiCopyHOC.dive().find(EuiButtonIcon);
expect(copyButton).toHaveLength(1);
execCommandMock.mockImplementationOnce(() => true);
copyButton.simulate('click');
expect(execCommandMock).toHaveBeenCalledWith('copy');
expect(mockTelemetryActions.sendEnterpriseSearchTelemetry).toHaveBeenCalledWith({
action: 'clicked',
metric: 'cloud_id',
});
});
it('should fail gracefully if not allowed to copy', () => {
const field = wrapper.find(EuiFieldText).dive();
const euiCopyHOC = field.dive().find(EuiCopy);
const copyButton = euiCopyHOC.dive().find(EuiButtonIcon);
execCommandMock.mockImplementationOnce(() => false);
copyButton.simulate('click');
expect(execCommandMock).toHaveBeenCalledWith('copy');
expect(warn).toHaveBeenCalledWith('Unable to copy to clipboard.');
expect(mockTelemetryActions.sendEnterpriseSearchTelemetry).toHaveBeenCalled();
});
it('should present a manage link to deployment screen', () => {
const manageLink = wrapper.find('[data-test-subj="cloudManageLink"]');
expect(manageLink).toHaveLength(1);
expect(manageLink.props().href).toEqual(
'https://cloud.elastic.co/deployments/fake-deployment-id'
);
});
});
});

View file

@ -0,0 +1,149 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { useActions, useValues } from 'kea';
import {
EuiButton,
EuiButtonIcon,
EuiCopy,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
EuiForm,
EuiFormRow,
EuiLink,
EuiPanel,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { HttpLogic } from '../../../shared/http';
import { KibanaLogic } from '../../../shared/kibana';
import { TelemetryLogic } from '../../../shared/telemetry';
import { SendTelemetryHelper } from '../../../shared/telemetry/telemetry_logic';
const onFocusHandler = (e: React.FocusEvent<HTMLInputElement>): void => {
e.target.select();
};
interface CloudDetails {
cloudId: string | undefined;
deploymentUrl: string | undefined;
}
const useCloudDetails = (): CloudDetails => {
const { cloud } = useValues(KibanaLogic);
return {
cloudId: cloud?.cloudId,
deploymentUrl: cloud?.deploymentUrl,
};
};
const copyCloudIdHandler = (
copy: () => void,
sendTelemetry: ({ action, metric }: SendTelemetryHelper) => void
) => {
return () => {
copy();
sendTelemetry({
action: 'clicked',
metric: 'cloud_id',
});
};
};
export const ElasticsearchCloudId: React.FC = () => {
const cloud = useCloudDetails();
const { sendEnterpriseSearchTelemetry } = useActions(TelemetryLogic);
const { http } = useValues(HttpLogic);
// hide the panel when no cloud context is available
if (!cloud.cloudId) {
return null;
}
return (
<EuiPanel color="subdued" grow={false} data-test-subj="CloudIdPanel">
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center" responsive>
<EuiFlexItem>
<EuiFlexGroup gutterSize="s" alignItems="center" responsive={false}>
<EuiFlexItem>
<EuiTitle size={'xs'}>
<h2>
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchCloudId.heading', {
defaultMessage: 'My Deployment',
})}
</h2>
</EuiTitle>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiLink href={cloud.deploymentUrl} target="_blank" data-test-subj="cloudManageLink">
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchCloudId.manageLink', {
defaultMessage: 'Manage',
})}
</EuiLink>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup direction="column" gutterSize="m">
<EuiFlexItem>
<EuiForm component="form">
<EuiFormRow
label={i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchCloudId.cloudIdLabel',
{
defaultMessage: 'Cloud ID',
}
)}
>
<EuiFieldText
onFocus={onFocusHandler}
value={cloud.cloudId}
compressed
readOnly
append={
<EuiCopy textToCopy={cloud.cloudId}>
{(copy) => (
<EuiButtonIcon
iconType={'copyClipboard'}
onClick={copyCloudIdHandler(copy, sendEnterpriseSearchTelemetry)}
iconSize="m"
data-test-subj="CopyCloudIdButton"
aria-label={i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchCloudId.copyCloudIdAriaLabel',
{
defaultMessage: 'Copy Cloud ID',
}
)}
/>
)}
</EuiCopy>
}
/>
</EuiFormRow>
</EuiForm>
</EuiFlexItem>
<EuiFlexItem>
<EuiButton href={`${http.basePath.publicBaseUrl}/app/management/security/api_keys`}>
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchCloudId.manageApiKeysLink',
{
defaultMessage: 'Manage API keys',
}
)}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
);
};

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { ElasticsearchCloudId } from './elasticsearch_cloud_id';

View file

@ -0,0 +1,198 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useEffect, useState } from 'react';
import queryString from 'query-string';
import {
EuiPageTemplate,
EuiText,
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiSteps,
EuiSelect,
EuiLink,
useGeneratedHtmlId,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { docLinks } from '../../../shared/doc_links';
import { ElasticsearchClientInstructions } from '../elasticsearch_client_instructions';
import { ElasticsearchCloudId } from '../elasticsearch_cloud_id';
import { ElasticsearchResources } from '../elasticsearch_resources';
// Replace FormattedMessage with i18n strings
export const ElasticsearchGuide: React.FC = () => {
const languages = [
{ value: 'dotnet', text: '.Net' },
{ value: 'go', text: 'Go' },
{ value: 'java', text: 'Java' },
{ value: 'javascript', text: 'JavaScript' },
{ value: 'php', text: 'PHP' },
{ value: 'python', text: 'Python' },
{ value: 'ruby', text: 'Ruby' },
{ value: 'rust', text: 'Rust' },
];
const client = queryString.parse(window.location.search).client;
const languageExists = languages.some((language) => language.value === client);
const [selectedLanguage, setSelectedLanguage] = useState(
languageExists ? (client as string) : 'java'
);
const basicSelectId = useGeneratedHtmlId({ prefix: 'languageSelect' });
const onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setSelectedLanguage(e.target.value);
};
// TODO: The page keeps the scroll position if being opened from Enterpise Search Overview,
// This is a temporary solution for demoing
useEffect(() => {
window.scrollTo(0, 0);
}, []);
return (
<EuiPageTemplate>
<EuiFlexGroup alignItems="flexStart">
{/* maxWidth is needed to prevent code blocks with long unbreakable strings (Kibana PR Cloud ID) from stretching the column */}
<EuiFlexItem grow={3} style={{ maxWidth: 800 }}>
<EuiText>
<h2>
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchTitle',
{
defaultMessage: 'Getting started with Elasticsearch',
}
)}
</h2>
<p>
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchDescription',
{
defaultMessage:
'Whether you are building a search-powered application, or designing a large-scale search implementation, Elasticsearch provides the low-level tools to create the most relevant and performant search experience.',
}
)}
</p>
</EuiText>
<EuiSpacer />
<EuiSteps
headingElement="h2"
steps={[
{
title: i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.connectToElasticsearchTitle',
{ defaultMessage: 'Connect to Elasticsearch' }
),
children: (
<>
<EuiText>
<p>
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.connectToElasticsearchDescription',
{
defaultMessage:
"Elastic builds and maintains clients in several popular languages and our community has contributed many more. They're easy to work with, feel natural to use, and, just like Elasticsearch, don't limit what you might want to do with them.",
}
)}
</p>
<EuiLink href={docLinks.clientsGuide} target="_blank">
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchClientsLink',
{ defaultMessage: 'Learn more about Elasticsearch clients' }
)}
</EuiLink>
</EuiText>
<EuiSpacer />
<EuiSelect
prepend={i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchClientsSelectLabel',
{ defaultMessage: 'Select a client' }
)}
id={basicSelectId}
options={languages}
value={selectedLanguage}
onChange={(e) => onChange(e)}
aria-label={i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchClientsSelectAriaLabel',
{ defaultMessage: 'Language client' }
)}
/>
<EuiSpacer size="m" />
<ElasticsearchClientInstructions language={selectedLanguage} />
</>
),
},
{
title: i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchSearchExperienceTitle',
{ defaultMessage: 'Build a search experience with Elasticsearch' }
),
children: (
<>
<EuiText>
<p>
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchSearchExperienceDescription',
{
defaultMessage:
'Ready to add an engaging, modern search experience to your application or website? Search UI, Elastics JavaScript search framework for building world-class search experiences, was made for the task.',
}
)}
</p>
</EuiText>
<EuiSpacer size="l" />
<EuiFlexGroup gutterSize="l" alignItems="center">
<EuiFlexItem grow={false}>
<EuiText>
<EuiLink
href="https://www.elastic.co/enterprise-search/search-ui"
target="_blank"
>
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchSearchUIMarketingLink',
{ defaultMessage: 'Learn more about Search UI' }
)}
</EuiLink>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText>
<EuiLink href="https://github.com/elastic/search-ui" target="_blank">
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchGuide.elasticsearchSearchUIGitHubLink',
{ defaultMessage: 'Search UI on GitHub' }
)}
</EuiLink>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</>
),
},
]}
/>
</EuiFlexItem>
<EuiFlexItem grow={1}>
<ElasticsearchCloudId />
<EuiSpacer />
<ElasticsearchResources />
</EuiFlexItem>
</EuiFlexGroup>
</EuiPageTemplate>
);
};

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { ElasticsearchGuide } from './elasticsearch_guide';

View file

@ -0,0 +1,57 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiSpacer, EuiPanel, EuiTitle, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { docLinks } from '../../../shared/doc_links';
export const ElasticsearchResources: React.FC = () => (
<EuiPanel hasShadow={false} color="subdued">
<EuiTitle size="xs">
<h4>
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchResources.title', {
defaultMessage: 'Resources',
})}
</h4>
</EuiTitle>
<EuiSpacer size="s" />
<EuiSpacer size="xs" />
<EuiLink href={docLinks.elasticsearchGettingStarted} target="_blank">
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchResources.gettingStarted', {
defaultMessage: 'Getting started with Elasticsearch',
})}
</EuiLink>
<EuiSpacer size="s" />
<EuiSpacer size="xs" />
<EuiLink href={docLinks.elasticsearchCreateIndex} target="_blank">
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchResources.createIndex', {
defaultMessage: 'Create a new index',
})}
</EuiLink>
<EuiSpacer size="s" />
<EuiSpacer size="xs" />
<EuiLink href={docLinks.clientsGuide} target="_blank">
{i18n.translate(
'xpack.enterpriseSearch.overview.elasticsearchResources.elasticsearchClients',
{ defaultMessage: 'Elasticsearch clients' }
)}
</EuiLink>
<EuiSpacer size="s" />
<EuiSpacer size="xs" />
<EuiLink
href="https://github.com/elastic/search-ui/tree/master/packages/search-ui-elasticsearch-connector"
target="_blank"
>
{i18n.translate('xpack.enterpriseSearch.overview.elasticsearchResources.searchUi', {
defaultMessage: 'Search UI for Elasticsearch',
})}
</EuiLink>
</EuiPanel>
);

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { ElasticsearchResources } from './elasticsearch_resources';

View file

@ -36,6 +36,7 @@ import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/
import AppSearchImage from '../../assets/app_search.png';
import WorkplaceSearchImage from '../../assets/workplace_search.png';
import { ElasticsearchCard } from '../elasticsearch_card';
import { LicenseCallout } from '../license_callout';
import { ProductCard } from '../product_card';
import { SetupGuideCta } from '../setup_guide';
@ -91,6 +92,10 @@ export const ProductSelector: React.FC<ProductSelectorProps> = ({
<EuiSpacer size="xxl" />
<ElasticsearchCard />
<EuiSpacer size="xxl" />
{config.host ? <LicenseCallout /> : <SetupGuideCta />}
</>
);

View file

@ -16,10 +16,11 @@ import { HttpLogic } from '../shared/http';
import { KibanaLogic } from '../shared/kibana';
import { VersionMismatchPage } from '../shared/version_mismatch';
import { ElasticsearchGuide } from './components/elasticsearch_guide';
import { ErrorConnecting } from './components/error_connecting';
import { ProductSelector } from './components/product_selector';
import { SetupGuide } from './components/setup_guide';
import { ROOT_PATH, SETUP_GUIDE_PATH } from './routes';
import { ROOT_PATH, SETUP_GUIDE_PATH, ELASTICSEARCH_GUIDE_PATH } from './routes';
export const EnterpriseSearchOverview: React.FC<InitialAppData> = ({
access = {},
@ -56,6 +57,9 @@ export const EnterpriseSearchOverview: React.FC<InitialAppData> = ({
<Route exact path={SETUP_GUIDE_PATH}>
<SetupGuide />
</Route>
<Route exact path={ELASTICSEARCH_GUIDE_PATH}>
<ElasticsearchGuide />
</Route>
<Route exact path={ROOT_PATH}>
{showView()}
</Route>

View file

@ -7,3 +7,4 @@
export const ROOT_PATH = '/';
export const SETUP_GUIDE_PATH = '/setup_guide';
export const ELASTICSEARCH_GUIDE_PATH = '/elasticsearch_guide';

View file

@ -29,13 +29,35 @@ class DocLinks {
public appSearchSynonyms: string;
public appSearchWebCrawler: string;
public appSearchWebCrawlerEventLogs: string;
public clientsGoIndex: string;
public clientsGuide: string;
public clientsJavaBasicAuthentication: string;
public clientsJavaInstallation: string;
public clientsJavaIntroduction: string;
public clientsJavaRestLow: string;
public clientsJsClientConnecting: string;
public clientsJsIntro: string;
public clientsNetIntroduction: string;
public clientsNetNest: string;
public clientsNetSingleNode: string;
public clientsPhpConnecting: string;
public clientsPhpInstallation: string;
public clientsPhpOverview: string;
public clientsPythonAuthentication: string;
public clientsPythonOverview: string;
public clientsRubyAuthentication: string;
public clientsRubyOverview: string;
public clientsRustOverview: string;
public cloudIndexManagement: string;
public elasticsearchCreateIndex: string;
public elasticsearchGettingStarted: string;
public enterpriseSearchConfig: string;
public enterpriseSearchMailService: string;
public enterpriseSearchTroubleshootSetup: string;
public enterpriseSearchUsersAccess: string;
public kibanaSecurity: string;
public licenseManagement: string;
public queryDsl: string;
public workplaceSearchApiKeys: string;
public workplaceSearchBox: string;
public workplaceSearchConfluenceCloud: string;
@ -86,13 +108,35 @@ class DocLinks {
this.appSearchSynonyms = '';
this.appSearchWebCrawler = '';
this.appSearchWebCrawlerEventLogs = '';
this.clientsGoIndex = '';
this.clientsGuide = '';
this.clientsJavaBasicAuthentication = '';
this.clientsJavaInstallation = '';
this.clientsJavaIntroduction = '';
this.clientsJavaRestLow = '';
this.clientsJsIntro = '';
this.clientsJsClientConnecting = '';
this.clientsNetIntroduction = '';
this.clientsNetNest = '';
this.clientsNetSingleNode = '';
this.clientsPhpConnecting = '';
this.clientsPhpInstallation = '';
this.clientsPhpOverview = '';
this.clientsPythonAuthentication = '';
this.clientsPythonOverview = '';
this.clientsRubyAuthentication = '';
this.clientsRubyOverview = '';
this.clientsRustOverview = '';
this.cloudIndexManagement = '';
this.elasticsearchCreateIndex = '';
this.elasticsearchGettingStarted = '';
this.enterpriseSearchConfig = '';
this.enterpriseSearchMailService = '';
this.enterpriseSearchTroubleshootSetup = '';
this.enterpriseSearchUsersAccess = '';
this.kibanaSecurity = '';
this.licenseManagement = '';
this.queryDsl = '';
this.workplaceSearchApiKeys = '';
this.workplaceSearchBox = '';
this.workplaceSearchConfluenceCloud = '';
@ -144,13 +188,35 @@ class DocLinks {
this.appSearchSynonyms = docLinks.links.appSearch.synonyms;
this.appSearchWebCrawler = docLinks.links.appSearch.webCrawler;
this.appSearchWebCrawlerEventLogs = docLinks.links.appSearch.webCrawlerEventLogs;
this.clientsGoIndex = docLinks.links.clients.goIndex;
this.clientsGuide = docLinks.links.clients.guide;
this.clientsJavaBasicAuthentication = docLinks.links.clients.javaBasicAuthentication;
this.clientsJavaInstallation = docLinks.links.clients.javaInstallation;
this.clientsJavaIntroduction = docLinks.links.clients.javaIntroduction;
this.clientsJavaRestLow = docLinks.links.clients.javaRestLow;
this.clientsJsClientConnecting = docLinks.links.clients.jsClientConnecting;
this.clientsJsIntro = docLinks.links.clients.jsIntro;
this.clientsNetIntroduction = docLinks.links.clients.netIntroduction;
this.clientsNetNest = docLinks.links.clients.netNest;
this.clientsNetSingleNode = docLinks.links.clients.netSingleNode;
this.clientsPhpConnecting = docLinks.links.clients.phpConnecting;
this.clientsPhpInstallation = docLinks.links.clients.phpInstallation;
this.clientsPhpOverview = docLinks.links.clients.phpOverview;
this.clientsPythonAuthentication = docLinks.links.clients.pythonAuthentication;
this.clientsPythonOverview = docLinks.links.clients.pythonOverview;
this.clientsRubyAuthentication = docLinks.links.clients.rubyAuthentication;
this.clientsRubyOverview = docLinks.links.clients.rubyOverview;
this.clientsRustOverview = docLinks.links.clients.rustOverview;
this.cloudIndexManagement = docLinks.links.cloud.indexManagement;
this.elasticsearchCreateIndex = docLinks.links.elasticsearch.createIndex;
this.elasticsearchGettingStarted = docLinks.links.elasticsearch.gettingStarted;
this.enterpriseSearchConfig = docLinks.links.enterpriseSearch.configuration;
this.enterpriseSearchMailService = docLinks.links.enterpriseSearch.mailService;
this.enterpriseSearchTroubleshootSetup = docLinks.links.enterpriseSearch.troubleshootSetup;
this.enterpriseSearchUsersAccess = docLinks.links.enterpriseSearch.usersAccess;
this.kibanaSecurity = docLinks.links.kibana.xpackSecurity;
this.licenseManagement = docLinks.links.enterpriseSearch.licenseManagement;
this.queryDsl = docLinks.links.query.queryDsl;
this.workplaceSearchApiKeys = docLinks.links.workplaceSearch.apiKeys;
this.workplaceSearchBox = docLinks.links.workplaceSearch.box;
this.workplaceSearchConfluenceCloud = docLinks.links.workplaceSearch.confluenceCloud;