Skip to content

Commit

Permalink
[Fleet] Fix add Fleet server scenarios with subfeatures enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet committed Apr 29, 2024
1 parent 70fb22d commit 7a460c6
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 22 deletions.
23 changes: 14 additions & 9 deletions x-pack/plugins/fleet/common/authz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ export const calculateAuthz = ({
? !!(fleet.agents?.all && fleet.agentPolicies?.all && fleet.settings?.all)
: fleet.all;

const writeIntegrationPolicies = subfeatureEnabled
? (fleet.agentPolicies?.all && integrations.all) ?? false
: ((fleet.all || fleet.agentPolicies?.all) ?? false) && integrations.all;
const readIntegrationPolicies = subfeatureEnabled
? (fleet.agentPolicies?.read && (integrations.all || integrations.read)) ?? false
: ((fleet.all || fleet.read || fleet.agentPolicies?.read) ?? false) &&
(integrations.all || integrations.read);

// TODO remove fallback when the feature flag is removed
const fleetAuthz: FleetAuthz['fleet'] = subfeatureEnabled
? {
Expand All @@ -109,7 +117,12 @@ export const calculateAuthz = ({
allSettings: fleet.settings?.all ?? false,
allAgentPolicies: fleet.agentPolicies?.all ?? false,
addAgents: fleet.agents?.all ?? false,
addFleetServers: (fleet.agents?.all && fleet.settings?.all) ?? false,
addFleetServers:
(fleet.agents?.all &&
fleet.settings?.all &&
fleet.agentPolicies?.all &&
writeIntegrationPolicies) ??
false,
// Setup is needed to access the Fleet UI
setup:
hasFleetAll ||
Expand Down Expand Up @@ -140,14 +153,6 @@ export const calculateAuthz = ({
(fleet.all || fleet.read || fleet.setup || fleet.agentPolicies?.read) ?? false,
};

const writeIntegrationPolicies = subfeatureEnabled
? (fleet.agentPolicies?.all && integrations.all) ?? false
: ((fleet.all || fleet.agentPolicies?.all) ?? false) && integrations.all;
const readIntegrationPolicies = subfeatureEnabled
? (fleet.agentPolicies?.read && (integrations.all || integrations.read)) ?? false
: ((fleet.all || fleet.read || fleet.agentPolicies?.read) ?? false) &&
(integrations.all || integrations.read);

return {
fleet: fleetAuthz,
integrations: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import {
EuiButton,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';

import styled from 'styled-components';

import { useStartServices, useFlyoutContext } from '../../hooks';
import { useStartServices, useFlyoutContext, useCheckPermissions } from '../../hooks';
import { FleetServerMissingESPrivileges } from '../../sections/agents/components';

import { QuickStartTab } from './quick_start_tab';
import { AdvancedTab } from './advanced_tab';
Expand Down Expand Up @@ -121,6 +121,17 @@ const Header: React.FunctionComponent<{
export const FleetServerFlyout: React.FunctionComponent<Props> = ({ onClose }) => {
const { tabs, currentTab, setCurrentTab, currentTabContent } = useFleetServerTabs(onClose);

const { permissionsError, isPermissionsLoading } = useCheckPermissions();

let errorContent: React.ReactNode | undefined;
if (permissionsError === 'MISSING_FLEET_SERVER_SETUP_PRIVILEGES') {
errorContent = (
<ContentWrapper gutterSize="none" justifyContent="center" direction="column">
<FleetServerMissingESPrivileges />
</ContentWrapper>
);
}

return (
<EuiFlyout data-test-subj="fleetServerFlyout" onClose={onClose} size="m">
<EuiFlyoutHeader hasBorder aria-labelledby="FleetAddFleetServerFlyoutTitle">
Expand All @@ -132,7 +143,9 @@ export const FleetServerFlyout: React.FunctionComponent<Props> = ({ onClose }) =
/>
</EuiFlyoutHeader>

<EuiFlyoutBody>{currentTabContent}</EuiFlyoutBody>
<EuiFlyoutBody>
{isPermissionsLoading ? null : errorContent ? errorContent : currentTabContent}
</EuiFlyoutBody>
</EuiFlyout>
);
};
Expand All @@ -153,7 +166,7 @@ export const AddFleetServerLanding: React.FunctionComponent = () => {
<h2 data-test-subj="addFleetServerHeader">
<FormattedMessage
id="xpack.fleet.fleetServerLanding.title"
defaultMessage="Add a Fleet Server"
defaultMessage="Add a Fleet Server test"
/>
</h2>
</EuiTitle>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ async function checkPermissions() {
}

export const useCheckPermissions = () => {
const { data: permissionsError, status } = useQuery(
const { data: permissionsError, isInitialLoading } = useQuery(
['fetch-check-permissions'],
checkPermissions
);
return { isPermissionsLoading: status === 'loading', permissionsError };
return { isPermissionsLoading: isInitialLoading, permissionsError };
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedRelative, FormattedMessage } from '@kbn/i18n-react';

import { policyHasFleetServer } from '../../../../../../../../common/services';

import { InstallStatus } from '../../../../../types';
import type { GetAgentPoliciesResponseItem, InMemoryPackagePolicy } from '../../../../../types';
import {
Expand Down Expand Up @@ -113,6 +115,7 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps

const canWriteIntegrationPolicies = useAuthz().integrations.writeIntegrationPolicies;
const canAddAgents = useAuthz().fleet.addAgents;
const canAddFleetServers = useAuthz().fleet.addFleetServers;

const packageAndAgentPolicies = useMemo((): Array<{
agentPolicy?: GetAgentPoliciesResponseItem;
Expand Down Expand Up @@ -264,12 +267,15 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps
if (!agentPolicy) {
return null;
}
const canAddAgentsForPolicy = policyHasFleetServer(agentPolicy)
? canAddFleetServers
: canAddAgents;
return (
<PackagePolicyAgentsCell
agentPolicy={agentPolicy}
agentCount={agentPolicy.agents}
onAddAgent={() => setFlyoutOpenForPolicyId(agentPolicy.id)}
canAddAgents={canAddAgents}
canAddAgents={canAddAgentsForPolicy}
hasHelpPopover={showAddAgentHelpForPackagePolicyId === packagePolicy.id}
/>
);
Expand Down Expand Up @@ -301,7 +307,13 @@ export const PackagePoliciesPage = ({ name, version }: PackagePoliciesPanelProps
},
},
],
[getHref, canWriteIntegrationPolicies, canAddAgents, showAddAgentHelpForPackagePolicyId]
[
getHref,
canWriteIntegrationPolicies,
canAddAgents,
canAddFleetServers,
showAddAgentHelpForPackagePolicyId,
]
);

const noItemsMessage = useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { EuiContextMenuItem, EuiPortal } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';

import type { AgentPolicy, InMemoryPackagePolicy } from '../types';

import { useAgentPolicyRefresh, useAuthz, useLink } from '../hooks';
import { policyHasFleetServer } from '../services';

import { AgentEnrollmentFlyout } from './agent_enrollment_flyout';
import { ContextMenuActions } from './context_menu_actions';
Expand All @@ -35,8 +35,12 @@ export const PackagePolicyActionsMenu: React.FunctionComponent<{
}) => {
const [isEnrollmentFlyoutOpen, setIsEnrollmentFlyoutOpen] = useState(false);
const { getHref } = useLink();
const canWriteIntegrationPolicies = useAuthz().integrations.writeIntegrationPolicies;
const canAddAgents = useAuthz().fleet.addAgents;
const authz = useAuthz();

const canWriteIntegrationPolicies = authz.integrations.writeIntegrationPolicies;
const isFleetServerPolicy = agentPolicy && policyHasFleetServer(agentPolicy);

const canAddAgents = isFleetServerPolicy ? authz.fleet.addFleetServers : authz.fleet.addAgents;
const refreshAgentPolicy = useAgentPolicyRefresh();
const [isActionsMenuOpen, setIsActionsMenuOpen] = useState(defaultIsOpen);

Expand Down
18 changes: 16 additions & 2 deletions x-pack/plugins/fleet/server/routes/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ export const getCheckPermissionsHandler: FleetRequestHandler<
error: 'MISSING_PRIVILEGES',
} as CheckPermissionsResponse,
});
} else if (request.query.fleetServerSetup) {
const esClient = (await context.core).elasticsearch.client.asCurrentUser;
const { has_all_requested: hasAllPrivileges } = await esClient.security.hasPrivileges({
body: { cluster: ['manage_service_account'] },
});

if (!hasAllPrivileges) {
return response.ok({
body: {
success: false,
error: 'MISSING_FLEET_SERVER_SETUP_PRIVILEGES',
} as CheckPermissionsResponse,
});
}
}

return response.ok({ body: { success: true } as CheckPermissionsResponse });
Expand Down Expand Up @@ -142,7 +156,7 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
.post({
path: APP_API_ROUTES.GENERATE_SERVICE_TOKEN_PATTERN,
fleetAuthz: {
fleet: { all: true },
fleet: { allAgents: true },
},
})
.addVersion(
Expand All @@ -159,7 +173,7 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
.post({
path: APP_API_ROUTES.GENERATE_SERVICE_TOKEN_PATTERN_DEPRECATED,
fleetAuthz: {
fleet: { all: true },
fleet: { allAgents: true },
},
})
.addVersion(
Expand Down

0 comments on commit 7a460c6

Please sign in to comment.