2023-11-29 16:07:24 +00:00
|
|
|
import React from "react";
|
|
|
|
|
import { useQuery } from "react-query";
|
|
|
|
|
import { AxiosError } from "axios";
|
2024-07-12 20:04:59 +00:00
|
|
|
import { InjectedRouter } from "react-router";
|
2023-11-29 16:07:24 +00:00
|
|
|
|
|
|
|
|
import { IOperatingSystemVersion } from "interfaces/operating_system";
|
|
|
|
|
import {
|
|
|
|
|
getOSVersions,
|
|
|
|
|
IOSVersionsResponse,
|
|
|
|
|
} from "services/entities/operating_systems";
|
|
|
|
|
|
|
|
|
|
import LastUpdatedText from "components/LastUpdatedText";
|
|
|
|
|
import SectionHeader from "components/SectionHeader";
|
|
|
|
|
import DataError from "components/DataError";
|
2024-07-02 15:36:35 +00:00
|
|
|
import Spinner from "components/Spinner";
|
2023-11-29 16:07:24 +00:00
|
|
|
|
|
|
|
|
import OSVersionTable from "../OSVersionTable";
|
|
|
|
|
import { OSUpdatesSupportedPlatform } from "../../OSUpdates";
|
|
|
|
|
import OSVersionsEmptyState from "../OSVersionsEmptyState";
|
|
|
|
|
|
|
|
|
|
/** This overrides the `platform` attribute on IOperatingSystemVersion so that only our filtered platforms (currently
|
|
|
|
|
* "darwin" and "windows") values are included */
|
|
|
|
|
export type IFilteredOperatingSystemVersion = Omit<
|
|
|
|
|
IOperatingSystemVersion,
|
|
|
|
|
"platform"
|
|
|
|
|
> & {
|
|
|
|
|
platform: OSUpdatesSupportedPlatform;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const baseClass = "os-updates-current-version-section";
|
|
|
|
|
|
|
|
|
|
interface ICurrentVersionSectionProps {
|
2024-07-12 20:04:59 +00:00
|
|
|
router: InjectedRouter;
|
2023-11-29 16:07:24 +00:00
|
|
|
currentTeamId: number;
|
2024-07-12 20:04:59 +00:00
|
|
|
queryParams: ReturnType<typeof parseOSUpdatesCurrentVersionsQueryParams>;
|
2023-11-29 16:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-12 20:04:59 +00:00
|
|
|
const DEFAULT_SORT_DIRECTION = "desc";
|
|
|
|
|
const DEFAULT_SORT_HEADER = "hosts_count";
|
|
|
|
|
const DEFAULT_PAGE = 0;
|
|
|
|
|
const DEFAULT_PAGE_SIZE = 8;
|
|
|
|
|
|
|
|
|
|
export const parseOSUpdatesCurrentVersionsQueryParams = (queryParams: {
|
|
|
|
|
page?: string;
|
|
|
|
|
order_key?: string;
|
|
|
|
|
order_direction?: "asc" | "desc";
|
|
|
|
|
}) => {
|
|
|
|
|
const sortHeader = queryParams?.order_key ?? DEFAULT_SORT_HEADER;
|
|
|
|
|
const sortDirection = queryParams?.order_direction ?? DEFAULT_SORT_DIRECTION;
|
|
|
|
|
const page = queryParams?.page
|
|
|
|
|
? parseInt(queryParams.page, 10)
|
|
|
|
|
: DEFAULT_PAGE;
|
|
|
|
|
const pageSize = DEFAULT_PAGE_SIZE;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
page,
|
|
|
|
|
order_key: sortHeader,
|
|
|
|
|
order_direction: sortDirection,
|
|
|
|
|
per_page: pageSize,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2023-11-29 16:07:24 +00:00
|
|
|
const CurrentVersionSection = ({
|
2024-07-12 20:04:59 +00:00
|
|
|
router,
|
2023-11-29 16:07:24 +00:00
|
|
|
currentTeamId,
|
2024-07-12 20:04:59 +00:00
|
|
|
queryParams,
|
2023-11-29 16:07:24 +00:00
|
|
|
}: ICurrentVersionSectionProps) => {
|
|
|
|
|
const { data, isError, isLoading: isLoadingOsVersions } = useQuery<
|
|
|
|
|
IOSVersionsResponse,
|
|
|
|
|
AxiosError
|
2023-11-30 18:38:16 +00:00
|
|
|
>(
|
2024-07-12 20:04:59 +00:00
|
|
|
["os_versions", currentTeamId, queryParams],
|
|
|
|
|
() => getOSVersions({ teamId: currentTeamId, ...queryParams }),
|
2023-11-30 18:38:16 +00:00
|
|
|
{
|
|
|
|
|
retry: false,
|
|
|
|
|
refetchOnWindowFocus: false,
|
|
|
|
|
}
|
|
|
|
|
);
|
2023-11-29 16:07:24 +00:00
|
|
|
|
|
|
|
|
const generateSubTitleText = () => {
|
|
|
|
|
return (
|
|
|
|
|
<LastUpdatedText
|
|
|
|
|
lastUpdatedAt={data?.counts_updated_at}
|
2025-01-06 18:55:28 +00:00
|
|
|
customTooltipText={
|
|
|
|
|
<>
|
|
|
|
|
Fleet periodically queries all hosts to
|
|
|
|
|
<br />
|
|
|
|
|
retrieve operating systems. Click to
|
|
|
|
|
<br />
|
|
|
|
|
view hosts for the most up-to-date
|
|
|
|
|
<br />
|
|
|
|
|
lists.
|
|
|
|
|
</>
|
|
|
|
|
}
|
2023-11-29 16:07:24 +00:00
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const renderTable = () => {
|
2024-07-02 15:36:35 +00:00
|
|
|
if (isLoadingOsVersions) {
|
|
|
|
|
return <Spinner />;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-29 16:07:24 +00:00
|
|
|
if (isError) {
|
|
|
|
|
return (
|
|
|
|
|
<DataError
|
2025-05-06 13:20:03 +00:00
|
|
|
verticalPaddingSize="pad-xxxlarge"
|
2023-11-29 16:07:24 +00:00
|
|
|
description="Refresh the page to try again."
|
|
|
|
|
excludeIssueLink
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 16:38:53 +00:00
|
|
|
if (!data) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-29 16:07:24 +00:00
|
|
|
if (!data.os_versions) {
|
|
|
|
|
return <OSVersionsEmptyState />;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-09 13:18:00 +00:00
|
|
|
// We only want to show windows mac, ios, ipados versions atm.
|
2023-11-29 16:07:24 +00:00
|
|
|
const filteredOSVersionData = data.os_versions.filter((osVersion) => {
|
|
|
|
|
return (
|
2024-07-09 13:18:00 +00:00
|
|
|
osVersion.platform === "windows" ||
|
|
|
|
|
osVersion.platform === "darwin" ||
|
|
|
|
|
osVersion.platform === "ios" ||
|
|
|
|
|
osVersion.platform === "ipados"
|
2023-11-29 16:07:24 +00:00
|
|
|
);
|
|
|
|
|
}) as IFilteredOperatingSystemVersion[];
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<OSVersionTable
|
2024-07-12 20:04:59 +00:00
|
|
|
router={router}
|
2023-11-29 16:07:24 +00:00
|
|
|
osVersionData={filteredOSVersionData}
|
|
|
|
|
currentTeamId={currentTeamId}
|
|
|
|
|
isLoading={isLoadingOsVersions}
|
2024-07-12 20:04:59 +00:00
|
|
|
queryParams={queryParams}
|
2024-07-16 19:28:35 +00:00
|
|
|
hasNextPage={data.meta.has_next_results}
|
2023-11-29 16:07:24 +00:00
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={baseClass}>
|
|
|
|
|
<SectionHeader
|
|
|
|
|
title="Current versions"
|
2025-01-07 18:29:13 +00:00
|
|
|
subTitle={isLoadingOsVersions ? null : generateSubTitleText()}
|
Linux disk encryption: frontend changes, backend missing private key errors, remove disk encryption endpoints dependence on MDM being enabled (#23714)
## Addresses #22702, #23713, #23756, #23746, #23747, and #23876
_-Note that much of this code as is will render as expected only once
integrated with the backend or if manipulated manually for testing
purposes_
**Frontend**:
- Update banners on my device page, tests
- Build new logic for calling endpoint to trigger linux key escrow on
clicking `Create key`
- Add `CreateLinuxKeyModal` to inform user of next steps after clicking
`Create key`
- Update banners on host details page, tests
- Update the Controls > OS settings section with new logic related to
linux disk encryption
- Expect and include counts of Linux hosts in aggregate disk encryption
stats UI
- Add "Linux" column to the disk encryption table
- Show disk encryption related UI for supported Linux platforms
- TODO: confirm platform string matching functionality in manual e2e
testing
- Expand capabilities of `SectionHeader` component, apply to new UI
- Flash "missing private key" error, with clickable link, when trying to
update disk encryption enabled while no server private key is present.
- TODO: QA this once other endpoints on Controls > Disk encryption are
enabled even when MDM not turned on
- Update Disk encryption key modal copy
-Other TODO:
- Confirm when integrated with API:
- Aggregate disk encryption counts
- Disk encryption table Linux column
- Show disk encryption key action on host details page when expected
- Opens Disk encryption key modal, displays key as expected
**Backend**:
- For "No team" and teams, error when trying to update disk encryption
enabled while no server private key is present.
- Remove requirement of mdm being enabled for use of various endpoints
related to Linux disk encryption
- Update tests
_________
**Host details and my device page banners**

**Create key modal**
<img width="1799" alt="create-key-modal"
src="https://github.com/user-attachments/assets/81a55ccb-b6b9-4eb6-b2ff-a463c60724c0">
**Enabling disk encryption**

**Disk encryption: Fleet free**
<img width="1912" alt="free"
src="https://github.com/user-attachments/assets/9f9cace3-8955-47c2-87d9-24ff9387ac1a">
**Custom settings: turn on MDM**
<img width="1912" alt="turn on mdm"
src="https://github.com/user-attachments/assets/4d3ad47b-4035-4d93-86f0-dc2691b38bb4">
**Device status indicators**

**Encryption key action and modal**

- [x] Changes file added for user-visible changes in `changes/`
- [x] Added/updated tests
- [x] Manual QA for all new/changed functionality
- [ ] Full e2e testing to do when integrated with backend
---------
Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
Co-authored-by: Ian Littman <iansltx@gmail.com>
2024-11-20 19:58:47 +00:00
|
|
|
wrapperCustomClass={`${baseClass}__header`}
|
2023-11-29 16:07:24 +00:00
|
|
|
/>
|
|
|
|
|
{renderTable()}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default CurrentVersionSection;
|