2021-09-30 19:32:06 +00:00
|
|
|
|
import React, { useCallback, useContext, useEffect, useState } from "react";
|
|
|
|
|
import { useQuery } from "react-query";
|
|
|
|
|
import { useDispatch } from "react-redux";
|
2022-02-14 22:11:12 +00:00
|
|
|
|
import { InjectedRouter } from "react-router/lib/Router";
|
2022-01-18 15:17:44 +00:00
|
|
|
|
import { noop } from "lodash";
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
import { AppContext } from "context/app";
|
|
|
|
|
import { PolicyContext } from "context/policy";
|
2022-01-20 00:22:45 +00:00
|
|
|
|
import { TableContext } from "context/table";
|
2022-01-18 15:17:44 +00:00
|
|
|
|
import { inMilliseconds, secondsToHms } from "fleet/helpers";
|
|
|
|
|
import { IPolicyStats, ILoadAllPoliciesResponse } from "interfaces/policy";
|
|
|
|
|
import { IWebhookFailingPolicies } from "interfaces/webhook";
|
2022-02-07 18:45:49 +00:00
|
|
|
|
import { IConfig, IConfigNested } from "interfaces/config";
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
import { getConfig } from "redux/nodes/app/actions";
|
2021-08-30 23:02:53 +00:00
|
|
|
|
// @ts-ignore
|
2021-09-30 19:32:06 +00:00
|
|
|
|
import { renderFlash } from "redux/nodes/notifications/actions";
|
|
|
|
|
import PATHS from "router/paths";
|
2021-12-28 18:07:18 +00:00
|
|
|
|
import configAPI from "services/entities/config";
|
2021-09-30 19:32:06 +00:00
|
|
|
|
import globalPoliciesAPI from "services/entities/global_policies";
|
|
|
|
|
import teamPoliciesAPI from "services/entities/team_policies";
|
2022-01-18 15:17:44 +00:00
|
|
|
|
import usersAPI, { IGetMeResponse } from "services/entities/users";
|
|
|
|
|
import { DEFAULT_POLICY } from "utilities/constants";
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
|
|
|
|
import Button from "components/buttons/Button";
|
2022-03-09 18:00:37 +00:00
|
|
|
|
import RevealButton from "components/buttons/RevealButton";
|
2021-08-30 23:02:53 +00:00
|
|
|
|
import InfoBanner from "components/InfoBanner/InfoBanner";
|
2022-01-18 15:17:44 +00:00
|
|
|
|
import Spinner from "components/Spinner";
|
2021-12-01 23:37:33 +00:00
|
|
|
|
import TeamsDropdown from "components/TeamsDropdown";
|
2022-01-18 15:17:44 +00:00
|
|
|
|
import TableDataError from "components/TableDataError";
|
2021-08-30 23:02:53 +00:00
|
|
|
|
import PoliciesListWrapper from "./components/PoliciesListWrapper";
|
2021-12-28 18:07:18 +00:00
|
|
|
|
import ManageAutomationsModal from "./components/ManageAutomationsModal";
|
2021-12-05 23:12:55 +00:00
|
|
|
|
import AddPolicyModal from "./components/AddPolicyModal";
|
2021-08-30 23:02:53 +00:00
|
|
|
|
import RemovePoliciesModal from "./components/RemovePoliciesModal";
|
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
interface IManagePoliciesPageProps {
|
2022-02-14 22:11:12 +00:00
|
|
|
|
router: InjectedRouter; // v3
|
|
|
|
|
location: {
|
|
|
|
|
action: string;
|
|
|
|
|
hash: string;
|
|
|
|
|
key: string;
|
|
|
|
|
pathname: string;
|
|
|
|
|
query: { team_id?: string };
|
|
|
|
|
search: string;
|
|
|
|
|
};
|
2022-01-18 15:17:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-30 23:02:53 +00:00
|
|
|
|
const baseClass = "manage-policies-page";
|
|
|
|
|
|
|
|
|
|
const DOCS_LINK =
|
2021-10-11 15:13:10 +00:00
|
|
|
|
"https://fleetdm.com/docs/deploying/configuration#osquery-policy-update-interval";
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const ManagePolicyPage = ({
|
|
|
|
|
router,
|
|
|
|
|
location,
|
|
|
|
|
}: IManagePoliciesPageProps): JSX.Element => {
|
2021-08-30 23:02:53 +00:00
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
|
2021-09-30 19:32:06 +00:00
|
|
|
|
const {
|
2022-01-18 15:17:44 +00:00
|
|
|
|
availableTeams,
|
2021-09-30 19:32:06 +00:00
|
|
|
|
config,
|
|
|
|
|
isGlobalAdmin,
|
|
|
|
|
isGlobalMaintainer,
|
|
|
|
|
isOnGlobalTeam,
|
|
|
|
|
isFreeTier,
|
|
|
|
|
isPremiumTier,
|
2022-01-18 15:17:44 +00:00
|
|
|
|
isTeamAdmin,
|
|
|
|
|
isTeamMaintainer,
|
2021-12-07 02:04:40 +00:00
|
|
|
|
currentTeam,
|
2022-01-18 15:17:44 +00:00
|
|
|
|
setAvailableTeams,
|
|
|
|
|
setCurrentUser,
|
2021-12-07 02:04:40 +00:00
|
|
|
|
setCurrentTeam,
|
2022-02-07 18:45:49 +00:00
|
|
|
|
setConfig,
|
2021-09-30 19:32:06 +00:00
|
|
|
|
} = useContext(AppContext);
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
2022-02-14 22:11:12 +00:00
|
|
|
|
const teamId = location?.query?.team_id
|
|
|
|
|
? parseInt(location?.query?.team_id, 10)
|
|
|
|
|
: 0;
|
2022-01-18 15:17:44 +00:00
|
|
|
|
|
2021-12-02 15:03:56 +00:00
|
|
|
|
const {
|
|
|
|
|
setLastEditedQueryName,
|
|
|
|
|
setLastEditedQueryDescription,
|
|
|
|
|
setLastEditedQueryBody,
|
2021-12-05 23:12:55 +00:00
|
|
|
|
setLastEditedQueryResolution,
|
2021-12-14 00:21:36 +00:00
|
|
|
|
setLastEditedQueryPlatform,
|
2021-12-02 15:03:56 +00:00
|
|
|
|
} = useContext(PolicyContext);
|
2021-11-29 19:50:58 +00:00
|
|
|
|
|
2022-01-20 00:22:45 +00:00
|
|
|
|
const { setResetSelectedRows } = useContext(TableContext);
|
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const [selectedPolicyIds, setSelectedPolicyIds] = useState<number[]>([]);
|
2021-12-28 18:07:18 +00:00
|
|
|
|
const [showManageAutomationsModal, setShowManageAutomationsModal] = useState(
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
const [showPreviewPayloadModal, setShowPreviewPayloadModal] = useState(false);
|
2021-12-05 23:12:55 +00:00
|
|
|
|
const [showAddPolicyModal, setShowAddPolicyModal] = useState(false);
|
2021-08-30 23:02:53 +00:00
|
|
|
|
const [showRemovePoliciesModal, setShowRemovePoliciesModal] = useState(false);
|
2021-09-30 19:32:06 +00:00
|
|
|
|
const [showInheritedPolicies, setShowInheritedPolicies] = useState(false);
|
2021-12-28 18:07:18 +00:00
|
|
|
|
const [currentAutomatedPolicies, setCurrentAutomatedPolicies] = useState<
|
|
|
|
|
number[]
|
|
|
|
|
>();
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
useQuery(["me"], () => usersAPI.me(), {
|
|
|
|
|
onSuccess: ({ user, available_teams }: IGetMeResponse) => {
|
|
|
|
|
setCurrentUser(user);
|
|
|
|
|
setAvailableTeams(available_teams);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
data: globalPolicies,
|
|
|
|
|
error: globalPoliciesError,
|
|
|
|
|
isLoading: isLoadingGlobalPolicies,
|
|
|
|
|
isStale: isStaleGlobalPolicies,
|
|
|
|
|
refetch: refetchGlobalPolicies,
|
|
|
|
|
} = useQuery<ILoadAllPoliciesResponse, Error, IPolicyStats[]>(
|
|
|
|
|
["globalPolicies"],
|
|
|
|
|
() => {
|
|
|
|
|
return globalPoliciesAPI.loadAll();
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
enabled: !!availableTeams,
|
|
|
|
|
select: (data) => data.policies,
|
|
|
|
|
onSuccess: () => setLastEditedQueryPlatform(""),
|
|
|
|
|
staleTime: 3000,
|
2021-08-30 23:02:53 +00:00
|
|
|
|
}
|
2022-01-18 15:17:44 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
data: teamPolicies,
|
|
|
|
|
error: teamPoliciesError,
|
|
|
|
|
isLoading: isLoadingTeamPolicies,
|
|
|
|
|
refetch: refetchTeamPolicies,
|
|
|
|
|
} = useQuery<ILoadAllPoliciesResponse, Error, IPolicyStats[]>(
|
|
|
|
|
["teamPolicies", teamId],
|
|
|
|
|
() => teamPoliciesAPI.loadAll(teamId),
|
|
|
|
|
{
|
|
|
|
|
enabled: !!availableTeams && isPremiumTier && !!teamId,
|
|
|
|
|
select: (data) => data.policies,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2022-02-07 18:45:49 +00:00
|
|
|
|
const canAddOrRemovePolicy =
|
|
|
|
|
isGlobalAdmin || isGlobalMaintainer || isTeamMaintainer || isTeamAdmin;
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
data: failingPoliciesWebhook,
|
|
|
|
|
isLoading: isLoadingFailingPoliciesWebhook,
|
|
|
|
|
refetch: refetchFailingPoliciesWebhook,
|
|
|
|
|
} = useQuery<IConfigNested, Error, IWebhookFailingPolicies>(
|
|
|
|
|
["config"],
|
|
|
|
|
() => configAPI.loadAll(),
|
|
|
|
|
{
|
|
|
|
|
enabled: canAddOrRemovePolicy,
|
|
|
|
|
select: (data: IConfigNested) =>
|
|
|
|
|
data.webhook_settings.failing_policies_webhook,
|
|
|
|
|
onSuccess: (data) => {
|
|
|
|
|
setCurrentAutomatedPolicies(data.policy_ids);
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const refetchPolicies = (id?: number) => {
|
|
|
|
|
refetchGlobalPolicies();
|
|
|
|
|
if (id) {
|
|
|
|
|
refetchTeamPolicies();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const findAvailableTeam = (id: number) => {
|
|
|
|
|
return availableTeams?.find((t) => t.id === id);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleTeamSelect = (id: number) => {
|
|
|
|
|
const { MANAGE_POLICIES } = PATHS;
|
|
|
|
|
|
|
|
|
|
const selectedTeam = findAvailableTeam(id);
|
|
|
|
|
const path = selectedTeam?.id
|
|
|
|
|
? `${MANAGE_POLICIES}?team_id=${selectedTeam.id}`
|
|
|
|
|
: MANAGE_POLICIES;
|
|
|
|
|
|
|
|
|
|
router.replace(path);
|
|
|
|
|
setShowInheritedPolicies(false);
|
|
|
|
|
setSelectedPolicyIds([]);
|
|
|
|
|
setCurrentTeam(selectedTeam);
|
|
|
|
|
isStaleGlobalPolicies && refetchGlobalPolicies();
|
|
|
|
|
};
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
2021-12-28 18:07:18 +00:00
|
|
|
|
const toggleManageAutomationsModal = () =>
|
|
|
|
|
setShowManageAutomationsModal(!showManageAutomationsModal);
|
|
|
|
|
|
|
|
|
|
const togglePreviewPayloadModal = useCallback(() => {
|
|
|
|
|
setShowPreviewPayloadModal(!showPreviewPayloadModal);
|
|
|
|
|
}, [setShowPreviewPayloadModal, showPreviewPayloadModal]);
|
|
|
|
|
|
2021-12-05 23:12:55 +00:00
|
|
|
|
const toggleAddPolicyModal = () => setShowAddPolicyModal(!showAddPolicyModal);
|
|
|
|
|
|
2021-09-30 19:32:06 +00:00
|
|
|
|
const toggleRemovePoliciesModal = () =>
|
2021-08-30 23:02:53 +00:00
|
|
|
|
setShowRemovePoliciesModal(!showRemovePoliciesModal);
|
|
|
|
|
|
2021-09-30 19:32:06 +00:00
|
|
|
|
const toggleShowInheritedPolicies = () =>
|
|
|
|
|
setShowInheritedPolicies(!showInheritedPolicies);
|
|
|
|
|
|
2021-12-28 18:07:18 +00:00
|
|
|
|
const onManageAutomationsClick = () => {
|
|
|
|
|
toggleManageAutomationsModal();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onCreateWebhookSubmit = async ({
|
|
|
|
|
destination_url,
|
|
|
|
|
policy_ids,
|
|
|
|
|
enable_failing_policies_webhook,
|
|
|
|
|
}: IWebhookFailingPolicies) => {
|
|
|
|
|
try {
|
|
|
|
|
const request = configAPI.update({
|
|
|
|
|
webhook_settings: {
|
|
|
|
|
failing_policies_webhook: {
|
|
|
|
|
destination_url,
|
|
|
|
|
policy_ids,
|
|
|
|
|
enable_failing_policies_webhook,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
await request.then(() => {
|
|
|
|
|
dispatch(
|
|
|
|
|
renderFlash("success", "Successfully updated policy automations.")
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
} catch {
|
|
|
|
|
dispatch(
|
|
|
|
|
renderFlash(
|
|
|
|
|
"error",
|
|
|
|
|
"Could not update policy automations. Please try again."
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
} finally {
|
|
|
|
|
toggleManageAutomationsModal();
|
2022-02-07 18:45:49 +00:00
|
|
|
|
refetchFailingPoliciesWebhook();
|
|
|
|
|
// Config must be updated in both Redux and AppContext
|
|
|
|
|
dispatch(getConfig())
|
|
|
|
|
.then((configState: IConfig) => {
|
|
|
|
|
setConfig(configState);
|
|
|
|
|
})
|
|
|
|
|
.catch(() => false);
|
2021-12-28 18:07:18 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-02 15:03:56 +00:00
|
|
|
|
const onAddPolicyClick = () => {
|
|
|
|
|
setLastEditedQueryName("");
|
|
|
|
|
setLastEditedQueryDescription("");
|
|
|
|
|
setLastEditedQueryBody(DEFAULT_POLICY.query);
|
2021-12-05 23:12:55 +00:00
|
|
|
|
setLastEditedQueryResolution("");
|
|
|
|
|
toggleAddPolicyModal();
|
2021-12-02 15:03:56 +00:00
|
|
|
|
};
|
|
|
|
|
|
2021-09-30 19:32:06 +00:00
|
|
|
|
const onRemovePoliciesClick = (selectedTableIds: number[]): void => {
|
|
|
|
|
toggleRemovePoliciesModal();
|
|
|
|
|
setSelectedPolicyIds(selectedTableIds);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onRemovePoliciesSubmit = async () => {
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const id = currentTeam?.id;
|
2021-09-30 19:32:06 +00:00
|
|
|
|
try {
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const request = id
|
|
|
|
|
? teamPoliciesAPI.destroy(id, selectedPolicyIds)
|
2021-09-30 19:32:06 +00:00
|
|
|
|
: globalPoliciesAPI.destroy(selectedPolicyIds);
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
2021-09-30 19:32:06 +00:00
|
|
|
|
await request.then(() => {
|
2021-08-30 23:02:53 +00:00
|
|
|
|
dispatch(
|
|
|
|
|
renderFlash(
|
|
|
|
|
"success",
|
|
|
|
|
`Successfully removed ${
|
2021-09-30 19:32:06 +00:00
|
|
|
|
selectedPolicyIds?.length === 1 ? "policy" : "policies"
|
2021-08-30 23:02:53 +00:00
|
|
|
|
}.`
|
|
|
|
|
)
|
|
|
|
|
);
|
2022-01-20 00:22:45 +00:00
|
|
|
|
setResetSelectedRows(true);
|
|
|
|
|
refetchPolicies(id);
|
2021-08-30 23:02:53 +00:00
|
|
|
|
});
|
2021-09-30 19:32:06 +00:00
|
|
|
|
} catch {
|
|
|
|
|
dispatch(
|
|
|
|
|
renderFlash(
|
|
|
|
|
"error",
|
|
|
|
|
`Unable to remove ${
|
|
|
|
|
selectedPolicyIds?.length === 1 ? "policy" : "policies"
|
|
|
|
|
}. Please try again.`
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
} finally {
|
|
|
|
|
toggleRemovePoliciesModal();
|
|
|
|
|
}
|
|
|
|
|
};
|
2021-08-30 23:02:53 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const inheritedPoliciesButtonText = (
|
|
|
|
|
showPolicies: boolean,
|
|
|
|
|
count: number
|
|
|
|
|
) => {
|
|
|
|
|
return `${showPolicies ? "Hide" : "Show"} ${count} inherited ${
|
|
|
|
|
count > 1 ? "policies" : "policy"
|
|
|
|
|
}`;
|
|
|
|
|
};
|
2021-09-30 19:32:06 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const policyUpdateInterval =
|
|
|
|
|
secondsToHms(inMilliseconds(config?.osquery_policy || 0) / 1000) ||
|
|
|
|
|
"osquery policy update interval";
|
2021-09-30 19:32:06 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
const showTeamDescription = isPremiumTier && !!teamId;
|
2021-10-02 00:35:13 +00:00
|
|
|
|
|
|
|
|
|
const showInfoBanner =
|
2022-01-18 15:17:44 +00:00
|
|
|
|
(teamId && !teamPoliciesError && !!teamPolicies?.length) ||
|
|
|
|
|
(!teamId && !globalPoliciesError && !!globalPolicies?.length);
|
2021-10-02 00:35:13 +00:00
|
|
|
|
|
|
|
|
|
const showInheritedPoliciesButton =
|
2022-01-18 15:17:44 +00:00
|
|
|
|
!!teamId &&
|
|
|
|
|
!isLoadingTeamPolicies &&
|
|
|
|
|
!teamPoliciesError &&
|
|
|
|
|
!isLoadingGlobalPolicies &&
|
|
|
|
|
!globalPoliciesError &&
|
|
|
|
|
!!globalPolicies?.length;
|
|
|
|
|
|
|
|
|
|
// If team_id from URL query params is not valid, we instead use a default team
|
|
|
|
|
// either the current team (if any) or all teams (for global users) or
|
|
|
|
|
// the first available team (for non-global users)
|
|
|
|
|
const getValidatedTeamId = () => {
|
|
|
|
|
if (findAvailableTeam(teamId)) {
|
|
|
|
|
return teamId;
|
|
|
|
|
}
|
|
|
|
|
if (!teamId && currentTeam) {
|
|
|
|
|
return currentTeam.id;
|
|
|
|
|
}
|
|
|
|
|
if (!teamId && !currentTeam && !isOnGlobalTeam && availableTeams) {
|
|
|
|
|
return availableTeams[0]?.id;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
};
|
2021-10-02 00:35:13 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
// If team_id or currentTeam doesn't match validated id, switch to validated id
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (availableTeams) {
|
|
|
|
|
const validatedId = getValidatedTeamId();
|
|
|
|
|
|
|
|
|
|
if (validatedId !== currentTeam?.id || validatedId !== teamId) {
|
|
|
|
|
handleTeamSelect(validatedId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [availableTeams]);
|
2021-11-10 18:46:16 +00:00
|
|
|
|
|
2022-01-18 15:17:44 +00:00
|
|
|
|
return !availableTeams ? (
|
|
|
|
|
<Spinner />
|
|
|
|
|
) : (
|
2021-08-30 23:02:53 +00:00
|
|
|
|
<div className={baseClass}>
|
|
|
|
|
<div className={`${baseClass}__wrapper body-wrap`}>
|
|
|
|
|
<div className={`${baseClass}__header-wrap`}>
|
|
|
|
|
<div className={`${baseClass}__header`}>
|
|
|
|
|
<div className={`${baseClass}__text`}>
|
2021-09-30 19:32:06 +00:00
|
|
|
|
<div className={`${baseClass}__title`}>
|
|
|
|
|
{isFreeTier && <h1>Policies</h1>}
|
|
|
|
|
{isPremiumTier &&
|
2022-01-18 15:17:44 +00:00
|
|
|
|
(availableTeams.length > 1 || isOnGlobalTeam) && (
|
2021-09-30 19:32:06 +00:00
|
|
|
|
<TeamsDropdown
|
2022-01-18 15:17:44 +00:00
|
|
|
|
currentUserTeams={availableTeams || []}
|
|
|
|
|
selectedTeamId={teamId}
|
2021-12-01 23:37:33 +00:00
|
|
|
|
onChange={(newSelectedValue: number) =>
|
|
|
|
|
handleTeamSelect(newSelectedValue)
|
|
|
|
|
}
|
2021-09-30 19:32:06 +00:00
|
|
|
|
/>
|
|
|
|
|
)}
|
2021-12-07 02:04:40 +00:00
|
|
|
|
{isPremiumTier &&
|
|
|
|
|
!isOnGlobalTeam &&
|
2022-01-18 15:17:44 +00:00
|
|
|
|
availableTeams.length === 1 && (
|
|
|
|
|
<h1>{availableTeams[0].name}</h1>
|
|
|
|
|
)}
|
2021-09-30 19:32:06 +00:00
|
|
|
|
</div>
|
2021-08-30 23:02:53 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2021-12-28 18:07:18 +00:00
|
|
|
|
<div className={`${baseClass} button-wrap`}>
|
2022-02-14 22:09:55 +00:00
|
|
|
|
{canAddOrRemovePolicy &&
|
|
|
|
|
teamId === 0 &&
|
|
|
|
|
!isLoadingFailingPoliciesWebhook &&
|
|
|
|
|
!isLoadingGlobalPolicies && (
|
|
|
|
|
<Button
|
|
|
|
|
onClick={() => onManageAutomationsClick()}
|
|
|
|
|
className={`${baseClass}__manage-automations button`}
|
|
|
|
|
variant="inverse"
|
|
|
|
|
>
|
|
|
|
|
<span>Manage automations</span>
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
2022-01-18 15:17:44 +00:00
|
|
|
|
{canAddOrRemovePolicy && (
|
2021-12-28 18:07:18 +00:00
|
|
|
|
<div className={`${baseClass}__action-button-container`}>
|
|
|
|
|
<Button
|
|
|
|
|
variant="brand"
|
|
|
|
|
className={`${baseClass}__select-policy-button`}
|
|
|
|
|
onClick={onAddPolicyClick}
|
|
|
|
|
>
|
|
|
|
|
Add a policy
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
2021-08-30 23:02:53 +00:00
|
|
|
|
</div>
|
2022-01-18 15:17:44 +00:00
|
|
|
|
<div className={`${baseClass}__description`}>
|
|
|
|
|
{showTeamDescription ? (
|
|
|
|
|
<p>
|
|
|
|
|
Add additional policies for <b>all hosts assigned to this team</b>
|
|
|
|
|
.
|
|
|
|
|
</p>
|
|
|
|
|
) : (
|
|
|
|
|
<p>
|
|
|
|
|
Add policies for <b>all of your hosts</b> to see which pass your
|
|
|
|
|
organization’s standards.
|
|
|
|
|
</p>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
{!!policyUpdateInterval && showInfoBanner && (
|
2021-10-02 00:35:13 +00:00
|
|
|
|
<InfoBanner className={`${baseClass}__sandbox-info`}>
|
|
|
|
|
<p>
|
2022-01-18 15:17:44 +00:00
|
|
|
|
Your policies are checked every{" "}
|
|
|
|
|
<b>{policyUpdateInterval.trim()}</b>.{" "}
|
2021-10-02 00:35:13 +00:00
|
|
|
|
{isGlobalAdmin && (
|
|
|
|
|
<span>
|
|
|
|
|
Check out the Fleet documentation on{" "}
|
|
|
|
|
<a href={DOCS_LINK} target="_blank" rel="noreferrer">
|
|
|
|
|
<b>how to edit this frequency</b>
|
|
|
|
|
</a>
|
|
|
|
|
.
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
</p>
|
|
|
|
|
</InfoBanner>
|
|
|
|
|
)}
|
2021-09-30 19:32:06 +00:00
|
|
|
|
<div>
|
2022-01-18 15:17:44 +00:00
|
|
|
|
{!!teamId && teamPoliciesError && <TableDataError />}
|
|
|
|
|
{!!teamId &&
|
|
|
|
|
!teamPoliciesError &&
|
2022-02-05 00:48:35 +00:00
|
|
|
|
(isLoadingTeamPolicies && isLoadingFailingPoliciesWebhook ? (
|
2022-01-18 15:17:44 +00:00
|
|
|
|
<Spinner />
|
2021-09-30 19:32:06 +00:00
|
|
|
|
) : (
|
|
|
|
|
<PoliciesListWrapper
|
2022-01-18 15:17:44 +00:00
|
|
|
|
policiesList={teamPolicies || []}
|
2021-12-28 18:07:18 +00:00
|
|
|
|
isLoading={
|
|
|
|
|
isLoadingTeamPolicies && isLoadingFailingPoliciesWebhook
|
|
|
|
|
}
|
2021-09-30 19:32:06 +00:00
|
|
|
|
onRemovePoliciesClick={onRemovePoliciesClick}
|
2022-01-18 15:17:44 +00:00
|
|
|
|
canAddOrRemovePolicy={canAddOrRemovePolicy}
|
|
|
|
|
currentTeam={currentTeam}
|
2021-12-28 18:07:18 +00:00
|
|
|
|
currentAutomatedPolicies={currentAutomatedPolicies}
|
2021-09-30 19:32:06 +00:00
|
|
|
|
/>
|
|
|
|
|
))}
|
2022-01-18 15:17:44 +00:00
|
|
|
|
{!teamId && globalPoliciesError && <TableDataError />}
|
|
|
|
|
{!teamId &&
|
|
|
|
|
!globalPoliciesError &&
|
|
|
|
|
(isLoadingGlobalPolicies ? (
|
|
|
|
|
<Spinner />
|
2021-09-30 19:32:06 +00:00
|
|
|
|
) : (
|
|
|
|
|
<PoliciesListWrapper
|
2022-01-18 15:17:44 +00:00
|
|
|
|
policiesList={globalPolicies || []}
|
2021-12-28 18:07:18 +00:00
|
|
|
|
isLoading={
|
|
|
|
|
isLoadingGlobalPolicies && isLoadingFailingPoliciesWebhook
|
|
|
|
|
}
|
2021-09-30 19:32:06 +00:00
|
|
|
|
onRemovePoliciesClick={onRemovePoliciesClick}
|
2022-01-18 15:17:44 +00:00
|
|
|
|
canAddOrRemovePolicy={canAddOrRemovePolicy}
|
|
|
|
|
currentTeam={currentTeam}
|
2021-12-28 18:07:18 +00:00
|
|
|
|
currentAutomatedPolicies={currentAutomatedPolicies}
|
2021-09-30 19:32:06 +00:00
|
|
|
|
/>
|
|
|
|
|
))}
|
2021-08-30 23:02:53 +00:00
|
|
|
|
</div>
|
2022-02-14 22:09:55 +00:00
|
|
|
|
{showInheritedPoliciesButton && globalPolicies && (
|
2022-03-09 18:00:37 +00:00
|
|
|
|
<RevealButton
|
|
|
|
|
isShowing={showInheritedPolicies}
|
|
|
|
|
baseClass={baseClass}
|
|
|
|
|
hideText={inheritedPoliciesButtonText(
|
|
|
|
|
showInheritedPolicies,
|
|
|
|
|
globalPolicies.length
|
|
|
|
|
)}
|
|
|
|
|
showText={inheritedPoliciesButtonText(
|
|
|
|
|
showInheritedPolicies,
|
|
|
|
|
globalPolicies.length
|
|
|
|
|
)}
|
|
|
|
|
caretPosition={"before"}
|
|
|
|
|
tooltipHtml={
|
|
|
|
|
'"All teams" policies are checked <br/> for this team’s hosts.'
|
|
|
|
|
}
|
|
|
|
|
onClick={toggleShowInheritedPolicies}
|
|
|
|
|
/>
|
2021-10-02 00:35:13 +00:00
|
|
|
|
)}
|
|
|
|
|
{showInheritedPoliciesButton && showInheritedPolicies && (
|
|
|
|
|
<div className={`${baseClass}__inherited-policies-table`}>
|
2022-01-18 15:17:44 +00:00
|
|
|
|
{globalPoliciesError && <TableDataError />}
|
|
|
|
|
{!globalPoliciesError &&
|
|
|
|
|
(isLoadingGlobalPolicies ? (
|
|
|
|
|
<Spinner />
|
|
|
|
|
) : (
|
|
|
|
|
<PoliciesListWrapper
|
|
|
|
|
isLoading={
|
|
|
|
|
isLoadingGlobalPolicies && isLoadingFailingPoliciesWebhook
|
|
|
|
|
}
|
|
|
|
|
policiesList={globalPolicies || []}
|
|
|
|
|
onRemovePoliciesClick={noop}
|
|
|
|
|
resultsTitle="policies"
|
|
|
|
|
canAddOrRemovePolicy={canAddOrRemovePolicy}
|
|
|
|
|
tableType="inheritedPolicies"
|
|
|
|
|
currentTeam={currentTeam}
|
|
|
|
|
currentAutomatedPolicies={currentAutomatedPolicies}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
2021-10-02 00:35:13 +00:00
|
|
|
|
</div>
|
|
|
|
|
)}
|
2021-12-28 18:07:18 +00:00
|
|
|
|
{showManageAutomationsModal && (
|
|
|
|
|
<ManageAutomationsModal
|
|
|
|
|
onCancel={toggleManageAutomationsModal}
|
|
|
|
|
onCreateWebhookSubmit={onCreateWebhookSubmit}
|
|
|
|
|
togglePreviewPayloadModal={togglePreviewPayloadModal}
|
|
|
|
|
showPreviewPayloadModal={showPreviewPayloadModal}
|
2022-01-18 15:17:44 +00:00
|
|
|
|
availablePolicies={globalPolicies || []}
|
2021-12-28 18:07:18 +00:00
|
|
|
|
currentAutomatedPolicies={currentAutomatedPolicies || []}
|
|
|
|
|
currentDestinationUrl={
|
|
|
|
|
(failingPoliciesWebhook &&
|
|
|
|
|
failingPoliciesWebhook.destination_url) ||
|
|
|
|
|
""
|
|
|
|
|
}
|
2022-03-11 17:56:14 +00:00
|
|
|
|
enableFailingPoliciesWebhook={
|
|
|
|
|
(failingPoliciesWebhook &&
|
|
|
|
|
failingPoliciesWebhook.enable_failing_policies_webhook) ||
|
|
|
|
|
false
|
|
|
|
|
}
|
2021-12-28 18:07:18 +00:00
|
|
|
|
/>
|
|
|
|
|
)}
|
2021-12-05 23:12:55 +00:00
|
|
|
|
{showAddPolicyModal && (
|
|
|
|
|
<AddPolicyModal
|
|
|
|
|
onCancel={toggleAddPolicyModal}
|
|
|
|
|
router={router}
|
2022-01-18 15:17:44 +00:00
|
|
|
|
teamId={teamId}
|
|
|
|
|
teamName={currentTeam?.name}
|
2021-12-05 23:12:55 +00:00
|
|
|
|
/>
|
|
|
|
|
)}
|
2021-08-30 23:02:53 +00:00
|
|
|
|
{showRemovePoliciesModal && (
|
|
|
|
|
<RemovePoliciesModal
|
|
|
|
|
onCancel={toggleRemovePoliciesModal}
|
|
|
|
|
onSubmit={onRemovePoliciesSubmit}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default ManagePolicyPage;
|