Merge branch 'main' into feat-prefill-account-name

This commit is contained in:
Martin Angers 2024-03-26 14:01:22 -04:00 committed by GitHub
commit 12d9377d68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 239 additions and 264 deletions

View file

@ -1,3 +1,11 @@
## Fleet 4.47.2 (Mar 22, 2024)
### Bug fixes
* Fixed false negative vulnerabilities on macOS Homebrew Python packages.
* Fixed policies to check "disable guest user".
* Resolved the issue where Microsoft Edge was not reporting vulnerabilities.
## Fleet 4.47.1 (Mar 18, 2024)
### Bug fixes

View file

@ -0,0 +1 @@
- UI fix: users can see a tooltip on a disabled checkbox

View file

@ -0,0 +1,2 @@
- Fix error state rendering on the global Host status expiry settings page, fix error state
alignment for tooltip-wrapper field labels across organization settings.

View file

@ -0,0 +1 @@
- Fixed a bug where OS version information would not get detected on Windows Server 2019

View file

@ -8,7 +8,7 @@ version: v6.0.2
home: https://github.com/fleetdm/fleet
sources:
- https://github.com/fleetdm/fleet.git
appVersion: v4.47.1
appVersion: v4.47.2
dependencies:
- name: mysql
condition: mysql.enabled

View file

@ -2,7 +2,7 @@
# All settings related to how Fleet is deployed in Kubernetes
hostName: fleet.localhost
replicas: 3 # The number of Fleet instances to deploy
imageTag: v4.47.1 # Version of Fleet to deploy
imageTag: v4.47.2 # Version of Fleet to deploy
podAnnotations: {} # Additional annotations to add to the Fleet pod
serviceAccountAnnotations: {} # Additional annotations to add to the Fleet service account
resources:

View file

@ -113,7 +113,7 @@ When the Actions Workflow has been completed, [publish the new version of Fleet]
2. Check the [Docker Publish GitHub action](https://github.com/fleetdm/fleet/actions/workflows/goreleaser-snapshot-fleet.yaml) to confirm it completes successfully for this branch.
3. Create a [Release QA](https://github.com/fleetdm/fleet/blob/main/.github/ISSUE_TEMPLATE/smoke-tests.md) issue. Populate the version and browsers, and assign to the QA person leading the release. Add the appropriate [product group label](https://fleetdm.com/handbook/company/product-groups), and `:release` label, so that it appears on the product group's release board.
3. Create a [Release QA](https://github.com/fleetdm/fleet/blob/main/.github/ISSUE_TEMPLATE/release-qa.md) issue. Populate the version and browsers, and assign to the QA person leading the release. Add the appropriate [product group label](https://fleetdm.com/handbook/company/product-groups), and `:release` label, so that it appears on the product group's release board.
4. Notify QA that the release candidate is ready for (release QA)[#complete-release-qa].

View file

@ -2518,7 +2518,7 @@ Returns the information of the specified host.
Returns the information of the host specified using the `uuid`, `hardware_serial`, `osquery_host_id`, `hostname`, or
`node_key` as an identifier.
If `hostname` is specified when there is more than one host with the same hostname, the endpoint returns the first matching host.
If `hostname` is specified when there is more than one host with the same hostname, the endpoint returns the first matching host. In Fleet, hostnames are fully qualified domain names (FQDNs).
`GET /api/v1/fleet/hosts/identifier/:identifier`
@ -7372,7 +7372,7 @@ This allows you to easily configure scheduled queries that will impact a whole t
- [Run script](#run-script)
- [Get script result](#get-script-result)
- [Run live script](#run-script)
- [Run live script](#run-live-script)
- [Upload a script](#upload-a-script)
- [Delete a script](#delete-a-script)
- [List scripts](#list-scripts)

View file

@ -30,6 +30,8 @@ For the MDM protocol to function, we need to generate the four following files:
The APNs certificates serve as authentication between Fleet and Apple, while the SCEP certificates serve as authentication between Fleet and hosts.
> To prevent abuse, please use your work email. If your email isn't accepted, please make sure it's not on this [list of blocked emails].(https://github.com/fleetdm/fleet/blob/d5df23964b0b52f1d442b66ffe4451dc2a9ef969/website/api/controllers/deliver-apple-csr.js#L60)
Use either of the following methods to generate the necessary files:
#### Fleet UI

View file

@ -680,7 +680,7 @@ function getParseRegexForToken (token, config) {
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function unescapeFormat(s) {
return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
return regexEscape(s.replace(/\\/g, '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
return p1 || p2 || p3 || p4;
}));
}
@ -1477,9 +1477,9 @@ function localeWeekdaysParse (weekdayName, format, strict) {
mom = createUTC([2000, 1]).day(i);
if (strict && !this._fullWeekdaysParse[i]) {
this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
}
if (!this._weekdaysParse[i]) {
regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');

View file

@ -55,21 +55,26 @@ const Checkbox = (props: ICheckboxProps) => {
className,
baseClass
);
const checkBoxTickClass = classnames(`${baseClass}__tick`, {
[`${baseClass}__tick--disabled`]: disabled,
[`${baseClass}__tick--indeterminate`]: indeterminate,
});
const checkBoxLabelClass = classnames(checkBoxClass, {
[`${baseClass}__label--disabled`]: disabled,
});
const formFieldProps = {
...pick(props, ["helpText", "label", "error", "name"]),
className: wrapperClassName,
type: "checkbox",
} as IFormFieldProps;
const checkBoxTickClass = classnames(`${checkBoxClass}__tick`, {
[`${checkBoxClass}__tick--disabled`]: disabled,
[`${checkBoxClass}__tick--indeterminate`]: indeterminate,
});
return (
<FormField {...formFieldProps}>
<>
<label htmlFor={name} className={checkBoxClass}>
<label htmlFor={name} className={checkBoxLabelClass}>
<input
checked={value}
className={`${baseClass}__input`}

View file

@ -29,6 +29,18 @@
}
}
&--disabled {
&::after {
@include disabled-checkbox;
}
&:hover {
&::after {
@include disabled-checkbox;
}
}
}
&::before {
@include position(absolute, 50% null null 50%);
transform: rotate(45deg);
@ -41,6 +53,7 @@
border-top: 0;
border-left: 0;
content: "";
z-index: 9;
}
}
}
@ -109,6 +122,10 @@
padding-left: $pad-small;
display: inline-block;
vertical-align: top;
&--disabled {
color: $ui-fleet-black-50;
}
}
&__label-tooltip {

View file

@ -19,7 +19,9 @@ export type ColumnType =
| "bigint"
| "double"
| "text"
| "unsigned_bigint";
| "unsigned_bigint"
| "STRING"
| "string"; // TODO: Why do we have type string, STRING, and text in schema.json?
export interface IQueryTableColumn {
name: string;

View file

@ -55,20 +55,21 @@ const CurrentVersionSection = ({
);
};
if (!data) {
return null;
}
const renderTable = () => {
if (isError) {
return (
<DataError
className={`${baseClass}__error`}
description="Refresh the page to try again."
excludeIssueLink
/>
);
}
if (!data) {
return null;
}
if (!data.os_versions) {
return <OSVersionsEmptyState />;
}

View file

@ -15,4 +15,8 @@
font-size: 18px;
}
}
&__error {
padding: $pad-xxlarge;
}
}

View file

@ -101,10 +101,6 @@
&__disabled-usage-statistics-checkbox {
@include disabled;
}
.component__tooltip-wrapper {
margin-bottom: $pad-xsmall;
}
}
}
}

View file

@ -28,7 +28,7 @@ const baseClass = "app-config-form";
export type IGlobalHostStatusWebhookFormData = {
enableHostStatusWebhook: boolean;
hostStatusWebhookDestinationUrl: string;
destination_url: string;
hostStatusWebhookHostPercentage: number;
hostStatusWebhookWindow: number;
};
@ -46,7 +46,7 @@ const GlobalHostStatusWebhook = ({
enableHostStatusWebhook:
appConfig.webhook_settings.host_status_webhook
?.enable_host_status_webhook || false,
hostStatusWebhookDestinationUrl:
destination_url:
appConfig.webhook_settings.host_status_webhook?.destination_url || "",
hostStatusWebhookHostPercentage:
appConfig.webhook_settings.host_status_webhook?.host_percentage || 1,
@ -56,7 +56,7 @@ const GlobalHostStatusWebhook = ({
const {
enableHostStatusWebhook,
hostStatusWebhookDestinationUrl,
destination_url,
hostStatusWebhookHostPercentage,
hostStatusWebhookWindow,
} = formData;
@ -72,10 +72,10 @@ const GlobalHostStatusWebhook = ({
const errors: IAppConfigFormErrors = {};
if (enableHostStatusWebhook) {
if (!hostStatusWebhookDestinationUrl) {
if (!destination_url) {
errors.destination_url = "Destination URL must be present";
} else if (!validUrl({ url: hostStatusWebhookDestinationUrl })) {
errors.server_url = `${hostStatusWebhookDestinationUrl} is not a valid URL`;
} else if (!validUrl({ url: destination_url })) {
errors.destination_url = `${destination_url} is not a valid URL`;
}
}
@ -99,7 +99,7 @@ const GlobalHostStatusWebhook = ({
webhook_settings: {
host_status_webhook: {
enable_host_status_webhook: enableHostStatusWebhook,
destination_url: hostStatusWebhookDestinationUrl,
destination_url,
host_percentage: hostStatusWebhookHostPercentage,
days_count: hostStatusWebhookWindow,
},
@ -166,8 +166,8 @@ const GlobalHostStatusWebhook = ({
placeholder="https://server.com/example"
label="Destination URL"
onChange={handleInputChange}
name="hostStatusWebhookDestinationUrl"
value={hostStatusWebhookDestinationUrl}
name="destination_url"
value={destination_url}
parseTarget
onBlur={validateForm}
error={formErrors.destination_url}

View file

@ -48,32 +48,26 @@ const TeamHostExpiryToggle = ({
<Checkbox
name="enableHostExpiry"
onChange={setTeamExpiryEnabled}
value={teamExpiryEnabled || globalHostExpiryEnabled}
wrapperClassName={
globalHostExpiryEnabled
? `${baseClass}__disabled-team-host-expiry-toggle`
: ""
}
value={teamExpiryEnabled || globalHostExpiryEnabled} // Still shows checkmark if global expiry is enabled though the checkbox will be disabled.
disabled={globalHostExpiryEnabled}
helpText={renderHelpText()}
tooltipContent={
!globalHostExpiryEnabled && (
<>
When enabled, allows automatic cleanup of
<>
When enabled, allows automatic cleanup of
<br />
hosts that have not communicated with Fleet in
<br />
the number of days specified in the{" "}
<strong>
Host expiry
<br />
hosts that have not communicated with Fleet in
<br />
the number of days specified in the{" "}
<strong>
Host expiry
<br />
window
</strong>{" "}
setting.{" "}
<em>
(Default: <strong>Off</strong>)
</em>
</>
)
window
</strong>{" "}
setting.{" "}
<em>
(Default: <strong>Off</strong>)
</em>
</>
}
>
Enable host expiry

View file

@ -1,8 +1,4 @@
.team-host-expiry-toggle {
&__disabled-team-host-expiry-toggle > .fleet-checkbox {
@include disabled;
}
&__add-custom-window {
display: inline-flex;
align-items: center;

View file

@ -53,6 +53,7 @@ const generateTableHeaders = (): IDataColumn[] => {
Cell: (cellProps: ICellProps): JSX.Element => (
<TextCell value={cellProps.cell.value} />
),
sortType: "caseInsensitive",
},
{
title: "Status",

View file

@ -5,13 +5,16 @@ import classnames from "classnames";
import FileSaver from "file-saver";
import { QueryContext } from "context/query";
import { useDebouncedCallback } from "use-debounce";
import { find } from "lodash";
import {
generateCSVFilename,
generateCSVQueryResults,
} from "utilities/generate_csv";
import { osqueryTables } from "utilities/osquery_tables";
import { ICampaign, ICampaignError } from "interfaces/campaign";
import { ITarget } from "interfaces/target";
import { IQueryTableColumn } from "interfaces/osquery_table";
import Button from "components/buttons/Button";
import Icon from "components/Icon/Icon";
@ -22,6 +25,7 @@ import QueryResultsHeading from "components/queries/queryResults/QueryResultsHea
import AwaitingResults from "components/queries/queryResults/AwaitingResults";
import InfoBanner from "components/InfoBanner";
import CustomLink from "components/CustomLink";
import { checkTable } from "utilities/sql_tools";
import generateColumnConfigsFromRows from "./QueryResultsTableConfig";
@ -73,6 +77,9 @@ const QueryResults = ({
const [queryResultsForTableRender, setQueryResultsForTableRender] = useState(
queryResults
);
const [osqueryTableColumns, setOsqueryTableColumns] = useState<
IQueryTableColumn[] | []
>([]);
// immediately reset results
const onRunAgain = useCallback(() => {
@ -91,10 +98,25 @@ const QueryResults = ({
debounceQueryResults(queryResults);
}, [queryResults, debounceQueryResults]);
// Set table/s columns from SQL
useEffect(() => {
const tableNames =
(lastEditedQueryBody && checkTable(lastEditedQueryBody).tables) || [];
let columns: IQueryTableColumn[] | [] = [];
tableNames.forEach((tableName: string) => {
const tableColumns =
find(osqueryTables, { name: tableName })?.columns || [];
columns = [...columns, ...tableColumns];
});
setOsqueryTableColumns(columns);
}, [lastEditedQueryBody]);
useEffect(() => {
if (queryResults && queryResults.length > 0) {
const newResultsColumnConfigs = generateColumnConfigsFromRows(
queryResults
queryResults,
osqueryTableColumns
);
// Update tableHeaders if new headers are found
if (newResultsColumnConfigs !== resultsColumnConfigs) {

View file

@ -4,6 +4,7 @@
import React from "react";
import { CellProps, Column, HeaderProps } from "react-table";
import { find } from "lodash";
import DefaultColumnFilter from "components/TableContainer/DataTable/DefaultColumnFilter";
import HeaderCell from "components/TableContainer/DataTable/HeaderCell/HeaderCell";
@ -11,6 +12,7 @@ import {
getUniqueColumnNamesFromRows,
internallyTruncateText,
} from "utilities/helpers";
import { IQueryTableColumn } from "interfaces/osquery_table";
const _unshiftHostname = <T extends object>(columns: Column<T>[]) => {
const newHeaders = [...columns];
@ -32,10 +34,28 @@ const _unshiftHostname = <T extends object>(columns: Column<T>[]) => {
return newHeaders;
};
// Sorts numerical columns correctly while perserving case insensitive sort for text columns
const sortType = (
colName: string | number | symbol,
osqueryTableColumns?: IQueryTableColumn[] | []
) => {
if (typeof colName === "string" && !!osqueryTableColumns) {
const numberTypes = ["integer", "bigint", "unsigned_bigint", "double"];
const type = find(osqueryTableColumns, { name: colName })?.type;
if (type && numberTypes.includes(type)) {
return "alphanumeric";
}
}
return "caseInsensitive";
};
const generateColumnConfigsFromRows = <T extends Record<keyof T, unknown>>(
// TODO - narrow typing down this entire chain of logic
// typed as any[] to accomodate loose typing of websocket API
results: T[] // {col:val, ...} for each row of query results
results: T[], // {col:val, ...} for each row of query results
osqueryTableColumns?: IQueryTableColumn[] | []
): Column<T>[] => {
const uniqueColumnNames = getUniqueColumnNamesFromRows(results);
const columnsConfigs = uniqueColumnNames.map<Column<T>>((colName) => {
@ -56,7 +76,7 @@ const generateColumnConfigsFromRows = <T extends Record<keyof T, unknown>>(
},
Filter: DefaultColumnFilter,
disableSortBy: false,
sortType: "caseInsensitive",
sortType: sortType(colName, osqueryTableColumns),
};
});
return _unshiftHostname(columnsConfigs);

View file

@ -4,6 +4,7 @@ import endpoints from "utilities/endpoints";
import { IOperatingSystemVersion } from "interfaces/operating_system";
import { OsqueryPlatform } from "interfaces/platform";
import { buildQueryStringFromParams } from "utilities/url";
import { API_NO_TEAM_ID } from "interfaces/team";
// TODO: add platforms to this constant as new ones are supported
export const OS_VERSIONS_API_SUPPORTED_PLATFORMS = [
@ -49,6 +50,11 @@ export interface IOSVersionResponse {
os_version: IOperatingSystemVersion;
}
type IGetOSVersionsRequestQueryParams = Record<
string,
string | number | undefined
>;
export const getOSVersions = ({
platform,
teamId,
@ -62,16 +68,21 @@ export const getOSVersions = ({
const { OS_VERSIONS } = endpoints;
let path = OS_VERSIONS;
const queryString = buildQueryStringFromParams({
const params: IGetOSVersionsRequestQueryParams = {
platform,
team_id: teamId,
os_name,
os_version,
order_key,
order_direction,
page,
per_page,
});
};
if (teamId !== API_NO_TEAM_ID) {
params.team_id = teamId;
}
const queryString = buildQueryStringFromParams(params);
if (queryString) path += `?${queryString}`;

View file

@ -117,6 +117,13 @@ $max-width: 2560px;
cursor: default;
}
@mixin disabled-checkbox {
background-color: $ui-fleet-black-25;
border-color: $ui-fleet-black-25;
pointer-events: none;
cursor: default;
}
@mixin grey-text {
color: $ui-fleet-black-75;
}

View file

@ -44,7 +44,7 @@
repo: "confidential"
-
task: "AP invoice monitoring" # TODO tie this to a responsibility
startedOn: "2024-03-31"
startedOn: "2024-04-01"
frequency: "Weekly"
description: "Look for new accounts payable invoices and make sure that Fleet's suppliers are paid"
moreInfoUrl:
@ -64,7 +64,7 @@
repo: "confidential"
-
task: "Vanta check" # TODO tie this to a responsibility
startedOn: "2024-03-01"
startedOn: "2024-04-01"
frequency: "Monthly"
description: "Look for any new actions in Vanta due in the upcoming months and create issues to ensure they're done on time"
moreInfoUrl:

View file

@ -3,7 +3,7 @@
-
task: "Check browser compatibility for fleetdm.com"
startedOn: "2024-03-01"
startedOn: "2024-03-06"
frequency: "Monthly"
description: "Run `npm audit --only=prod` to check for vulnerabilities on the production dependencies of fleetdm.com."
moreInfoUrl: "https://fleetdm.com/handbook/digital-experience#check-production-dependencies-of-fleetdm-com"

View file

@ -124,6 +124,7 @@ Next, create a new GitHub issue using the [Release QA template](https://github.c
The issue's template will contain validation steps for Fleet and individual `fleetd` components. Remove any instructions that do not apply to this release.
### Indicate your product group is release-ready
Once a product group completes its QA process during the freeze period, its QA lead moves the smoke testing ticket to the "Ready for release" column on their ZenHub board. They then notify the release ritual DRI by tagging them in a comment, indicating that their group is prepared for release. The release ritual DRI starts the [release process](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Releasing-Fleet.md) after all QA leads have made these updates and confirmed their readiness for release.

View file

@ -56,7 +56,7 @@ variable "database_name" {
variable "fleet_image" {
description = "the name of the container image to run"
default = "fleetdm/fleet:v4.47.1"
default = "fleetdm/fleet:v4.47.2"
}
variable "software_inventory" {

View file

@ -68,5 +68,5 @@ variable "redis_mem" {
}
variable "image" {
default = "fleet:v4.47.1"
default = "fleet:v4.47.2"
}

View file

@ -61,3 +61,11 @@ queries:
- path: ../lib/collect-failed-login-attempts.queries.yml
- path: ../lib/collect-usb-devices.queries.yml
- path: ../lib/collect-vs-code-extensions.queries.yml
- name: Collect expiration date for MDM SCEP certificates
description: "For the following issue: https://github.com/fleetdm/confidential/issues/4518. Returns expiration date for macOS hosts's MDM SCEP certs."
query: "SELECT common_name, datetime(not_valid_after,'unixepoch') AS expires FROM certificates WHERE 'common_name' LIKE '%FleetDM Identity%';"
platform: darwin
interval: 300
automations_enabled: false
observer_can_run: true

View file

@ -24,7 +24,7 @@
"dompurify": "3.0.3",
"es6-object-assign": "1.1.0",
"es6-promise": "4.2.8",
"express": "4.17.3",
"express": "4.19.2",
"file-saver": "1.3.8",
"history": "2.1.0",
"isomorphic-fetch": "3.0.0",

View file

@ -172,14 +172,24 @@ var hostDetailQueries = map[string]DetailQuery{
},
},
"os_version_windows": {
// display_version is not available in some versions of
// Windows (Server 2019). By including it using a JOIN it can
// return no rows and the query will still succeed
Query: `
SELECT os.name, r.data as display_version, k.version
WITH display_version_table AS (
SELECT data as display_version
FROM registry
WHERE path = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\DisplayVersion'
)
SELECT
os.name,
COALESCE(d.display_version, '') AS display_version,
k.version
FROM
registry r,
os_version os,
kernel_info k
WHERE r.path = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\DisplayVersion'
`,
LEFT JOIN
display_version_table d`,
Platforms: []string{"windows"},
IngestFunc: func(ctx context.Context, logger log.Logger, host *fleet.Host, rows []map[string]string) error {
if len(rows) != 1 {
@ -531,20 +541,29 @@ var extraDetailQueries = map[string]DetailQuery{
// This query is used to populate the `operating_systems` and `host_operating_system`
// tables. Separately, the `hosts` table is populated via the `os_version` and
// `os_version_windows` detail queries above.
//
// DisplayVersion doesn't exist on all versions of Windows (Server 2019).
// To prevent the query from failing in those cases, we join
// the values in when they exist, alternatively the column is
// just empty.
Query: `
WITH display_version_table AS (
SELECT data as display_version
FROM registry
WHERE path = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\DisplayVersion'
)
SELECT
os.name,
os.platform,
os.arch,
k.version as kernel_version,
os.version,
r.data as display_version
COALESCE(d.display_version, '') AS display_version
FROM
os_version os,
kernel_info k,
registry r
WHERE
r.path = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\DisplayVersion'`,
kernel_info k
LEFT JOIN
display_version_table d`,
Platforms: []string{"windows"},
DirectIngestFunc: directIngestOSWindows,
},

File diff suppressed because one or more lines are too long

View file

@ -13,7 +13,7 @@ variable "fleet_config" {
type = object({
mem = optional(number, 4096)
cpu = optional(number, 512)
image = optional(string, "fleetdm/fleet:v4.47.1")
image = optional(string, "fleetdm/fleet:v4.47.2")
family = optional(string, "fleet")
sidecars = optional(list(any), [])
depends_on = optional(list(any), [])

View file

@ -74,7 +74,7 @@ variable "fleet_config" {
type = object({
mem = optional(number, 4096)
cpu = optional(number, 512)
image = optional(string, "fleetdm/fleet:v4.47.1")
image = optional(string, "fleetdm/fleet:v4.47.2")
family = optional(string, "fleet")
sidecars = optional(list(any), [])
depends_on = optional(list(any), [])

View file

@ -17,7 +17,7 @@ provider "aws" {
}
locals {
fleet_image = "fleetdm/fleet:v4.47.1"
fleet_image = "fleetdm/fleet:v4.47.2"
domain_name = "example.com"
}

View file

@ -167,7 +167,7 @@ variable "fleet_config" {
type = object({
mem = optional(number, 4096)
cpu = optional(number, 512)
image = optional(string, "fleetdm/fleet:v4.47.1")
image = optional(string, "fleetdm/fleet:v4.47.2")
family = optional(string, "fleet")
sidecars = optional(list(any), [])
depends_on = optional(list(any), [])

View file

@ -59,8 +59,8 @@ module "fleet" {
fleet_config = {
# To avoid pull-rate limiting from dockerhub, consider using our quay.io mirror
# for the Fleet image. e.g. "quay.io/fleetdm/fleet:v4.47.1"
image = "fleetdm/fleet:v4.47.1" # override default to deploy the image you desire
# for the Fleet image. e.g. "quay.io/fleetdm/fleet:v4.47.2"
image = "fleetdm/fleet:v4.47.2" # override default to deploy the image you desire
# See https://fleetdm.com/docs/deploy/reference-architectures#aws for appropriate scaling
# memory and cpu.
autoscaling = {

View file

@ -215,7 +215,7 @@ variable "fleet_config" {
type = object({
mem = optional(number, 4096)
cpu = optional(number, 512)
image = optional(string, "fleetdm/fleet:v4.47.1")
image = optional(string, "fleetdm/fleet:v4.47.2")
family = optional(string, "fleet")
sidecars = optional(list(any), [])
depends_on = optional(list(any), [])

View file

@ -1,6 +1,6 @@
{
"name": "fleetctl",
"version": "v4.47.1",
"version": "v4.47.2",
"description": "Installer for the fleetctl CLI tool",
"bin": {
"fleetctl": "./run.js"

View file

@ -258,7 +258,7 @@ module.exports.custom = {
'.github/ISSUE_TEMPLATE': ['mikermcneil', 'lukeheath', 'sampfluger88'],
'.github/ISSUE_TEMPLATE/bug-report.md': ['xpkoala','noahtalerman', 'lukeheath'],
'.github/ISSUE_TEMPLATE/feature-request.md': ['xpkoala','noahtalerman', 'lukeheath'],
'.github/ISSUE_TEMPLATE/smoke-tests.md': ['xpkoala','lukeheath','noahtalerman', 'lukeheath'],
'.github/ISSUE_TEMPLATE/release-qa.md': ['xpkoala','lukeheath','noahtalerman', 'lukeheath'],
},
confidentialGithubRepoMaintainersByPath: {// fleetdm/confidential

View file

@ -35,7 +35,8 @@ module.exports = {
},
headers: { accept: 'application/json' }
})
.retry({raw:{statusCode: 503}})
.retry({raw:{statusCode: 503}})// Retry requests that respond with "503: Service temporarily unavailable"
.retry({raw:{statusCode: 504}})// Retry requests that respond with "504: Endpoint request timed out"
.tolerate((err)=>{
// If an error occurs while sending a request to Vanta, we'll add the error to the errorReportById object, with this connections ID set as the key.
errorReportById[connectionIdAsString] = new Error(`Could not refresh the token for Vanta connection (id: ${connectionIdAsString}). Full error: ${err}`);

200
yarn.lock
View file

@ -6639,29 +6639,13 @@ bn.js@^5.0.0, bn.js@^5.2.1:
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
body-parser@1.19.2:
version "1.19.2"
resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz"
integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==
body-parser@1.20.2:
version "1.20.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
dependencies:
bytes "3.1.2"
content-type "~1.0.4"
debug "2.6.9"
depd "~1.1.2"
http-errors "1.8.1"
iconv-lite "0.4.24"
on-finished "~2.3.0"
qs "6.9.7"
raw-body "2.4.3"
type-is "~1.6.18"
body-parser@1.20.1:
version "1.20.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
dependencies:
bytes "3.1.2"
content-type "~1.0.4"
content-type "~1.0.5"
debug "2.6.9"
depd "2.0.0"
destroy "1.2.0"
@ -6669,7 +6653,7 @@ body-parser@1.20.1:
iconv-lite "0.4.24"
on-finished "2.4.1"
qs "6.11.0"
raw-body "2.5.1"
raw-body "2.5.2"
type-is "~1.6.18"
unpipe "1.0.0"
@ -7551,10 +7535,10 @@ content-disposition@0.5.4:
dependencies:
safe-buffer "5.2.1"
content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
content-type@~1.0.4, content-type@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.9.0"
@ -7571,16 +7555,16 @@ cookie-signature@1.0.6:
resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
cookie@0.4.2, cookie@^0.4.2:
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
cookie@^0.4.2:
version "0.4.2"
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
cookie@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
copy-descriptor@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
@ -8034,7 +8018,7 @@ depd@2.0.0:
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
depd@^1.1.2, depd@~1.1.2:
depd@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
@ -8057,11 +8041,6 @@ destroy@1.2.0:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
detect-file@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz"
@ -9215,53 +9194,17 @@ expect@^29.2.0:
jest-message-util "^29.2.0"
jest-util "^29.2.0"
express@4.17.3:
version "4.17.3"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1"
integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==
express@4.19.2, express@^4.17.3:
version "4.19.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.19.2"
body-parser "1.20.2"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.4.2"
cookie-signature "1.0.6"
debug "2.6.9"
depd "~1.1.2"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "~1.1.2"
fresh "0.5.2"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "~2.3.0"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.9.7"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.17.2"
serve-static "1.14.2"
setprototypeof "1.2.0"
statuses "~1.5.0"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
express@^4.17.3:
version "4.18.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.1"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.5.0"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
@ -9479,19 +9422,6 @@ finalhandler@1.2.0:
statuses "2.0.1"
unpipe "~1.0.0"
finalhandler@~1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz"
integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
dependencies:
debug "2.6.9"
encodeurl "~1.0.2"
escape-html "~1.0.3"
on-finished "~2.3.0"
parseurl "~1.3.3"
statuses "~1.5.0"
unpipe "~1.0.0"
find-cache-dir@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
@ -10413,17 +10343,6 @@ http-cache-semantics@^4.1.0:
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-errors@1.8.1:
version "1.8.1"
resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz"
integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.1"
http-errors@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
@ -14102,13 +14021,6 @@ on-finished@2.4.1:
dependencies:
ee-first "1.1.1"
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
dependencies:
ee-first "1.1.1"
on-headers@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
@ -14907,25 +14819,13 @@ puppeteer-core@^2.1.1:
rimraf "^2.6.1"
ws "^6.1.0"
qs@6.11.0:
qs@6.11.0, qs@^6.10.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
dependencies:
side-channel "^1.0.4"
qs@6.9.7:
version "6.9.7"
resolved "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz"
integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
qs@^6.10.0:
version "6.10.3"
resolved "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz"
integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==
dependencies:
side-channel "^1.0.4"
query-string@^3.0.0:
version "3.0.3"
resolved "https://registry.npmjs.org/query-string/-/query-string-3.0.3.tgz"
@ -14998,20 +14898,10 @@ range-parser@^1.2.1, range-parser@~1.2.1:
resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@2.4.3:
version "2.4.3"
resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz"
integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==
dependencies:
bytes "3.1.2"
http-errors "1.8.1"
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-body@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
raw-body@2.5.2:
version "2.5.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
dependencies:
bytes "3.1.2"
http-errors "2.0.0"
@ -15977,25 +15867,6 @@ semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semve
dependencies:
lru-cache "^6.0.0"
send@0.17.2:
version "0.17.2"
resolved "https://registry.npmjs.org/send/-/send-0.17.2.tgz"
integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==
dependencies:
debug "2.6.9"
depd "~1.1.2"
destroy "~1.0.4"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
http-errors "1.8.1"
mime "1.6.0"
ms "2.1.3"
on-finished "~2.3.0"
range-parser "~1.2.1"
statuses "~1.5.0"
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
@ -16037,16 +15908,6 @@ serialize-javascript@^6.0.1:
dependencies:
randombytes "^2.1.0"
serve-static@1.14.2:
version "1.14.2"
resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz"
integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==
dependencies:
encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.3"
send "0.17.2"
serve-static@1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
@ -16439,11 +16300,6 @@ statuses@2.0.1, statuses@^2.0.0:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
version "1.5.0"
resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
stdout-stream@^1.4.0:
version "1.4.1"
resolved "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz"