-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Remote clusters] Cloud deployment form when adding new cluster #93953
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
/* | ||
* 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, { FunctionComponent, useState } from 'react'; | ||
|
||
import { i18n } from '@kbn/i18n'; | ||
import { FormattedMessage } from '@kbn/i18n/react'; | ||
import { | ||
EuiAccordion, | ||
EuiButton, | ||
EuiButtonEmpty, | ||
EuiFieldText, | ||
EuiFlexGroup, | ||
EuiFlexItem, | ||
EuiFlyout, | ||
EuiFlyoutBody, | ||
EuiFlyoutFooter, | ||
EuiFlyoutHeader, | ||
EuiFormRow, | ||
EuiIcon, | ||
EuiImage, | ||
EuiLink, | ||
EuiSpacer, | ||
EuiText, | ||
EuiTitle, | ||
} from '@elastic/eui'; | ||
import { useAppContext } from '../../../app_context'; | ||
import { | ||
convertCloudUrlToProxyConnection, | ||
validateCloudUrl, | ||
} from '../../../services/cloud_deployment_url'; | ||
|
||
import { cloudRemoteClustersUrl } from '../../../services/documentation'; | ||
|
||
// @ts-ignore | ||
import Screenshot from './cloud_deployment_screenshot.png'; | ||
|
||
interface Props { | ||
onClose: () => void; | ||
onClusterConfigure: (value: { proxyAddress: string; serverName: string }) => void; | ||
} | ||
|
||
// TODO copy review | ||
export const CloudDeploymentForm: FunctionComponent<Props> = ({ onClose, onClusterConfigure }) => { | ||
const [cloudDeploymentUrl, setCloudDeploymentUrl] = useState<string>(''); | ||
const [error, setError] = useState<string | null>(null); | ||
const { cloudDeploymentUrl: accountLink } = useAppContext(); | ||
|
||
const configureCluster = () => { | ||
const urlError: string | null = validateCloudUrl(cloudDeploymentUrl); | ||
if (urlError) { | ||
setError(urlError); | ||
} else { | ||
onClose(); | ||
onClusterConfigure(convertCloudUrlToProxyConnection(cloudDeploymentUrl)); | ||
} | ||
}; | ||
return ( | ||
<EuiFlyout onClose={() => onClose()}> | ||
<EuiFlyoutHeader hasBorder> | ||
<EuiTitle> | ||
<h2> | ||
<EuiFlexGroup alignItems="center" gutterSize="s"> | ||
<EuiFlexItem grow={false}> | ||
<EuiIcon type="logoCloud" size="l" /> | ||
</EuiFlexItem> | ||
|
||
<EuiFlexItem> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.formTitle" | ||
defaultMessage=" Add Cloud deployment as remote cluster" | ||
/> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</h2> | ||
</EuiTitle> | ||
</EuiFlyoutHeader> | ||
<EuiFlyoutBody> | ||
<EuiText> | ||
<p> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.formDescription" | ||
defaultMessage="If you're connecting to a Cloud deployment, you can copy and paste the Elasticsearch | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We know this is cloud deployment (we don't support any other option) so I think the text can be more instructive. Text suggestion: "Copy and paste the Elasticsearch endpoint URL of the remote deployment to automatically configure the remote cluster. The URL can be found on the remote deployment overview page." |
||
endpoint URL into the field below. The remote cluster will be automatically configured to connect to the Cloud deployment." | ||
/> | ||
</p> | ||
</EuiText> | ||
|
||
<EuiSpacer /> | ||
|
||
<EuiAccordion | ||
id="cloudDeploymentScreenshot" | ||
buttonContent={i18n.translate( | ||
'xpack.remoteClusters.cloudDeploymentForm.screenshotButtonLabel', | ||
{ defaultMessage: 'Expand for a screenshot' } | ||
)} | ||
> | ||
<EuiImage url={Screenshot} alt="Screenshot of Cloud deployment url link" /> | ||
</EuiAccordion> | ||
|
||
<EuiSpacer /> | ||
|
||
<EuiFormRow | ||
fullWidth={true} | ||
isInvalid={!!error} | ||
error={error} | ||
label={ | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.inputLabel" | ||
defaultMessage="Elasticsearch endpoint URL" | ||
/> | ||
} | ||
> | ||
<EuiFieldText | ||
isInvalid={!!error} | ||
fullWidth={true} | ||
value={cloudDeploymentUrl} | ||
onChange={(e) => setCloudDeploymentUrl(e.target.value)} | ||
/> | ||
</EuiFormRow> | ||
|
||
<EuiSpacer /> | ||
|
||
<EuiText color="subdued"> | ||
<p> | ||
<i> | ||
<strong> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.aliasNoteLabel" | ||
defaultMessage="Note: " | ||
/> | ||
</strong> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.aliasNoteDescription" | ||
defaultMessage="If you configured a deployment alias in Elastic Cloud, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "If you configured a deployment alias, either in Elastic Cloud, in your reverse proxy or load-balancer, you will need to copy-paste the Proxy address and Server name or the remote deployment in the remote cluster form directly. These values can be copied from the Remote parameters section on the remote deployment Security page. More information is available here". As you mentioned, we can't point to the relevant security page so I think we need to only keep the link to our user guide. @shubhaat are we going to call this feature deployment alias or configurable deployment endpoints? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @shubhaat ! Heads up @yuliacech @cjcenizal et al that when using the alias in the URL and changing the alias things will break. That's expected since changing the alias requires changing clients, integrations, etc. Just want to raise it in the context of a need to handle what happens when we can't connect to the cluster during and after creation. One of the benefits of using a UUID is that it never changes. |
||
in your own load balancer or reverse proxy, you will need to copy the deployment | ||
proxy address and server name from the Remote cluster parameters section in | ||
the {securityPageLink} and paste them in the form directly. " | ||
values={{ | ||
securityPageLink: ( | ||
<EuiLink href={`${accountLink}${'/security'}`} target="_blank" external={true}> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.cloudDeploymentLink" | ||
defaultMessage="Security page" | ||
/> | ||
</EuiLink> | ||
), | ||
}} | ||
/> | ||
<EuiLink href={cloudRemoteClustersUrl} target="_blank" external={true}> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.aliasDocsLink" | ||
defaultMessage="Learn more" | ||
/> | ||
</EuiLink> | ||
</i> | ||
</p> | ||
</EuiText> | ||
</EuiFlyoutBody> | ||
<EuiFlyoutFooter> | ||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center"> | ||
<EuiFlexItem grow={false}> | ||
<EuiButtonEmpty iconType="cross" flush="left" onClick={onClose}> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.closeButtonLabel" | ||
defaultMessage="Close" | ||
/> | ||
</EuiButtonEmpty> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<EuiButton fill color="primary" onClick={configureCluster}> | ||
<FormattedMessage | ||
id="xpack.remoteClusters.cloudDeploymentForm.configureClusterButtonLabel" | ||
defaultMessage="Configure cluster" | ||
/> | ||
</EuiButton> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiFlyoutFooter> | ||
</EuiFlyout> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { CloudDeploymentForm } from './cloud_deployment_form'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { | ||
validateCloudUrl, | ||
convertCloudUrlToProxyConnection, | ||
i18nTexts, | ||
} from './cloud_deployment_url'; | ||
describe('Cloud deployment url', () => { | ||
describe('validation', () => { | ||
it('errors when the url is empty', () => { | ||
const actual = validateCloudUrl(''); | ||
expect(actual).toBe(i18nTexts.urlInvalid); | ||
}); | ||
|
||
it('errors when the url is invalid', () => { | ||
const actual = validateCloudUrl('invalid%url'); | ||
expect(actual).toBe(i18nTexts.urlInvalid); | ||
}); | ||
}); | ||
|
||
describe('conversion', () => { | ||
it('empty url to empty proxy connection values', () => { | ||
const actual = convertCloudUrlToProxyConnection(''); | ||
expect(actual).toEqual({ proxyAddress: '', serverName: '' }); | ||
}); | ||
|
||
it('url with protocol and port to proxy connection values', () => { | ||
const actual = convertCloudUrlToProxyConnection('http://test.com:1234'); | ||
expect(actual).toEqual({ proxyAddress: 'test.com:9400', serverName: 'test.com' }); | ||
}); | ||
|
||
it('url with protocol and no port to proxy connection values', () => { | ||
const actual = convertCloudUrlToProxyConnection('http://test.com'); | ||
expect(actual).toEqual({ proxyAddress: 'test.com:9400', serverName: 'test.com' }); | ||
}); | ||
|
||
it('url with no protocol to proxy connection values', () => { | ||
const actual = convertCloudUrlToProxyConnection('test.com'); | ||
expect(actual).toEqual({ proxyAddress: 'test.com:9400', serverName: 'test.com' }); | ||
}); | ||
it('invalid url to empty proxy connection values', () => { | ||
const actual = convertCloudUrlToProxyConnection('invalid%url'); | ||
expect(actual).toEqual({ proxyAddress: '', serverName: '' }); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be "Add Cloud deployment as a remote cluster", no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should it say "Elastic Cloud"?