Skip to content

Commit

Permalink
[Fleet] Do not allow user to add agent to managed policy (elastic#122676
Browse files Browse the repository at this point in the history
)

(cherry picked from commit 5f76e79)
  • Loading branch information
nchaulet authored and kibanamachine committed Jan 11, 2022
1 parent ecfd50b commit 39c2f9e
Show file tree
Hide file tree
Showing 6 changed files with 379 additions and 210 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 { HeaderLeftContent } from './left_content';
export { HeaderRightContent } from './right_content';
Original file line number Diff line number Diff line change
@@ -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 { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import {
EuiFlexGroup,
EuiIconTip,
EuiFlexItem,
EuiButtonEmpty,
EuiTitle,
EuiSpacer,
EuiText,
} from '@elastic/eui';

import { useLink } from '../../../../../hooks';
import type { AgentPolicy } from '../../../../../types';
import { Loading } from '../../../../../components';

interface HeaderLeftContentProps {
isLoading: boolean;
policyId: string;
agentPolicy?: AgentPolicy | null;
}

export const HeaderLeftContent: React.FunctionComponent<HeaderLeftContentProps> = ({
isLoading,
policyId,
agentPolicy,
}) => {
const { getHref } = useLink();

return (
<EuiFlexGroup direction="column" gutterSize="s" alignItems="flexStart">
<EuiFlexItem>
<EuiButtonEmpty iconType="arrowLeft" href={getHref('policies_list')} flush="left" size="xs">
<FormattedMessage
id="xpack.fleet.policyDetails.viewAgentListTitle"
defaultMessage="View all agent policies"
/>
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem>
{isLoading ? (
<Loading />
) : (
<EuiFlexGroup alignItems="center" wrap responsive={false} gutterSize="s">
<EuiFlexItem>
<EuiTitle>
<h1>
{(agentPolicy && agentPolicy.name) || (
<FormattedMessage
id="xpack.fleet.policyDetails.policyDetailsTitle"
defaultMessage="Policy '{id}'"
values={{ id: policyId }}
/>
)}
</h1>
</EuiTitle>
</EuiFlexItem>
{agentPolicy?.is_managed && (
<EuiFlexItem grow={false}>
<EuiIconTip
title="Hosted agent policy"
content={i18n.translate(
'xpack.fleet.policyDetails.policyDetailsHostedPolicyTooltip',
{
defaultMessage:
'This policy is managed outside of Fleet. Most actions related to this policy are unavailable.',
}
)}
type="lock"
size="l"
color="subdued"
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
)}
</EuiFlexItem>

{agentPolicy && agentPolicy.description ? (
<EuiFlexItem>
<EuiSpacer size="s" />
<EuiText color="subdued" size="s" className="eui-textBreakWord">
{agentPolicy.description}
</EuiText>
</EuiFlexItem>
) : null}
</EuiFlexGroup>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* 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 { HeaderRightContent as Component } from './right_content';

export default {
component: Component,
title: 'Sections/Fleet/AgentPolicyDetails/Header/RightContent',
};

export const HeaderRightContent = () => {
return (
<div style={{ maxWidth: '800px' }}>
<Component
policyId="test123"
isLoading={false}
addAgent={() => {}}
isAddAgentHelpPopoverOpen={false}
setIsAddAgentHelpPopoverOpen={() => {}}
agentPolicy={
{
id: 'test123',
revision: 1,
updated_at: new Date().toISOString(),
package_policies: ['test1', 'test2'],
} as any
}
agentStatus={
{
total: 0,
} as any
}
/>
</div>
);
};

export const HeaderRightContentWithManagedPolicy = () => {
return (
<div style={{ maxWidth: '800px' }}>
<Component
policyId="test123"
isLoading={false}
addAgent={() => {}}
isAddAgentHelpPopoverOpen={false}
setIsAddAgentHelpPopoverOpen={() => {}}
agentPolicy={
{
id: 'test123',
revision: 1,
updated_at: new Date().toISOString(),
package_policies: ['test1', 'test2'],
is_managed: true,
} as any
}
agentStatus={
{
total: 0,
} as any
}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
* 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 { i18n } from '@kbn/i18n';
import { FormattedDate, FormattedMessage } from '@kbn/i18n-react';
import styled from 'styled-components';
import { useHistory } from 'react-router-dom';
import {
EuiFlexGroup,
EuiI18nNumber,
EuiFlexItem,
EuiDescriptionList,
EuiDescriptionListTitle,
EuiDescriptionListDescription,
EuiLink,
} from '@elastic/eui';

import { useLink } from '../../../../../hooks';
import type { AgentPolicy, GetAgentStatusResponse } from '../../../../../types';
import { AgentPolicyActionMenu, LinkedAgentCount } from '../../../components';
import { AddAgentHelpPopover } from '../../../../../components';

export interface HeaderRightContentProps {
isLoading: boolean;
policyId: string;
agentPolicy?: AgentPolicy | null;
agentStatus?: GetAgentStatusResponse['results'];
addAgent: () => void;
onCancelEnrollment?: () => void;
isAddAgentHelpPopoverOpen: boolean;
setIsAddAgentHelpPopoverOpen: (state: boolean) => void;
}

const Divider = styled.div`
width: 0;
height: 100%;
border-left: ${(props) => props.theme.eui.euiBorderThin};
`;

export const HeaderRightContent: React.FunctionComponent<HeaderRightContentProps> = ({
isLoading,
policyId,
agentPolicy,
agentStatus,
addAgent,
onCancelEnrollment,
isAddAgentHelpPopoverOpen,
setIsAddAgentHelpPopoverOpen,
}) => {
const { getPath } = useLink();
const history = useHistory();

if (!agentPolicy) {
return null;
}
const addAgentLink = (
<EuiLink onClick={addAgent}>
<FormattedMessage id="xpack.fleet.policyDetails.addAgentButton" defaultMessage="Add agent" />
</EuiLink>
);

return (
<EuiFlexGroup justifyContent={'flexEnd'} direction="row">
{[
{
label: i18n.translate('xpack.fleet.policyDetails.summary.revision', {
defaultMessage: 'Revision',
}),
content: agentPolicy?.revision ?? 0,
},
{ isDivider: true },
{
label: i18n.translate('xpack.fleet.policyDetails.summary.integrations', {
defaultMessage: 'Integrations',
}),
content: (
<EuiI18nNumber
value={
(agentPolicy &&
agentPolicy.package_policies &&
agentPolicy.package_policies.length) ||
0
}
/>
),
},
{ isDivider: true },
{
label: i18n.translate('xpack.fleet.policyDetails.summary.usedBy', {
defaultMessage: 'Agents',
}),
content:
agentStatus && agentStatus!.total ? (
<LinkedAgentCount
count={agentStatus.total}
agentPolicyId={(agentPolicy && agentPolicy.id) || ''}
showAgentText
/>
) : agentPolicy?.is_managed ? (
<LinkedAgentCount
count={0}
agentPolicyId={(agentPolicy && agentPolicy.id) || ''}
showAgentText
/>
) : (
<AddAgentHelpPopover
button={addAgentLink}
isOpen={isAddAgentHelpPopoverOpen}
offset={15}
closePopover={() => {
setIsAddAgentHelpPopoverOpen(false);
}}
/>
),
},
{ isDivider: true },
{
label: i18n.translate('xpack.fleet.policyDetails.summary.lastUpdated', {
defaultMessage: 'Last updated on',
}),
content:
(agentPolicy && (
<FormattedDate
value={agentPolicy?.updated_at}
year="numeric"
month="short"
day="2-digit"
/>
)) ||
'',
},
{ isDivider: true },
{
content: agentPolicy && (
<AgentPolicyActionMenu
agentPolicy={agentPolicy}
fullButton={true}
onCopySuccess={(newAgentPolicy: AgentPolicy) => {
history.push(getPath('policy_details', { policyId: newAgentPolicy.id }));
}}
onCancelEnrollment={onCancelEnrollment}
/>
),
},
].map((item, index) => (
<EuiFlexItem grow={false} key={index}>
{item.isDivider ?? false ? (
<Divider />
) : item.label ? (
<EuiDescriptionList compressed textStyle="reverse" style={{ textAlign: 'right' }}>
<EuiDescriptionListTitle className="eui-textNoWrap">
{item.label}
</EuiDescriptionListTitle>
<EuiDescriptionListDescription className="eui-textNoWrap">
{item.content}
</EuiDescriptionListDescription>
</EuiDescriptionList>
) : (
item.content
)}
</EuiFlexItem>
))}
</EuiFlexGroup>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
export { PackagePoliciesTable } from './package_policies/package_policies_table';
export { PackagePoliciesView } from './package_policies';
export { SettingsView } from './settings';
export * from './header';
Loading

0 comments on commit 39c2f9e

Please sign in to comment.