Skip to content

Commit

Permalink
[Ingest Manager] Add UI to enroll standalone agent (#71288)
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet authored Jul 13, 2020
1 parent 24edc80 commit 17dc043
Show file tree
Hide file tree
Showing 13 changed files with 516 additions and 163 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const CONFIG_KEYS_ORDER = [
'name',
'revision',
'type',
'settings',
'outputs',
'settings',
'inputs',
'enabled',
'use_output',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ export const useGetOneAgentConfigFull = (agentConfigId: string) => {
});
};

export const sendGetOneAgentConfigFull = (
agentConfigId: string,
query: { standalone?: boolean } = {}
) => {
return sendRequest<GetFullAgentConfigResponse>({
path: agentConfigRouteService.getInfoFullPath(agentConfigId),
method: 'get',
query,
});
};

export const sendGetOneAgentConfig = (agentConfigId: string) => {
return sendRequest<GetOneAgentConfigResponse>({
path: agentConfigRouteService.getInfoPath(agentConfigId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ export function sendDeleteOneEnrollmentAPIKey(keyId: string, options?: RequestOp
});
}

export function sendGetEnrollmentAPIKeys(
query: GetEnrollmentAPIKeysRequest['query'],
options?: RequestOptions
) {
return sendRequest<GetEnrollmentAPIKeysResponse>({
method: 'get',
path: enrollmentAPIKeyRouteService.getListPath(),
query,
...options,
});
}

export function useGetEnrollmentAPIKeys(
query: GetEnrollmentAPIKeysRequest['query'],
options?: RequestOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,99 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiSelect, EuiSpacer, EuiText, EuiButtonEmpty } from '@elastic/eui';
import { AgentConfig } from '../../../../types';
import { useGetEnrollmentAPIKeys } from '../../../../hooks';
import { AgentConfig, GetEnrollmentAPIKeysResponse } from '../../../../types';
import { sendGetEnrollmentAPIKeys, useCore } from '../../../../hooks';
import { AgentConfigPackageBadges } from '../agent_config_package_badges';

interface Props {
type Props = {
agentConfigs: AgentConfig[];
onKeyChange: (key: string) => void;
}
onConfigChange?: (key: string) => void;
} & (
| {
withKeySelection: true;
onKeyChange?: (key: string) => void;
}
| {
withKeySelection: false;
}
);

export const EnrollmentStepAgentConfig: React.FC<Props> = ({ agentConfigs, onKeyChange }) => {
const [isAuthenticationSettingsOpen, setIsAuthenticationSettingsOpen] = useState(false);
const enrollmentAPIKeysRequest = useGetEnrollmentAPIKeys({
page: 1,
perPage: 1000,
});
export const EnrollmentStepAgentConfig: React.FC<Props> = (props) => {
const { notifications } = useCore();
const { withKeySelection, agentConfigs, onConfigChange } = props;
const onKeyChange = props.withKeySelection && props.onKeyChange;

const [isAuthenticationSettingsOpen, setIsAuthenticationSettingsOpen] = useState(false);
const [enrollmentAPIKeys, setEnrollmentAPIKeys] = useState<GetEnrollmentAPIKeysResponse['list']>(
[]
);
const [selectedState, setSelectedState] = useState<{
agentConfigId?: string;
enrollmentAPIKeyId?: string;
}>({
agentConfigId: agentConfigs.length ? agentConfigs[0].id : undefined,
});
const filteredEnrollmentAPIKeys = React.useMemo(() => {
if (!selectedState.agentConfigId || !enrollmentAPIKeysRequest.data) {
return [];

useEffect(() => {
if (onConfigChange && selectedState.agentConfigId) {
onConfigChange(selectedState.agentConfigId);
}
}, [selectedState.agentConfigId, onConfigChange]);

return enrollmentAPIKeysRequest.data.list.filter(
(key) => key.config_id === selectedState.agentConfigId
);
}, [enrollmentAPIKeysRequest.data, selectedState.agentConfigId]);
useEffect(() => {
if (!withKeySelection) {
return;
}
if (!selectedState.agentConfigId) {
setEnrollmentAPIKeys([]);
return;
}

async function fetchEnrollmentAPIKeys() {
try {
const res = await sendGetEnrollmentAPIKeys({
page: 1,
perPage: 10000,
});
if (res.error) {
throw res.error;
}

if (!res.data) {
throw new Error('No data while fetching enrollment API keys');
}

setEnrollmentAPIKeys(
res.data.list.filter((key) => key.config_id === selectedState.agentConfigId)
);
} catch (error) {
notifications.toasts.addError(error, {
title: 'Error',
});
}
}
fetchEnrollmentAPIKeys();
}, [withKeySelection, selectedState.agentConfigId, notifications.toasts]);

// Select first API key when config change
React.useEffect(() => {
if (!selectedState.enrollmentAPIKeyId && filteredEnrollmentAPIKeys.length > 0) {
const enrollmentAPIKeyId = filteredEnrollmentAPIKeys[0].id;
if (!withKeySelection || !onKeyChange) {
return;
}
if (!selectedState.enrollmentAPIKeyId && enrollmentAPIKeys.length > 0) {
const enrollmentAPIKeyId = enrollmentAPIKeys[0].id;
setSelectedState({
agentConfigId: selectedState.agentConfigId,
enrollmentAPIKeyId,
});
onKeyChange(enrollmentAPIKeyId);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filteredEnrollmentAPIKeys, selectedState.enrollmentAPIKeyId, selectedState.agentConfigId]);
}, [enrollmentAPIKeys, selectedState.enrollmentAPIKeyId, selectedState.agentConfigId]);

return (
<>
Expand Down Expand Up @@ -85,43 +130,47 @@ export const EnrollmentStepAgentConfig: React.FC<Props> = ({ agentConfigs, onKey
{selectedState.agentConfigId && (
<AgentConfigPackageBadges agentConfigId={selectedState.agentConfigId} />
)}
<EuiSpacer size="m" />
<EuiButtonEmpty
flush="left"
iconType={isAuthenticationSettingsOpen ? 'arrowDown' : 'arrowRight'}
onClick={() => setIsAuthenticationSettingsOpen(!isAuthenticationSettingsOpen)}
>
<FormattedMessage
id="xpack.ingestManager.enrollmentStepAgentConfig.showAuthenticationSettingsButton"
defaultMessage="Authentication settings"
/>
</EuiButtonEmpty>
{isAuthenticationSettingsOpen && (
{withKeySelection && onKeyChange && (
<>
<EuiSpacer size="m" />
<EuiSelect
fullWidth
options={filteredEnrollmentAPIKeys.map((key) => ({
value: key.id,
text: key.name,
}))}
value={selectedState.enrollmentAPIKeyId || undefined}
prepend={
<EuiText>
<FormattedMessage
id="xpack.ingestManager.enrollmentStepAgentConfig.enrollmentTokenSelectLabel"
defaultMessage="Enrollment token"
/>
</EuiText>
}
onChange={(e) => {
setSelectedState({
...selectedState,
enrollmentAPIKeyId: e.target.value,
});
onKeyChange(e.target.value);
}}
/>
<EuiButtonEmpty
flush="left"
iconType={isAuthenticationSettingsOpen ? 'arrowDown' : 'arrowRight'}
onClick={() => setIsAuthenticationSettingsOpen(!isAuthenticationSettingsOpen)}
>
<FormattedMessage
id="xpack.ingestManager.enrollmentStepAgentConfig.showAuthenticationSettingsButton"
defaultMessage="Authentication settings"
/>
</EuiButtonEmpty>
{isAuthenticationSettingsOpen && (
<>
<EuiSpacer size="m" />
<EuiSelect
fullWidth
options={enrollmentAPIKeys.map((key) => ({
value: key.id,
text: key.name,
}))}
value={selectedState.enrollmentAPIKeyId || undefined}
prepend={
<EuiText>
<FormattedMessage
id="xpack.ingestManager.enrollmentStepAgentConfig.enrollmentTokenSelectLabel"
defaultMessage="Enrollment token"
/>
</EuiText>
}
onChange={(e) => {
setSelectedState({
...selectedState,
enrollmentAPIKeyId: e.target.value,
});
onKeyChange(e.target.value);
}}
/>
</>
)}
</>
)}
</>
Expand Down
Loading

0 comments on commit 17dc043

Please sign in to comment.