Skip to content
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

[Fleet] Do not allow user to add agent to managed policy #122676

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 ? (
Copy link
Member Author

@nchaulet nchaulet Jan 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is the only behavior change in that PR

<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