diff --git a/CODEOWNERS b/CODEOWNERS
index 4a7bc630f41f..b952d8777f0f 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -72,7 +72,6 @@ go.mod @fleetdm/go
#
# (see website/config/custom.js for DRIs of other paths not listed here)
##############################################################################################
-/website/views/pages/pricing.ejs @mikermcneil # « CEO is DRI for pricing
/handbook/company/pricing-features-table.yml @mikermcneil # « CEO is current DRI for features table
##############################################################################################
diff --git a/articles/fleet-4.37.0.md b/articles/fleet-4.37.0.md
index 0f4cf5ed80f8..f3a2c7c37bac 100644
--- a/articles/fleet-4.37.0.md
+++ b/articles/fleet-4.37.0.md
@@ -1,4 +1,4 @@
-# Fleet 4.37.0 | Remote script execution & Puppet support.
+# Fleet 4.37.0 | Puppet support.
![Fleet 4.37.0](../website/assets/images/articles/fleet-4.37.0-1600x900@2x.png)
@@ -13,11 +13,12 @@ For upgrade instructions, see our [upgrade guide](https://fleetdm.com/docs/deplo
* Puppet support
* Web user interface improvements
+
### Vulnerability dashboard
diff --git a/articles/introducing-cross-platform-script-execution.md b/articles/introducing-cross-platform-script-execution
similarity index 100%
rename from articles/introducing-cross-platform-script-execution.md
rename to articles/introducing-cross-platform-script-execution
diff --git a/changes/12927-disk-encryption-settings b/changes/12927-disk-encryption-settings
new file mode 100644
index 000000000000..a9464b7d5bac
--- /dev/null
+++ b/changes/12927-disk-encryption-settings
@@ -0,0 +1 @@
+* Deprecate `mdm.macos_settings.enable_disk_encryption` in favor of `mdm.enable_disk_encryption`
diff --git a/changes/12932-bitlocker-api-updates b/changes/12932-bitlocker-api-updates
new file mode 100644
index 000000000000..0ce9b45e8a1b
--- /dev/null
+++ b/changes/12932-bitlocker-api-updates
@@ -0,0 +1,4 @@
+- Added `GET /mdm/disk_encryption/summary` endpoint to get the disk encryption summary for macOS and
+ Windows devices.
+- Added `os_settings` and `os_settings_disk_encryption` filters to `GET /hosts`, `GET /hosts/count`,
+ `GET /api/v1/fleet/labels/{id}/hosts` endpoints to filter hosts by OS settings.
diff --git a/changes/12933-bitlocker-host-details-api b/changes/12933-bitlocker-host-details-api
new file mode 100644
index 000000000000..ccb11df8b74e
--- /dev/null
+++ b/changes/12933-bitlocker-host-details-api
@@ -0,0 +1 @@
+- Added `mdm.os_settings` to `GET /api/v1/hosts/{id}` response.
diff --git a/changes/bug-13894-failing-policies-styling b/changes/bug-13894-failing-policies-styling
new file mode 100644
index 000000000000..5bd83a7b0961
--- /dev/null
+++ b/changes/bug-13894-failing-policies-styling
@@ -0,0 +1 @@
+* Fix styling for host details/device user failing policies call out
\ No newline at end of file
diff --git a/changes/issue-13953-changes-to-controls-page-for-bitlocker b/changes/issue-13953-changes-to-controls-page-for-bitlocker
new file mode 100644
index 000000000000..728d93122e02
--- /dev/null
+++ b/changes/issue-13953-changes-to-controls-page-for-bitlocker
@@ -0,0 +1 @@
+- change Controls/Disk Encryption and host details page to include windows bitlocker information.
diff --git a/changes/issue-13954-orbit-disk-encryption-key b/changes/issue-13954-orbit-disk-encryption-key
new file mode 100644
index 000000000000..82767942ec0b
--- /dev/null
+++ b/changes/issue-13954-orbit-disk-encryption-key
@@ -0,0 +1 @@
+* Added the `POST /api/fleet/orbit/disk_encryption_key` endpoint for Windows hosts to report the bitlocker encryption key.
diff --git a/changes/issue-14007-support-get-windows-encryption-key b/changes/issue-14007-support-get-windows-encryption-key
new file mode 100644
index 000000000000..0705f8e974f6
--- /dev/null
+++ b/changes/issue-14007-support-get-windows-encryption-key
@@ -0,0 +1 @@
+* Added support to return the decrypted disk encryption key of a Windows host.
diff --git a/cmd/fleet/cron.go b/cmd/fleet/cron.go
index 99f448c5da80..b1a41965af6a 100644
--- a/cmd/fleet/cron.go
+++ b/cmd/fleet/cron.go
@@ -18,6 +18,7 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/license"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/fleet"
+ "github.com/fleetdm/fleet/v4/server/mdm"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/policies"
"github.com/fleetdm/fleet/v4/server/ptr"
@@ -852,7 +853,7 @@ func verifyDiskEncryptionKeys(
if key.UpdatedAt.After(latest) {
latest = key.UpdatedAt
}
- if _, err := apple_mdm.DecryptBase64CMS(key.Base64Encrypted, cert.Leaf, cert.PrivateKey); err != nil {
+ if _, err := mdm.DecryptBase64CMS(key.Base64Encrypted, cert.Leaf, cert.PrivateKey); err != nil {
undecryptable = append(undecryptable, key.HostID)
continue
}
diff --git a/cmd/fleetctl/apply_test.go b/cmd/fleetctl/apply_test.go
index 137c409ec786..62872eb91766 100644
--- a/cmd/fleetctl/apply_test.go
+++ b/cmd/fleetctl/apply_test.go
@@ -1043,13 +1043,13 @@ spec:
foo: qux
name: Team1
mdm:
+ enable_disk_encryption: false
macos_updates:
minimum_version: 10.10.10
deadline: 1992-03-01
macos_settings:
custom_settings:
- %s
- enable_disk_encryption: false
secrets:
- secret: BBB
`, mobileConfigPath))
@@ -1061,9 +1061,9 @@ spec:
require.Equal(t, "[+] applied 1 teams\n", runAppForTest(t, []string{"apply", "-f", name}))
assert.JSONEq(t, string(json.RawMessage(`{"config":{"views":{"foo":"qux"}}}`)), string(*savedTeam.Config.AgentOptions))
assert.Equal(t, fleet.TeamMDM{
+ EnableDiskEncryption: false,
MacOSSettings: fleet.MacOSSettings{
- CustomSettings: []string{mobileConfigPath},
- EnableDiskEncryption: false,
+ CustomSettings: []string{mobileConfigPath},
},
MacOSUpdates: fleet.MacOSUpdates{
MinimumVersion: optjson.SetString("10.10.10"),
@@ -1096,9 +1096,9 @@ spec:
require.True(t, ds.NewJobFuncInvoked)
// all left untouched, only setup assistant added
assert.Equal(t, fleet.TeamMDM{
+ EnableDiskEncryption: false,
MacOSSettings: fleet.MacOSSettings{
- CustomSettings: []string{mobileConfigPath},
- EnableDiskEncryption: false,
+ CustomSettings: []string{mobileConfigPath},
},
MacOSUpdates: fleet.MacOSUpdates{
MinimumVersion: optjson.SetString("10.10.10"),
@@ -1128,9 +1128,9 @@ spec:
require.Equal(t, "[+] applied 1 teams\n", runAppForTest(t, []string{"apply", "-f", name}))
// all left untouched, only bootstrap package added
assert.Equal(t, fleet.TeamMDM{
+ EnableDiskEncryption: false,
MacOSSettings: fleet.MacOSSettings{
- CustomSettings: []string{mobileConfigPath},
- EnableDiskEncryption: false,
+ CustomSettings: []string{mobileConfigPath},
},
MacOSUpdates: fleet.MacOSUpdates{
MinimumVersion: optjson.SetString("10.10.10"),
@@ -2885,7 +2885,7 @@ spec:
macos_settings:
enable_disk_encryption: true
`,
- wantErr: `Couldn't update macos_settings because MDM features aren't turned on in Fleet.`,
+ wantErr: `Couldn't edit enable_disk_encryption. Neither macOS MDM nor Windows is turned on`,
},
{
desc: "app config macos_settings.enable_disk_encryption false",
diff --git a/cmd/fleetctl/get.go b/cmd/fleetctl/get.go
index 60b87335cbcb..e94f145db27b 100644
--- a/cmd/fleetctl/get.go
+++ b/cmd/fleetctl/get.go
@@ -13,6 +13,7 @@ import (
"time"
"github.com/fatih/color"
+ "github.com/fleetdm/fleet/v4/pkg/rawjson"
"github.com/fleetdm/fleet/v4/pkg/secure"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/service"
@@ -166,12 +167,15 @@ func (eacp enrichedAppConfigPresenter) MarshalJSON() ([]byte, error) {
*fleet.VulnerabilitiesConfig
}
- return json.Marshal(&struct {
- fleet.EnrichedAppConfig
+ enrichedJSON, err := json.Marshal(fleet.EnrichedAppConfig(eacp))
+ if err != nil {
+ return nil, err
+ }
+
+ extraFieldsJSON, err := json.Marshal(&struct {
UpdateInterval UpdateIntervalConfigPresenter `json:"update_interval,omitempty"`
Vulnerabilities VulnerabilitiesConfigPresenter `json:"vulnerabilities,omitempty"`
}{
- EnrichedAppConfig: fleet.EnrichedAppConfig(eacp),
UpdateInterval: UpdateIntervalConfigPresenter{
eacp.UpdateInterval.OSQueryDetail.String(),
eacp.UpdateInterval.OSQueryPolicy.String(),
@@ -183,6 +187,13 @@ func (eacp enrichedAppConfigPresenter) MarshalJSON() ([]byte, error) {
eacp.Vulnerabilities,
},
})
+ if err != nil {
+ return nil, err
+ }
+
+ // we need to marshal and combine both groups separately because
+ // enrichedAppConfig has a custom marshaler.
+ return rawjson.CombineRoots(enrichedJSON, extraFieldsJSON)
}
func printConfig(c *cli.Context, config interface{}) error {
diff --git a/cmd/fleetctl/get_test.go b/cmd/fleetctl/get_test.go
index ff117e642004..88e612a637a4 100644
--- a/cmd/fleetctl/get_test.go
+++ b/cmd/fleetctl/get_test.go
@@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -168,15 +167,15 @@ func TestGetTeams(t *testing.T) {
}, nil
}
- b, err := ioutil.ReadFile(filepath.Join("testdata", "expectedGetTeamsText.txt"))
+ b, err := os.ReadFile(filepath.Join("testdata", "expectedGetTeamsText.txt"))
require.NoError(t, err)
expectedText := string(b)
- b, err = ioutil.ReadFile(filepath.Join("testdata", "expectedGetTeamsYaml.yml"))
+ b, err = os.ReadFile(filepath.Join("testdata", "expectedGetTeamsYaml.yml"))
require.NoError(t, err)
expectedYaml := string(b)
- b, err = ioutil.ReadFile(filepath.Join("testdata", "expectedGetTeamsJson.json"))
+ b, err = os.ReadFile(filepath.Join("testdata", "expectedGetTeamsJson.json"))
require.NoError(t, err)
// must read each JSON value separately and compact it
var buf bytes.Buffer
@@ -206,8 +205,8 @@ func TestGetTeams(t *testing.T) {
errBuffer.Reset()
actualJSON, err := runWithErrWriter([]string{"get", "teams", "--json"}, &errBuffer)
require.NoError(t, err)
- require.Equal(t, expectedJson, actualJSON.String())
require.Equal(t, errBuffer.String() == expiredBanner.String(), tt.shouldHaveExpiredBanner)
+ require.Equal(t, expectedJson, actualJSON.String())
errBuffer.Reset()
actualYaml, err := runWithErrWriter([]string{"get", "teams", "--yaml"}, &errBuffer)
@@ -433,7 +432,7 @@ func TestGetHosts(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- expected, err := ioutil.ReadFile(filepath.Join("testdata", tt.goldenFile))
+ expected, err := os.ReadFile(filepath.Join("testdata", tt.goldenFile))
require.NoError(t, err)
expectedResults := tt.scanner(string(expected))
actualResult := tt.scanner(runAppForTest(t, tt.args))
@@ -536,7 +535,7 @@ func TestGetHostsMDM(t *testing.T) {
}
if tt.goldenFile != "" {
- expected, err := ioutil.ReadFile(filepath.Join("testdata", tt.goldenFile))
+ expected, err := os.ReadFile(filepath.Join("testdata", tt.goldenFile))
require.NoError(t, err)
if ext := filepath.Ext(tt.goldenFile); ext == ".json" {
// the output of --json is not a json array, but a list of
diff --git a/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json b/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json
index 2bca9327cb1b..35a209176144 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json
+++ b/cmd/fleetctl/testdata/expectedGetConfigAppConfigJson.json
@@ -86,6 +86,7 @@
"enabled_and_configured": false,
"apple_bm_default_team": "",
"windows_enabled_and_configured": false,
+ "enable_disk_encryption": false,
"macos_updates": {
"minimum_version": null,
"deadline": null
@@ -96,8 +97,7 @@
"webhook_url": ""
},
"macos_settings": {
- "custom_settings": null,
- "enable_disk_encryption": false
+ "custom_settings": null
},
"macos_setup": {
"bootstrap_package": null,
diff --git a/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml b/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml
index 0206e1cf7683..dc026f027caa 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml
+++ b/cmd/fleetctl/testdata/expectedGetConfigAppConfigYaml.yml
@@ -19,6 +19,7 @@ spec:
enabled_and_configured: false
apple_bm_default_team: ""
windows_enabled_and_configured: false
+ enable_disk_encryption: false
macos_migration:
enable: false
mode: ""
@@ -28,7 +29,6 @@ spec:
deadline: null
macos_settings:
custom_settings:
- enable_disk_encryption: false
macos_setup:
bootstrap_package:
enable_end_user_authentication: false
diff --git a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json
index 632d37cc8fe7..42a6018435d1 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json
+++ b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigJson.json
@@ -44,6 +44,7 @@
"apple_bm_enabled_and_configured": false,
"enabled_and_configured": false,
"windows_enabled_and_configured": false,
+ "enable_disk_encryption": false,
"macos_updates": {
"minimum_version": null,
"deadline": null
@@ -54,8 +55,7 @@
"webhook_url": ""
},
"macos_settings": {
- "custom_settings": null,
- "enable_disk_encryption": false
+ "custom_settings": null
},
"macos_setup": {
"bootstrap_package": null,
diff --git a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml
index 4c835b47e864..0e5b42befeb6 100644
--- a/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml
+++ b/cmd/fleetctl/testdata/expectedGetConfigIncludeServerConfigYaml.yml
@@ -19,6 +19,7 @@ spec:
apple_bm_terms_expired: false
enabled_and_configured: false
windows_enabled_and_configured: false
+ enable_disk_encryption: false
macos_migration:
enable: false
mode: ""
@@ -28,7 +29,6 @@ spec:
deadline: null
macos_settings:
custom_settings:
- enable_disk_encryption: false
macos_setup:
bootstrap_package:
enable_end_user_authentication: false
diff --git a/cmd/fleetctl/testdata/expectedGetTeamsJson.json b/cmd/fleetctl/testdata/expectedGetTeamsJson.json
index 19152a690cd9..6a99943e9440 100644
--- a/cmd/fleetctl/testdata/expectedGetTeamsJson.json
+++ b/cmd/fleetctl/testdata/expectedGetTeamsJson.json
@@ -24,13 +24,13 @@
"enable_software_inventory": true
},
"mdm": {
+ "enable_disk_encryption": false,
"macos_updates": {
"minimum_version": null,
"deadline": null
},
"macos_settings": {
- "custom_settings": null,
- "enable_disk_encryption": false
+ "custom_settings": null
},
"macos_setup": {
"bootstrap_package": null,
@@ -84,13 +84,13 @@
}
},
"mdm": {
+ "enable_disk_encryption": false,
"macos_updates": {
"minimum_version": "12.3.1",
"deadline": "2021-12-14"
},
"macos_settings": {
- "custom_settings": null,
- "enable_disk_encryption": false
+ "custom_settings": null
},
"macos_setup": {
"bootstrap_package": null,
diff --git a/cmd/fleetctl/testdata/expectedGetTeamsYaml.yml b/cmd/fleetctl/testdata/expectedGetTeamsYaml.yml
index 2b571ae8b5bb..a6905cf569ee 100644
--- a/cmd/fleetctl/testdata/expectedGetTeamsYaml.yml
+++ b/cmd/fleetctl/testdata/expectedGetTeamsYaml.yml
@@ -7,12 +7,12 @@ spec:
enable_host_users: true
enable_software_inventory: true
mdm:
+ enable_disk_encryption: false
macos_updates:
minimum_version: null
deadline: null
macos_settings:
custom_settings:
- enable_disk_encryption: false
macos_setup:
bootstrap_package:
enable_end_user_authentication: false
@@ -36,12 +36,12 @@ spec:
enable_host_users: false
enable_software_inventory: false
mdm:
+ enable_disk_encryption: false
macos_updates:
minimum_version: "12.3.1"
deadline: "2021-12-14"
macos_settings:
custom_settings:
- enable_disk_encryption: false
macos_setup:
bootstrap_package:
enable_end_user_authentication: false
diff --git a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml
index bcd27f522e7e..5f25121e3b91 100644
--- a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml
+++ b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigEmpty.yml
@@ -19,13 +19,13 @@ spec:
apple_bm_terms_expired: false
enabled_and_configured: true
windows_enabled_and_configured: false
+ enable_disk_encryption: false
macos_migration:
enable: false
mode: ""
webhook_url: ""
macos_settings:
custom_settings: null
- enable_disk_encryption: false
macos_setup:
bootstrap_package: null
enable_end_user_authentication: false
diff --git a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml
index 0f94a3c0b5e0..4b2fd0c151e1 100644
--- a/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml
+++ b/cmd/fleetctl/testdata/macosSetupExpectedAppConfigSet.yml
@@ -19,13 +19,13 @@ spec:
apple_bm_terms_expired: false
enabled_and_configured: true
windows_enabled_and_configured: false
+ enable_disk_encryption: false
macos_migration:
enable: false
mode: ""
webhook_url: ""
macos_settings:
custom_settings: null
- enable_disk_encryption: false
macos_setup:
bootstrap_package: %s
enable_end_user_authentication: false
diff --git a/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Empty.yml b/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Empty.yml
index 346bbc2eb753..a3668e64b391 100644
--- a/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Empty.yml
+++ b/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Empty.yml
@@ -7,9 +7,9 @@ spec:
enable_host_users: true
enable_software_inventory: true
mdm:
+ enable_disk_encryption: false
macos_settings:
custom_settings: null
- enable_disk_encryption: false
macos_setup:
bootstrap_package: null
enable_end_user_authentication: false
@@ -27,9 +27,9 @@ spec:
enable_host_users: true
enable_software_inventory: true
mdm:
+ enable_disk_encryption: false
macos_settings:
custom_settings: null
- enable_disk_encryption: false
macos_setup:
bootstrap_package: null
macos_setup_assistant: null
diff --git a/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Set.yml b/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Set.yml
index 45f1733019c1..95e49d032146 100644
--- a/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Set.yml
+++ b/cmd/fleetctl/testdata/macosSetupExpectedTeam1And2Set.yml
@@ -7,9 +7,9 @@ spec:
enable_host_users: true
enable_software_inventory: true
mdm:
+ enable_disk_encryption: false
macos_settings:
custom_settings: null
- enable_disk_encryption: false
macos_setup:
bootstrap_package: %s
enable_end_user_authentication: false
@@ -27,9 +27,9 @@ spec:
enable_host_users: false
enable_software_inventory: false
mdm:
+ enable_disk_encryption: false
macos_settings:
custom_settings: null
- enable_disk_encryption: false
macos_setup:
bootstrap_package: %s
macos_setup_assistant: %s
diff --git a/cmd/fleetctl/testdata/macosSetupExpectedTeam1Empty.yml b/cmd/fleetctl/testdata/macosSetupExpectedTeam1Empty.yml
index 21d9b9d8db20..8ad10fc6c51a 100644
--- a/cmd/fleetctl/testdata/macosSetupExpectedTeam1Empty.yml
+++ b/cmd/fleetctl/testdata/macosSetupExpectedTeam1Empty.yml
@@ -7,9 +7,9 @@ spec:
enable_host_users: false
enable_software_inventory: false
mdm:
+ enable_disk_encryption: false
macos_settings:
custom_settings: null
- enable_disk_encryption: false
macos_setup:
bootstrap_package: null
enable_end_user_authentication: false
diff --git a/docs/Configuration/configuration-files/README.md b/docs/Configuration/configuration-files/README.md
index 9cc12b3321ac..8b8f34b8cf62 100644
--- a/docs/Configuration/configuration-files/README.md
+++ b/docs/Configuration/configuration-files/README.md
@@ -529,8 +529,10 @@ Use with caution as this may break Fleet ingestion of hosts data.
```yaml
features:
detail_query_overrides:
- # null allows to disable the "users" query from running on hosts.
+ # null disables the "users" query from running on hosts.
users: null
+ # "" disables the "disk_encryption_linux" query from running on hosts.
+ disk_encryption_linux: ""
# this replaces the hardcoded "mdm" detail query.
mdm: "SELECT enrolled, server_url, installed_from_dep, payload_identifier FROM mdm;"
```
diff --git a/docs/Contributing/API-for-contributors.md b/docs/Contributing/API-for-contributors.md
index 7724b770b74e..ddefdb2e9a53 100644
--- a/docs/Contributing/API-for-contributors.md
+++ b/docs/Contributing/API-for-contributors.md
@@ -533,6 +533,7 @@ The MDM endpoints exist to support the related command-line interface sub-comman
- [Complete SSO during DEP enrollment](#complete-sso-during-dep-enrollment)
- [Preassign profiles to devices](#preassign-profiles-to-devices)
- [Match preassigned profiles](#match-preassigned-profiles)
+- [Get FileVault statistics](#get-filevault-statistics)
### Generate Apple DEP Key Pair
@@ -701,6 +702,44 @@ This endpoint stores a profile to be assigned to a host at some point in the fut
`Status: 204`
+### Get FileVault statistics
+
+_Available in Fleet Premium_
+
+Get aggregate status counts of disk encryption enforced on macOS hosts.
+
+The summary can optionally be filtered by team id.
+
+`GET /api/v1/fleet/mdm/apple/filevault/summary`
+
+#### Parameters
+
+| Name | Type | In | Description |
+| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
+| team_id | string | query | _Available in Fleet Premium_ The team id to filter the summary. |
+
+#### Example
+
+Get aggregate status counts of Apple disk encryption profiles applying to macOS hosts enrolled to Fleet's MDM that are not assigned to any team.
+
+`GET /api/v1/fleet/mdm/apple/filevault/summary`
+
+##### Default response
+
+`Status: 200`
+
+```json
+{
+ "verified": 123,
+ "verifying": 123,
+ "action_required": 123,
+ "enforcing": 123,
+ "failed": 123,
+ "removing_enforcement": 123
+}
+```
+
+
### Match preassigned profiles
_Available in Fleet Premium_
@@ -2291,7 +2330,9 @@ Gets all information required by Fleet Desktop, this includes things like the nu
{
"failing_policies_count": 3,
"notifications": {
- "needs_mdm_migration": true
+ "needs_mdm_migration": true,
+ "renew_enrollment_profile": false,
+ "enforce_bitlocker_encryption": false,
},
"config": {
"org_info": {
@@ -2313,6 +2354,7 @@ In regards to the `notifications` key:
- `needs_mdm_migration` means that the device fits all the requirements to allow the user to initiate an MDM migration to Fleet.
- `renew_enrollment_profile` means that the device is currently unmanaged from MDM but should be DEP enrolled into Fleet.
+- `enforce_bitlocker_encryption` applies only to Windows devices and means that it should encrypt the disk and report the encryption key back to Fleet.
#### Get device's policies
diff --git a/docs/Contributing/FAQ.md b/docs/Contributing/FAQ.md
index 3d3f69c92bfa..c7522aa537bc 100644
--- a/docs/Contributing/FAQ.md
+++ b/docs/Contributing/FAQ.md
@@ -93,6 +93,7 @@ If you also have Fleetd running on hosts, it will need access to these API endpo
* `/api/fleet/orbit/ping`
* `/api/fleet/orbit/scripts/request`
* `/api/fleet/orbit/scripts/result`
+* `/api/fleet/orbit/disk_encryption_key`
* `/api/osquery/log`
diff --git a/docs/Get started/anatomy.md b/docs/Get started/anatomy.md
index 757c9614a148..7bc314d2454b 100644
--- a/docs/Get started/anatomy.md
+++ b/docs/Get started/anatomy.md
@@ -12,7 +12,7 @@ Fleetctl (pronouced “fleet control”) is a CLI (command line interface) tool
## Fleetd
-Fleetd is a bundle of agents provided by Fleet to gather information about your devices. Fleetd includes [osquery](https://www.osquery.io/), Orbit, and Fleet Desktop. [Docs](https://fleetdm.com/docs/using-fleet/fleet-ui).
+Fleetd is a bundle of agents provided by Fleet to gather information about your devices. Fleetd includes [osquery](https://www.osquery.io/), Orbit, and Fleet Desktop. [Docs](https://fleetdm.com/docs/using-fleet/fleetd).
## Osquery
Osquery is an open-source tool for gathering information about the state of any device that the osquery agent has been installed on. [Learn more](https://www.osquery.io/).
diff --git a/docs/REST API/rest-api.md b/docs/REST API/rest-api.md
index a40f5daa3950..8f8e12dfc6d3 100644
--- a/docs/REST API/rest-api.md
+++ b/docs/REST API/rest-api.md
@@ -1829,14 +1829,14 @@ the `software` table.
| page | integer | query | Page number of the results to fetch. |
| per_page | integer | query | Results per page. |
| order_key | string | query | What to order results by. Can be any column in the hosts table. |
-| after | string | query | The value to get results after. This needs `order_key` defined, as that's the column that would be used. **Note:** Use `page` instead of `after`. |
-| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include `asc` and `desc`. Default is `asc`. |
-| status | string | query | Indicates the status of the hosts to return. Can either be `new`, `online`, `offline`, `mia` or `missing`. |
-| query | string | query | Search query keywords. Searchable fields include `hostname`, `machine_serial`, `uuid`, `ipv4` and the hosts' email addresses (only searched if the query looks like an email address, i.e. contains an `@`, no space, etc.). |
-| additional_info_filters | string | query | A comma-delimited list of fields to include in each host's additional information object. See [Fleet Configuration Options](https://fleetdm.com/docs/using-fleet/fleetctl-cli#fleet-configuration-options) for an example configuration with hosts' additional information. Use `*` to get all stored fields. |
+| after | string | query | The value to get results after. This needs `order_key` defined, as that's the column that would be used. **Note:** Use `page` instead of `after` |
+| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include 'asc' and 'desc'. Default is 'asc'. |
+| status | string | query | Indicates the status of the hosts to return. Can either be 'new', 'online', 'offline', 'mia' or 'missing'. |
+| query | string | query | Search query keywords. Searchable fields include `hostname`, `machine_serial`, `uuid`, `ipv4` and the hosts' email addresses (only searched if the query looks like an email address, i.e. contains an '@', no space, etc.). |
+| additional_info_filters | string | query | A comma-delimited list of fields to include in each host's additional information object. See [Fleet Configuration Options](https://fleetdm.com/docs/using-fleet/fleetctl-cli#fleet-configuration-options) for an example configuration with hosts' additional information. Use '*' to get all stored fields. |
| team_id | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts in the specified team. |
| policy_id | integer | query | The ID of the policy to filter hosts by. |
-| policy_response | string | query | Valid options are `passing` or `failing`. `policy_id` must also be specified with `policy_response`. |
+| policy_response | string | query | Valid options are 'passing' or 'failing'. `policy_id` must also be specified with `policy_response`. |
| software_id | integer | query | The ID of the software to filter hosts by. |
| os_id | integer | query | The ID of the operating system to filter hosts by. |
| os_name | string | query | The name of the operating system to filter hosts by. `os_version` must also be specified with `os_name` |
@@ -1845,12 +1845,15 @@ the `software` table.
| mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). |
| mdm_name | string | query | The name of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider). |
| mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic', 'enrolled', 'pending', or 'unenrolled'. |
-| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team id filter, the results include only hosts that are not assigned to any team.** |
+| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
| munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). |
| low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. |
| disable_failing_policies| boolean | query | If "true", hosts will return failing policies as 0 regardless of whether there are any that failed for the host. This is meant to be used when increased performance is needed in exchange for the extra information. |
-| macos_settings_disk_encryption | string | query | Filters the hosts by the status of the macOS disk encryption MDM profile on the host. Can be one of `verified`, `verifying`, `action_required`, `enforcing`, `failed`, or `removing_enforcement`. |
-| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of `installed`, `pending`, or `failed`. |
+| macos_settings_disk_encryption | string | query | Filters the hosts by the status of the macOS disk encryption MDM profile on the host. Can be one of 'verified', 'verifying', 'action_required', 'enforcing', 'failed', or 'removing_enforcement'. |
+| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of 'installed', 'pending', or 'failed'. |
+| os_settings | string | query | Filters the hosts by the status of the operating system settings applied to the hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
+| os_settings_disk_encryption | string | query | Filters the hosts by the status of the disk encryption setting applied to the hosts. Can be one of 'verified', 'verifying', 'action_required', 'enforcing', 'failed', or 'removing_enforcement'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
+
If `additional_info_filters` is not specified, no `additional` information will be returned.
@@ -1858,9 +1861,9 @@ If `software_id` is specified, an additional top-level key `"software"` is retur
If `mdm_id` is specified, an additional top-level key `"mobile_device_management_solution"` is returned with the information corresponding to the `mdm_id`.
-If `mdm_id`, `mdm_name` or `mdm_enrollment_status` is specified, then Windows Servers are excluded from the results.
+If `mdm_id`, `mdm_name`, `mdm_enrollment_status`, `os_settings`, or `os_settings_disk_encryption` is specified, then Windows Servers are excluded from the results.
-If `munki_issue_id` is specified, an additional top-level key `"munki_issue"` is returned with the information corresponding to the `munki_issue_id`.
+If `munki_issue_id` is specified, an additional top-level key `munki_issue` is returned with the information corresponding to the `munki_issue_id`.
If `after` is being used with `created_at` or `updated_at`, the table must be specified in `order_key`. Those columns become `h.created_at` and `h.updated_at`.
@@ -1988,13 +1991,13 @@ Response payload with the `munki_issue_id` filter provided:
| Name | Type | In | Description |
| ----------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| order_key | string | query | What to order results by. Can be any column in the hosts table. |
-| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include `asc` and `desc`. Default is `asc`. |
+| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include 'asc' and 'desc'. Default is 'asc'. |
| after | string | query | The value to get results after. This needs `order_key` defined, as that's the column that would be used. |
-| status | string | query | Indicates the status of the hosts to return. Can either be `new`, `online`, `offline`, `mia` or `missing`. |
-| query | string | query | Search query keywords. Searchable fields include `hostname`, `machine_serial`, `uuid`, `ipv4` and the hosts' email addresses (only searched if the query looks like an email address, i.e. contains an `@`, no space, etc.). |
+| status | string | query | Indicates the status of the hosts to return. Can either be 'new', 'online', 'offline', 'mia' or 'missing'. |
+| query | string | query | Search query keywords. Searchable fields include `hostname`, `machine_serial`, `uuid`, `ipv4` and the hosts' email addresses (only searched if the query looks like an email address, i.e. contains an '@', no space, etc.). |
| team_id | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts in the specified team. |
| policy_id | integer | query | The ID of the policy to filter hosts by. |
-| policy_response | string | query | Valid options are `passing` or `failing`. `policy_id` must also be specified with `policy_response`. |
+| policy_response | string | query | Valid options are 'passing' or 'failing'. `policy_id` must also be specified with `policy_response`. |
| software_id | integer | query | The ID of the software to filter hosts by. |
| os_id | integer | query | The ID of the operating system to filter hosts by. |
| os_name | string | query | The name of the operating system to filter hosts by. `os_version` must also be specified with `os_name` |
@@ -2003,11 +2006,13 @@ Response payload with the `munki_issue_id` filter provided:
| mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). |
| mdm_name | string | query | The name of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider). |
| mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic', 'enrolled', 'pending', or 'unenrolled'. |
-| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team id filter, the results include only hosts that are not assigned to any team.** |
+| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
| munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). |
| low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. |
-| macos_settings_disk_encryption | string | query | Filters the hosts by the status of the macOS disk encryption MDM profile on the host. Can be one of `verified`, `verifying`, `action_required`, `enforcing`, `failed`, or `removing_enforcement`. |
-| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of `installed`, `pending`, or `failed`. **Note: If this filter is used in Fleet Premium without a team id filter, the results include only hosts that are not assigned to any team.** |
+| macos_settings_disk_encryption | string | query | Filters the hosts by the status of the macOS disk encryption MDM profile on the host. Can be one of 'verified', 'verifying', 'action_required', 'enforcing', 'failed', or 'removing_enforcement'. |
+| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of 'installed', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
+| os_settings | string | query | Filters the hosts by the status of the operating system settings applied to the hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
+| os_settings_disk_encryption | string | query | Filters the hosts by the status of the disk encryption setting applied to the hosts. Can be one of 'verified', 'verifying', 'action_required', 'enforcing', 'failed', or 'removing_enforcement'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
If `additional_info_filters` is not specified, no `additional` information will be returned.
@@ -2555,6 +2560,9 @@ Returns the information of the host specified using the `uuid`, `osquery_host_id
"bootstrap_package_status": "installed",
"detail": ""
},
+ "os_settings": {
+ "disk_encryption": null
+ },
"profiles": [
{
"profile_id": 999,
@@ -2743,6 +2751,9 @@ This is the API route used by the **My device** page in Fleet desktop to display
"detail": "",
"bootstrap_package_name": "test.pkg"
},
+ "os_settings": {
+ "disk_encryption": null
+ },
"profiles": [
{
"profile_id": 999,
@@ -3291,12 +3302,12 @@ requested by a web browser.
| format | string | query | **Required**, must be "csv" (only supported format for now). |
| columns | string | query | Comma-delimited list of columns to include in the report (returns all columns if none is specified). |
| order_key | string | query | What to order results by. Can be any column in the hosts table. |
-| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include `asc` and `desc`. Default is `asc`. |
-| status | string | query | Indicates the status of the hosts to return. Can either be `new`, `online`, `offline`, `mia` or `missing`. |
+| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include 'asc' and 'desc'. Default is 'asc'. |
+| status | string | query | Indicates the status of the hosts to return. Can either be 'new', 'online', 'offline', 'mia' or 'missing'. |
| query | string | query | Search query keywords. Searchable fields include `hostname`, `machine_serial`, `uuid`, `ipv4` and the hosts' email addresses (only searched if the query looks like an email address, i.e. contains an `@`, no space, etc.). |
| team_id | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts in the specified team. |
| policy_id | integer | query | The ID of the policy to filter hosts by. |
-| policy_response | string | query | Valid options are `passing` or `failing`. `policy_id` must also be specified with `policy_response`. **Note: If `policy_id` is specified _without_ including `policy_response`, this will also return hosts where the policy is not configured to run or failed to run.** |
+| policy_response | string | query | Valid options are 'passing' or 'failing'. `policy_id` must also be specified with `policy_response`. **Note: If `policy_id` is specified _without_ including `policy_response`, this will also return hosts where the policy is not configured to run or failed to run.** |
| software_id | integer | query | The ID of the software to filter hosts by. |
| os_id | integer | query | The ID of the operating system to filter hosts by. |
| os_name | string | query | The name of the operating system to filter hosts by. `os_version` must also be specified with `os_name` |
@@ -3304,11 +3315,11 @@ requested by a web browser.
| mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). |
| mdm_name | string | query | The name of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider). |
| mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic', 'enrolled', 'pending', or 'unenrolled'. |
-| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team id filter, the results include only hosts that are not assigned to any team.** |
+| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
| munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). |
| low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. |
| label_id | integer | query | A valid label ID. Can only be used in combination with `order_key`, `order_direction`, `status`, `query` and `team_id`. |
-| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of `installed`, `pending`, or `failed`. **Note: If this filter is used in Fleet Premium without a team id filter, the results include only hosts that are not assigned to any team.** |
+| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of 'installed', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
| disable_failing_policies | boolean | query | If `true`, hosts will return failing policies as 0 (returned as the `issues` column) regardless of whether there are any that failed for the host. This is meant to be used when increased performance is needed in exchange for the extra information. |
If `mdm_id`, `mdm_name` or `mdm_enrollment_status` is specified, then Windows Servers are excluded from the results.
@@ -3330,7 +3341,7 @@ created_at,updated_at,id,detail_updated_at,label_updated_at,policy_updated_at,la
### Get host's disk encryption key
-Requires the [macadmins osquery extension](https://github.com/macadmins/osquery-extension) which comes bundled
+For macOS, requires the [macadmins osquery extension](https://github.com/macadmins/osquery-extension) which comes bundled
in [Fleet's osquery installers](https://fleetdm.com/docs/using-fleet/adding-hosts#osquery-installer).
Requires Fleet's MDM properly [enabled and configured](https://fleetdm.com/docs/using-fleet/mdm-macos-setup).
@@ -3724,21 +3735,23 @@ Returns a list of the hosts that belong to the specified label.
| page | integer | query | Page number of the results to fetch. |
| per_page | integer | query | Results per page. |
| order_key | string | query | What to order results by. Can be any column in the hosts table. |
-| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include `asc` and `desc`. Default is `asc`. |
+| order_direction | string | query | **Requires `order_key`**. The direction of the order given the order key. Options include 'asc' and 'desc'. Default is 'asc'. |
| after | string | query | The value to get results after. This needs `order_key` defined, as that's the column that would be used. |
-| status | string | query | Indicates the status of the hosts to return. Can either be `new`, `online`, `offline`, `mia` or `missing`. |
+| status | string | query | Indicates the status of the hosts to return. Can either be 'new', 'online', 'offline', 'mia' or 'missing'. |
| query | string | query | Search query keywords. Searchable fields include `hostname`, `machine_serial`, `uuid`, and `ipv4`. |
| team_id | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts in the specified team. |
| disable_failing_policies | boolean | query | If "true", hosts will return failing policies as 0 regardless of whether there are any that failed for the host. This is meant to be used when increased performance is needed in exchange for the extra information. |
| mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). |
| mdm_name | string | query | The name of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider). |
| mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic', 'enrolled', 'pending', or 'unenrolled'. |
-| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team id filter, the results include only hosts that are not assigned to any team.** |
+| macos_settings | string | query | Filters the hosts by the status of the _mobile device management_ (MDM) profiles applied to hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
| low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. |
-| macos_settings_disk_encryption | string | query | Filters the hosts by the status of the macOS disk encryption MDM profile on the host. Can be one of `verified`, `verifying`, `action_required`, `enforcing`, `failed`, or `removing_enforcement`. |
-| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of `installed`, `pending`, or `failed`. **Note: If this filter is used in Fleet Premium without a team id filter, the results include only hosts that are not assigned to any team.** |
+| macos_settings_disk_encryption | string | query | Filters the hosts by the status of the macOS disk encryption MDM profile on the host. Can be one of 'verified', 'verifying', 'action_required', 'enforcing', 'failed', or 'removing_enforcement'. |
+| bootstrap_package | string | query | _Available in Fleet Premium_ Filters the hosts by the status of the MDM bootstrap package on the host. Can be one of 'installed', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
+| os_settings | string | query | Filters the hosts by the status of the operating system settings applied to the hosts. Can be one of 'verified', 'verifying', 'pending', or 'failed'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
+| os_settings_disk_encryption | string | query | Filters the hosts by the status of the disk encryption setting applied to the hosts. Can be one of 'verified', 'verifying', 'action_required', 'enforcing', 'failed', or 'removing_enforcement'. **Note: If this filter is used in Fleet Premium without a team ID filter, the results include only hosts that are not assigned to any team.** |
-If `mdm_id`, `mdm_name` or `mdm_enrollment_status` is specified, then Windows Servers are excluded from the results.
+If `mdm_id`, `mdm_name`, `mdm_enrollment_status`, `os_settings`, or `os_settings_disk_encryption` is specified, then Windows Servers are excluded from the results.
#### Example
@@ -3887,8 +3900,8 @@ Add a configuration profile to enforce custom settings on macOS hosts.
| Name | Type | In | Description |
| ------------------------- | -------- | ---- | ------------------------------------------------------------------------- |
-| profile | file | form | **Required**. The mobileconfig file containing the profile. |
-| team_id | string | form | _Available in Fleet Premium_ The team id for the profile. If specified, the profile is applied to only hosts that are assigned to the specified team. If not specified, the profile is applied to only to hosts that are not assigned to any team. |
+| profile | file | form | **Required**. The .mobileconfig file containing the profile. |
+| team_id | string | form | _Available in Fleet Premium_ The team ID for the profile. If specified, the profile is applied to only hosts that are assigned to the specified team. If not specified, the profile is applied to only to hosts that are not assigned to any team. |
#### Example
@@ -3967,7 +3980,7 @@ results (i.e., only profiles that are associated with "No team" are listed).
| Name | Type | In | Description |
| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
-| team_id | string | query | _Available in Fleet Premium_ The team id to filter profiles. |
+| team_id | string | query | _Available in Fleet Premium_ The team ID to filter profiles. |
#### Example
@@ -4090,23 +4103,23 @@ _Available in Fleet Premium_
_Available in Fleet Premium_
-Get aggregate status counts of disk encryption enforced on hosts.
+Get aggregate status counts of disk encryption enforced on macOS and Windows hosts.
-The summary can optionally be filtered by team id.
+The summary can optionally be filtered by team ID.
-`GET /api/v1/fleet/mdm/apple/filevault/summary`
+`GET /api/v1/fleet/mdm/disk_encryption/summary`
#### Parameters
| Name | Type | In | Description |
| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
-| team_id | string | query | _Available in Fleet Premium_ The team id to filter the summary. |
+| team_id | string | query | _Available in Fleet Premium_ The team ID to filter the summary. |
#### Example
-Get aggregate status counts of Apple disk encryption profiles applying to macOS hosts enrolled to Fleet's MDM that are not assigned to any team.
+Get aggregate disk encryption status counts of macOS and Windows hosts enrolled to Fleet's MDM that are not assigned to any team.
-`GET /api/v1/fleet/mdm/apple/filevault/summary`
+`GET /api/v1/fleet/mdm/disk_encryption/summary`
##### Default response
@@ -4114,12 +4127,12 @@ Get aggregate status counts of Apple disk encryption profiles applying to macOS
```json
{
- "verified": 123,
- "verifying": 123,
- "action_required": 123,
- "enforcing": 123,
- "failed": 123,
- "removing_enforcement": 123
+ "verified": {"macos": 123, "windows": 123},
+ "verifying": {"macos": 123, "windows": 0},
+ "action_required": {"macos": 123, "windows": 0},
+ "enforcing": {"macos": 123, "windows": 123},
+ "failed": {"macos": 123, "windows": 123},
+ "removing_enforcement": {"macos": 123, "windows": 0},
}
```
@@ -4128,7 +4141,7 @@ Get aggregate status counts of Apple disk encryption profiles applying to macOS
Get aggregate status counts of all macOS settings (configuraiton profiles and disk encryption) enforced on hosts.
For Fleet Premium uses, the statistics can
-optionally be filtered by team id. If no team id is specified, team profiles are excluded from the
+optionally be filtered by team ID. If no team ID is specified, team profiles are excluded from the
results (i.e., only profiles that are associated with "No team" are listed).
`GET /api/v1/fleet/mdm/apple/profiles/summary`
@@ -4137,7 +4150,7 @@ results (i.e., only profiles that are associated with "No team" are listed).
| Name | Type | In | Description |
| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
-| team_id | string | query | _Available in Fleet Premium_ The team id to filter profiles. |
+| team_id | string | query | _Available in Fleet Premium_ The team ID to filter profiles. |
#### Example
@@ -4274,7 +4287,7 @@ Sets the custom MDM setup enrollment profile for a team or no team.
| Name | Type | In | Description |
| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
-| team_id | integer | json | The team id this custom enrollment profile applies to, or no team if omitted. |
+| team_id | integer | json | The team ID this custom enrollment profile applies to, or no team if omitted. |
| name | string | json | The filename of the uploaded custom enrollment profile. |
| enrollment_profile | object | json | The custom enrollment profile's json, as documented in https://developer.apple.com/documentation/devicemanagement/profile. |
@@ -4310,7 +4323,7 @@ Gets the custom MDM setup enrollment profile for a team or no team.
| Name | Type | In | Description |
| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
-| team_id | integer | query | The team id for which to return the custom enrollment profile, or no team if omitted. |
+| team_id | integer | query | The team ID for which to return the custom enrollment profile, or no team if omitted. |
#### Example
@@ -4344,7 +4357,7 @@ Deletes the custom MDM setup enrollment profile assigned to a team or no team.
| Name | Type | In | Description |
| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
-| team_id | integer | query | The team id for which to delete the custom enrollment profile, or no team if omitted. |
+| team_id | integer | query | The team ID for which to delete the custom enrollment profile, or no team if omitted. |
#### Example
@@ -4439,7 +4452,7 @@ Upload a bootstrap package that will be automatically installed during DEP setup
| Name | Type | In | Description |
| ------- | ------ | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| package | file | form | **Required**. The bootstrap package installer. It must be a signed `pkg` file. |
-| team_id | string | form | The team id for the package. If specified, the package will be installed to hosts that are assigned to the specified team. If not specified, the package will be installed to hosts that are not assigned to any team. |
+| team_id | string | form | The team ID for the package. If specified, the package will be installed to hosts that are assigned to the specified team. If not specified, the package will be installed to hosts that are not assigned to any team. |
#### Example
@@ -4485,7 +4498,7 @@ Get information about a bootstrap package that was uploaded to Fleet.
| Name | Type | In | Description |
| ------- | ------ | --- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| team_id | string | url | **Required** The team id for the package. Zero (0) can be specified to get information about the bootstrap package for hosts that don't belong to a team. |
+| team_id | string | url | **Required** The team ID for the package. Zero (0) can be specified to get information about the bootstrap package for hosts that don't belong to a team. |
| for_update | boolean | query | If set to `true`, the authorization will be for a `write` action instead of a `read`. Useful for the write-only `gitops` role when requesting the bootstrap metadata to check if the package needs to be replaced. |
#### Example
@@ -4523,7 +4536,7 @@ Delete a team's bootstrap package.
| Name | Type | In | Description |
| ------- | ------ | --- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| team_id | string | url | **Required** The team id for the package. Zero (0) can be specified to get information about the bootstrap package for hosts that don't belong to a team. |
+| team_id | string | url | **Required** The team ID for the package. Zero (0) can be specified to get information about the bootstrap package for hosts that don't belong to a team. |
#### Example
@@ -4570,7 +4583,7 @@ _Available in Fleet Premium_
Get aggregate status counts of bootstrap packages delivered to DEP enrolled hosts.
-The summary can optionally be filtered by team id.
+The summary can optionally be filtered by team ID.
`GET /api/v1/fleet/mdm/apple/bootstrap/summary`
@@ -4578,7 +4591,7 @@ The summary can optionally be filtered by team id.
| Name | Type | In | Description |
| ------------------------- | ------ | ----- | ------------------------------------------------------------------------- |
-| team_id | string | query | The team id to filter the summary. |
+| team_id | string | query | The team ID to filter the summary. |
#### Example
@@ -5157,7 +5170,7 @@ Team policies work the same as policies, but at the team level.
| Name | Type | In | Description |
| ------------------ | ------- | ---- | ------------------------------------------------------------------------------------------------------------- |
-| id | integer | url | Required. Defines what team id to operate on |
+| id | integer | url | Required. Defines what team ID to operate on |
| page | integer | query | Page number of the results to fetch. |
| per_page | integer | query | Results per page. |
#### Example
@@ -5261,7 +5274,7 @@ Team policies work the same as policies, but at the team level.
| Name | Type | In | Description |
| ------------------ | ------- | ---- | ------------------------------------------------------------------------------------------------------------- |
-| team_id | integer | url | Defines what team id to operate on |
+| team_id | integer | url | Defines what team ID to operate on |
| id | integer | path | **Required.** The policy's ID. |
#### Example
@@ -5304,7 +5317,7 @@ The semantics for creating a team policy are the same as for global policies, se
| Name | Type | In | Description |
| ---------- | ------- | ---- | ------------------------------------ |
-| team_id | integer | url | Defines what team id to operate on. |
+| team_id | integer | url | Defines what team ID to operate on. |
| name | string | body | The query's name. |
| query | string | body | The query in SQL. |
| description | string | body | The query's description. |
@@ -5366,7 +5379,7 @@ Either `query` or `query_id` must be provided.
| Name | Type | In | Description |
| -------- | ------- | ---- | ------------------------------------------------- |
-| team_id | integer | url | Defines what team id to operate on |
+| team_id | integer | url | Defines what team ID to operate on |
| ids | list | body | **Required.** The IDs of the policies to delete. |
#### Example
@@ -6600,7 +6613,8 @@ Deletes the session specified by ID. When the user associated with the session n
"epss_probability": 0.01537,
"cisa_known_exploit": false,
"cve_published": "2022-01-01 12:32:00",
- "cve_description": "In the GNU C Library (aka glibc or libc6) before 2.28, parse_reg_exp in posix/regcomp.c misparses alternatives, which allows attackers to cause a denial of service (assertion failure and application exit) or trigger an incorrect result by attempting a regular-expression match."
+ "cve_description": "In the GNU C Library (aka glibc or libc6) before 2.28, parse_reg_exp in posix/regcomp.c misparses alternatives, which allows attackers to cause a denial of service (assertion failure and application exit) or trigger an incorrect result by attempting a regular-expression match.",
+ "resolved_in_version": "2.28"
}
],
"hosts_count": 1
diff --git a/docs/Using Fleet/CIS-Benchmarks.md b/docs/Using Fleet/CIS-Benchmarks.md
index 5d92bc4607ad..632caf0ae665 100644
--- a/docs/Using Fleet/CIS-Benchmarks.md
+++ b/docs/Using Fleet/CIS-Benchmarks.md
@@ -170,127 +170,11 @@ The following CIS benchmark checks cannot be automated and must be addressed man
Fleet's policies have been written against v1.12.0 of the benchmark. You can refer to the [CIS website](https://www.cisecurity.org/cis-benchmarks) for full details about this version.
-### Checks that require a Group Policy Template
+### Checks that require a Group Policy template
-38 items require Group Policy Template in place in order to audit them.
+Several items require Group Policy templates in place in order to audit them.
These items are tagged with the label `CIS_group_policy_template_required` in the YAML file, and details about the required Group Policy templates can be found in each item's `resolution`.
-```
-18.3.1 CIS - Ensure 'Apply UAC restrictions to local accounts on network logons' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MS Security Guide\Apply UAC restrictions to local accounts on network logons'
-
-18.3.2 CIS - Ensure 'Configure SMB v1 client driver' is set to 'Enabled: Disable driver (recommended)'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MS Security Guide\Configure SMB v1 client driver'
-
-18.3.3 CIS - Ensure 'Configure SMB v1 server' is set to 'Disabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MS Security Guide\Configure SMB v1 server'
-
-18.3.4 CIS - Ensure 'Enable Structured Exception Handling Overwrite Protection (SEHOP)' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MS Security Guide\Enable Structured Exception Handling Overwrite Protection (SEHOP)'
-
-18.3.5 CIS - Ensure 'Limits print driver installation to Administrators' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MS Security Guide\Limits print driver installation to Administrators'
-
-18.3.6 CIS - Ensure 'NetBT NodeType configuration' is set to 'Enabled: P-node (recommended)'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MS Security Guide\NetBT NodeType configuration'
-
-18.3.7 CIS - Ensure 'WDigest Authentication' is set to 'Disabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MS Security Guide\WDigest Authentication (disabling may require KB2871997)'
-
-18.4.1 CIS - Ensure 'MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)' is set to 'Disabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (AutoAdminLogon) Enable Automatic Logon (not recommended)'
-
-18.4.2 CIS - Ensure 'MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (DisableIPSourceRouting IPv6) IP source routing protection level (protects against packet spoofing)'
-
-18.4.3 CIS - Ensure 'MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)' is set to 'Enabled: Highest protection, source routing is completely disabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (DisableIPSourceRouting) IP source routing protection level (protects against packet spoofing)'
-
-18.4.4 CIS - Ensure 'MSS: (DisableSavePassword) Prevent the dial-up password from being saved' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS:(DisableSavePassword) Prevent the dial-up password from being saved'
-
-18.4.5 CIS - Ensure 'MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes' is set to 'Disabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (EnableICMPRedirect) Allow ICMP redirects to override OSPF generated routes'
-
-18.4.6 CIS - Ensure 'MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds' is set to 'Enabled: 300,000 or 5 minutes'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (KeepAliveTime) How often keep-alive packets are sent in milliseconds'
-
-18.4.7 CIS - Ensure 'MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (NoNameReleaseOnDemand) Allow the computer to ignore NetBIOS name release requests except from WINS servers'
-
-18.4.8 CIS - Ensure 'MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)' is set to 'Disabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (PerformRouterDiscovery) Allow IRDP to detect and configure Default Gateway addresses (could lead to DoS)'
-
-18.4.9 CIS - Ensure 'MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)'
-
-18.4.10 CIS - Ensure 'MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)' is set to 'Enabled: 5 or fewer seconds'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (ScreenSaverGracePeriod) The time in seconds before the screen saver grace period expires (0 recommended)'
-
-18.4.11 CIS - Ensure 'MSS: (TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS:(TcpMaxDataRetransmissions IPv6) How many times unacknowledged data is retransmitted'
-
-18.4.12 CIS - Ensure 'MSS: (TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted' is set to 'Enabled: 3'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS:(TcpMaxDataRetransmissions) How many times unacknowledged data is retransmitted'
-
-18.4.13 CIS - Ensure 'MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning' is set to 'Enabled: 90% or less'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\MSS (Legacy)\MSS: (WarningLevel) Percentage threshold for the security event log at which the system will generate a warning'
-
-18.8.21.2 CIS - Ensure 'Configure registry policy processing: Do not apply during periodic background processing' is set to 'Enabled: FALSE'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Group Policy\Configure registry policy processing'
-
-18.8.22.1.1 CIS - Ensure 'Turn off access to the Store' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off access to the Store'
-
-18.8.22.1.2 CIS - Ensure 'Turn off downloading of print drivers over HTTP' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off downloading of print drivers over HTTP'
-
-18.8.22.1.3 CIS - Ensure 'Turn off handwriting personalization data sharing' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off handwriting personalization data sharing'
-
-18.8.22.1.4 CIS - Ensure 'Turn off handwriting recognition error reporting' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off handwriting recognition error reporting'
-
-18.8.22.1.5 CIS - Ensure 'Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off Internet Connection Wizard if URL connection is referring to Microsoft.com'
-
-18.8.22.1.6 CIS - Ensure 'Turn off Internet download for Web publishing and online ordering wizards' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off Internet download for Web publishing and online ordering wizards'
-
-18.8.22.1.7 CIS - Ensure 'Turn off printing over HTTP' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off printing over HTTP'
-
-18.8.22.1.8 CIS - Ensure 'Turn off Registration if URL connection is referring to Microsoft.com' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off Registration if URL connection is referring to Microsoft.com'
-
-18.8.22.1.9 CIS - Ensure 'Turn off Search Companion content file updates' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off Search Companion content file updates'
-
-18.8.22.1.10 CIS - Ensure 'Turn off the "Order Prints" picture task' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off the "Order Prints" picture task'
-
-18.8.22.1.11 CIS - Ensure 'Turn off the "Publish to Web" task for files and folders' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off the "Publish to Web" task for files and folders'
-
-18.8.22.1.12 CIS - Ensure 'Turn off the Windows Messenger Customer Experience Improvement Program' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off the Windows Messenger Customer Experience Improvement Program'
-
-18.8.22.1.13 CIS - Ensure 'Turn off Windows Customer Experience Improvement Program' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off Windows Customer Experience Improvement Program'
-
-18.8.22.1.14 CIS - Ensure 'Turn off Windows Error Reporting' is set to 'Enabled'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Internet Communication Management\Internet Communication settings\Turn off Windows Error Reporting'
-
-18.8.25.1 CIS - Ensure 'Support device authentication using certificate' is set to 'Enabled: Automatic'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Kerberos\Support device authentication using certificate'
-
-18.8.26.1 CIS - Ensure 'Enumeration policy for external devices incompatible with Kernel DMA Protection' is set to 'Enabled: Block All'
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Kernel DMA Protection\Enumeration policy for external devices incompatible with Kernel DMA Protection'
-
-18.8.27.1 CIS - Ensure 'Disallow copying of user input methods to the system account for sign-in' is set to 'Enabled' (Automated)
-Requires this GPO in place: 'Computer Configuration\Policies\Administrative Templates\System\Locale Services\Disallow copying of user input methods to the system account for sign-in'
-```
-
## Performance testing
In August 2023, we completed scale testing on 10k Windows hosts and 70k macOS hosts. Ultimately, we validated both server and host performance at that scale.
diff --git a/docs/Using Fleet/Fleet-UI.md b/docs/Using Fleet/Fleet-UI.md
index 0d4f2c1a39ae..da80b0342d60 100644
--- a/docs/Using Fleet/Fleet-UI.md
+++ b/docs/Using Fleet/Fleet-UI.md
@@ -52,7 +52,7 @@ Fleet allows you to schedule queries to run at a set frequency. Scheduled querie
The default log destination, **filesystem**, is good to start. With this set, data is sent to the `/var/log/osquery/osqueryd.snapshots.log` file on each host’s filesystem. To see which log destinations are available in Fleet, head to the [log destinations page](https://fleetdm.com/docs/using-fleet/log-destinations).
-By default, queries that run on a schedule will only target platforms compatible with that query. This behavior can be overridden by setting the platforms in the "advanced options" when saving a query.
+By default, queries that run on a schedule will only target platforms compatible with that query. This behavior can be overridden by setting the platforms in "advanced options" when saving a query.
**How to schedule queries:**
@@ -94,4 +94,4 @@ See "[Agent configuration](https://fleetdm.com/docs/configuration/agent-configur
-
\ No newline at end of file
+
diff --git a/docs/Using Fleet/manage-access.md b/docs/Using Fleet/manage-access.md
index 48c1a2152600..90774c86e1a7 100644
--- a/docs/Using Fleet/manage-access.md
+++ b/docs/Using Fleet/manage-access.md
@@ -75,7 +75,7 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines.
| View Apple mobile device management (MDM) certificate information | | | | ✅ | |
| View Apple business manager (BM) information | | | | ✅ | |
| Generate Apple mobile device management (MDM) certificate signing request (CSR) | | | | ✅ | |
-| View disk encryption key for macOS hosts | ✅ | ✅ | ✅ | ✅ | |
+| View disk encryption key for macOS and Windows hosts | ✅ | ✅ | ✅ | ✅ | |
| Create edit and delete configuration profiles for macOS hosts | | | ✅ | ✅ | ✅ |
| Execute MDM commands on macOS and Windows hosts*** | | | ✅ | ✅ | |
| View results of MDM commands executed on macOS and Windows hosts*** | ✅ | ✅ | ✅ | ✅ | |
diff --git a/ee/server/service/mdm.go b/ee/server/service/mdm.go
index afd304a6c8f9..37cf53721821 100644
--- a/ee/server/service/mdm.go
+++ b/ee/server/service/mdm.go
@@ -15,6 +15,7 @@ import (
"strings"
"github.com/fleetdm/fleet/v4/pkg/file"
+ "github.com/fleetdm/fleet/v4/pkg/optjson"
"github.com/fleetdm/fleet/v4/server/authz"
"github.com/fleetdm/fleet/v4/server/contexts/ctxdb"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
@@ -890,12 +891,7 @@ func (svc *Service) getOrCreatePreassignTeam(ctx context.Context, groups []strin
}
payload.MDM = &fleet.TeamPayloadMDM{
- MacOSSettings: &fleet.MacOSSettings{
- // teams created by the match endpoint have disk encryption
- // enabled by default.
- // TODO: maybe make this configurable?
- EnableDiskEncryption: true,
- },
+ EnableDiskEncryption: optjson.SetBool(true),
MacOSSetup: &fleet.MacOSSetup{
MacOSSetupAssistant: ac.MDM.MacOSSetup.MacOSSetupAssistant,
// NOTE: BootstrapPackage is currently ignored by svc.ModifyTeam and gets set
@@ -968,3 +964,51 @@ func teamNameFromPreassignGroups(groups []string) string {
return strings.Join(groups, " - ")
}
+
+func (svc *Service) GetMDMDiskEncryptionSummary(ctx context.Context, teamID *uint) (*fleet.MDMDiskEncryptionSummary, error) {
+ // TODO: Consider adding a new generic OSSetting type or Windows-specific type for authz checks
+ // like this.
+ if err := svc.authz.Authorize(ctx, fleet.MDMAppleConfigProfile{TeamID: teamID}, fleet.ActionRead); err != nil {
+ return nil, ctxerr.Wrap(ctx, err)
+ }
+ var macOS fleet.MDMAppleFileVaultSummary
+ if m, err := svc.ds.GetMDMAppleFileVaultSummary(ctx, teamID); err != nil {
+ return nil, ctxerr.Wrap(ctx, err, "getting filevault summary")
+ } else if m != nil {
+ macOS = *m
+ }
+
+ var windows fleet.MDMWindowsBitLockerSummary
+ if w, err := svc.ds.GetMDMWindowsBitLockerSummary(ctx, teamID); err != nil {
+ return nil, ctxerr.Wrap(ctx, err, "getting bitlocker summary")
+ } else if w != nil {
+ windows = *w
+ }
+
+ return &fleet.MDMDiskEncryptionSummary{
+ Verified: fleet.MDMPlatformsCounts{
+ MacOS: macOS.Verified,
+ Windows: windows.Verified,
+ },
+ Verifying: fleet.MDMPlatformsCounts{
+ MacOS: macOS.Verifying,
+ Windows: windows.Verifying,
+ },
+ ActionRequired: fleet.MDMPlatformsCounts{
+ MacOS: macOS.ActionRequired,
+ Windows: windows.ActionRequired,
+ },
+ Enforcing: fleet.MDMPlatformsCounts{
+ MacOS: macOS.Enforcing,
+ Windows: windows.Enforcing,
+ },
+ Failed: fleet.MDMPlatformsCounts{
+ MacOS: macOS.Failed,
+ Windows: windows.Failed,
+ },
+ RemovingEnforcement: fleet.MDMPlatformsCounts{
+ MacOS: macOS.RemovingEnforcement,
+ Windows: windows.RemovingEnforcement,
+ },
+ }, nil
+}
diff --git a/ee/server/service/teams.go b/ee/server/service/teams.go
index 33a777323f1b..529408de47b0 100644
--- a/ee/server/service/teams.go
+++ b/ee/server/service/teams.go
@@ -150,13 +150,13 @@ func (svc *Service) ModifyTeam(ctx context.Context, teamID uint, payload fleet.T
}
}
- if payload.MDM.MacOSSettings != nil {
- if !appCfg.MDM.EnabledAndConfigured && payload.MDM.MacOSSettings.EnableDiskEncryption {
+ if payload.MDM.EnableDiskEncryption.Valid {
+ macOSDiskEncryptionUpdated = team.Config.MDM.EnableDiskEncryption != payload.MDM.EnableDiskEncryption.Value
+ if macOSDiskEncryptionUpdated && !appCfg.MDM.EnabledAndConfigured {
return nil, fleet.NewInvalidArgumentError("macos_settings.enable_disk_encryption",
`Couldn't update macos_settings because MDM features aren't turned on in Fleet. Use fleetctl generate mdm-apple and then fleet serve with mdm configuration to turn on MDM features.`)
}
- macOSDiskEncryptionUpdated = team.Config.MDM.MacOSSettings.EnableDiskEncryption != payload.MDM.MacOSSettings.EnableDiskEncryption
- team.Config.MDM.MacOSSettings.EnableDiskEncryption = payload.MDM.MacOSSettings.EnableDiskEncryption
+ team.Config.MDM.EnableDiskEncryption = payload.MDM.EnableDiskEncryption.Value
}
if payload.MDM.MacOSSetup != nil {
@@ -225,7 +225,7 @@ func (svc *Service) ModifyTeam(ctx context.Context, teamID uint, payload fleet.T
}
if macOSDiskEncryptionUpdated {
var act fleet.ActivityDetails
- if team.Config.MDM.MacOSSettings.EnableDiskEncryption {
+ if team.Config.MDM.EnableDiskEncryption {
act = fleet.ActivityTypeEnabledMacosDiskEncryption{TeamID: &team.ID, TeamName: &team.Name}
if err := svc.MDMAppleEnableFileVaultAndEscrow(ctx, &team.ID); err != nil {
return nil, ctxerr.Wrap(ctx, err, "enable team filevault and escrow")
@@ -802,6 +802,17 @@ func (svc *Service) createTeamFromSpec(
`Couldn't update macos_setup because MDM features aren't turned on in Fleet. Use fleetctl generate mdm-apple and then fleet serve with mdm configuration to turn on MDM features.`))
}
}
+ enableDiskEncryption := spec.MDM.EnableDiskEncryption.Value
+ if !spec.MDM.EnableDiskEncryption.Valid {
+ if de := macOSSettings.DeprecatedEnableDiskEncryption; de != nil {
+ enableDiskEncryption = *de
+ }
+ }
+
+ if enableDiskEncryption && !defaults.MDM.AtLeastOnePlatformEnabledAndConfigured() {
+ return nil, ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("mdm",
+ `Couldn't edit enable_disk_encryption. Neither macOS MDM nor Windows is turned on. Visit https://fleetdm.com/docs/using-fleet to learn how to turn on MDM.`))
+ }
if dryRun {
return &fleet.Team{Name: spec.Name}, nil
@@ -813,9 +824,10 @@ func (svc *Service) createTeamFromSpec(
AgentOptions: agentOptions,
Features: features,
MDM: fleet.TeamMDM{
- MacOSUpdates: spec.MDM.MacOSUpdates,
- MacOSSettings: macOSSettings,
- MacOSSetup: macOSSetup,
+ EnableDiskEncryption: enableDiskEncryption,
+ MacOSUpdates: spec.MDM.MacOSUpdates,
+ MacOSSettings: macOSSettings,
+ MacOSSetup: macOSSetup,
},
},
Secrets: secrets,
@@ -824,7 +836,7 @@ func (svc *Service) createTeamFromSpec(
return nil, err
}
- if macOSSettings.EnableDiskEncryption {
+ if enableDiskEncryption && defaults.MDM.EnabledAndConfigured {
if err := svc.MDMAppleEnableFileVaultAndEscrow(ctx, &tm.ID); err != nil {
return nil, ctxerr.Wrap(ctx, err, "enable team filevault and escrow")
}
@@ -871,11 +883,23 @@ func (svc *Service) editTeamFromSpec(
team.Config.MDM.MacOSUpdates = spec.MDM.MacOSUpdates
}
- oldMacOSDiskEncryption := team.Config.MDM.MacOSSettings.EnableDiskEncryption
+ oldMacOSDiskEncryption := team.Config.MDM.EnableDiskEncryption
if err := svc.applyTeamMacOSSettings(ctx, spec, &team.Config.MDM.MacOSSettings); err != nil {
return err
}
- newMacOSDiskEncryption := team.Config.MDM.MacOSSettings.EnableDiskEncryption
+
+ // 1. if the spec has the new setting, use that
+ // 2. else if the spec has the deprecated setting, use that
+ // 3. otherwise, leave the setting untouched
+ if spec.MDM.EnableDiskEncryption.Valid {
+ team.Config.MDM.EnableDiskEncryption = spec.MDM.EnableDiskEncryption.Value
+ } else if de := team.Config.MDM.MacOSSettings.DeprecatedEnableDiskEncryption; de != nil {
+ team.Config.MDM.EnableDiskEncryption = *de
+ }
+ if team.Config.MDM.EnableDiskEncryption && !appCfg.MDM.AtLeastOnePlatformEnabledAndConfigured() {
+ return ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("mdm",
+ `Couldn't edit enable_disk_encryption. Neither macOS MDM nor Windows is turned on. Visit https://fleetdm.com/docs/using-fleet to learn how to turn on MDM.`))
+ }
oldMacOSSetup := team.Config.MDM.MacOSSetup
if spec.MDM.MacOSSetup.MacOSSetupAssistant.Set || spec.MDM.MacOSSetup.BootstrapPackage.Set {
@@ -925,9 +949,9 @@ func (svc *Service) editTeamFromSpec(
return err
}
}
- if oldMacOSDiskEncryption != newMacOSDiskEncryption {
+ if appCfg.MDM.EnabledAndConfigured && oldMacOSDiskEncryption != team.Config.MDM.EnableDiskEncryption {
var act fleet.ActivityDetails
- if team.Config.MDM.MacOSSettings.EnableDiskEncryption {
+ if team.Config.MDM.EnableDiskEncryption {
act = fleet.ActivityTypeEnabledMacosDiskEncryption{TeamID: &team.ID, TeamName: &team.Name}
if err := svc.MDMAppleEnableFileVaultAndEscrow(ctx, &team.ID); err != nil {
return ctxerr.Wrap(ctx, err, "enable team filevault and escrow")
@@ -982,7 +1006,7 @@ func (svc *Service) applyTeamMacOSSettings(ctx context.Context, spec *fleet.Team
}
if (setFields["custom_settings"] && len(applyUpon.CustomSettings) > 0) ||
- (setFields["enable_disk_encryption"] && applyUpon.EnableDiskEncryption) {
+ (setFields["enable_disk_encryption"] && *applyUpon.DeprecatedEnableDiskEncryption) {
field := "custom_settings"
if !setFields["custom_settings"] {
field = "enable_disk_encryption"
@@ -1016,8 +1040,8 @@ func unmarshalWithGlobalDefaults(b *json.RawMessage) (fleet.Features, error) {
func (svc *Service) updateTeamMDMAppleSettings(ctx context.Context, tm *fleet.Team, payload fleet.MDMAppleSettingsPayload) error {
var didUpdate, didUpdateMacOSDiskEncryption bool
if payload.EnableDiskEncryption != nil {
- if tm.Config.MDM.MacOSSettings.EnableDiskEncryption != *payload.EnableDiskEncryption {
- tm.Config.MDM.MacOSSettings.EnableDiskEncryption = *payload.EnableDiskEncryption
+ if tm.Config.MDM.EnableDiskEncryption != *payload.EnableDiskEncryption {
+ tm.Config.MDM.EnableDiskEncryption = *payload.EnableDiskEncryption
didUpdate = true
didUpdateMacOSDiskEncryption = true
}
@@ -1029,7 +1053,7 @@ func (svc *Service) updateTeamMDMAppleSettings(ctx context.Context, tm *fleet.Te
}
if didUpdateMacOSDiskEncryption {
var act fleet.ActivityDetails
- if tm.Config.MDM.MacOSSettings.EnableDiskEncryption {
+ if tm.Config.MDM.EnableDiskEncryption {
act = fleet.ActivityTypeEnabledMacosDiskEncryption{TeamID: &tm.ID, TeamName: &tm.Name}
if err := svc.MDMAppleEnableFileVaultAndEscrow(ctx, &tm.ID); err != nil {
return ctxerr.Wrap(ctx, err, "enable team filevault and escrow")
diff --git a/frontend/__mocks__/configMock.ts b/frontend/__mocks__/configMock.ts
index c51d2895d506..f225356c8d9c 100644
--- a/frontend/__mocks__/configMock.ts
+++ b/frontend/__mocks__/configMock.ts
@@ -125,6 +125,7 @@ const DEFAULT_CONFIG_MOCK: IConfig = {
},
fleet_desktop: { transparency_url: "https://fleetdm.com/transparency" },
mdm: {
+ enable_disk_encryption: false,
windows_enabled_and_configured: true,
apple_bm_default_team: "Apples",
apple_bm_enabled_and_configured: true,
diff --git a/frontend/__mocks__/hostMock.ts b/frontend/__mocks__/hostMock.ts
index c2e0993649e2..6834d0c7037a 100644
--- a/frontend/__mocks__/hostMock.ts
+++ b/frontend/__mocks__/hostMock.ts
@@ -1,7 +1,7 @@
import { IHost } from "interfaces/host";
-import { IHostMacMdmProfile } from "interfaces/mdm";
+import { IHostMdmProfile } from "interfaces/mdm";
-const DEFAULT_HOST_PROFILE_MOCK: IHostMacMdmProfile = {
+const DEFAULT_HOST_PROFILE_MOCK: IHostMdmProfile = {
profile_id: 1,
name: "Test Profile",
operation_type: "install",
@@ -10,8 +10,8 @@ const DEFAULT_HOST_PROFILE_MOCK: IHostMacMdmProfile = {
};
export const createMockHostMacMdmProfile = (
- overrides?: Partial
-): IHostMacMdmProfile => {
+ overrides?: Partial
+): IHostMdmProfile => {
return { ...DEFAULT_HOST_PROFILE_MOCK, ...overrides };
};
@@ -53,6 +53,11 @@ const DEFAULT_HOST_MOCK: IHost = {
enrollment_status: "Off",
server_url: "https://www.example.com/1",
profiles: [],
+ os_settings: {
+ disk_encryption: {
+ status: null,
+ },
+ },
macos_settings: {
disk_encryption: null,
action_required: null,
diff --git a/frontend/__mocks__/mdmMock.ts b/frontend/__mocks__/mdmMock.ts
index c0584bf66aaf..5ffebcdbc30d 100644
--- a/frontend/__mocks__/mdmMock.ts
+++ b/frontend/__mocks__/mdmMock.ts
@@ -36,6 +36,11 @@ const DEFAULT_HOST_MDM_DATA: IHostMdmData = {
name: "MDM Solution",
id: 1,
profiles: [],
+ os_settings: {
+ disk_encryption: {
+ status: "verified",
+ },
+ },
macos_settings: {
disk_encryption: null,
action_required: null,
diff --git a/frontend/components/InfoBanner/InfoBanner.tsx b/frontend/components/InfoBanner/InfoBanner.tsx
index 1eb8d6d0214f..9873e9d55edf 100644
--- a/frontend/components/InfoBanner/InfoBanner.tsx
+++ b/frontend/components/InfoBanner/InfoBanner.tsx
@@ -3,6 +3,7 @@ import classNames from "classnames";
import Icon from "components/Icon";
import Button from "components/buttons/Button";
+import { IconNames } from "components/icons";
const baseClass = "info-banner";
@@ -11,28 +12,35 @@ export interface IInfoBannerProps {
className?: string;
/** default light purple */
color?: "yellow" | "grey";
+ /** default 4px */
+ borderRadius?: "large" | "xlarge";
pageLevel?: boolean;
/** cta and link are mutually exclusive */
cta?: JSX.Element;
/** closable and link are mutually exclusive */
closable?: boolean;
link?: string;
+ icon?: IconNames;
}
const InfoBanner = ({
children,
className,
color,
+ borderRadius,
pageLevel,
cta,
closable,
link,
+ icon,
}: IInfoBannerProps): JSX.Element => {
const wrapperClasses = classNames(
baseClass,
{
[`${baseClass}__${color}`]: !!color,
+ [`${baseClass}__border-radius-${borderRadius}`]: !!borderRadius,
[`${baseClass}__page-banner`]: !!pageLevel,
+ [`${baseClass}__icon`]: !!icon,
},
className
);
@@ -42,6 +50,7 @@ const InfoBanner = ({
const content = (
<>
{children}
+
{(cta || closable) && (
{cta}
diff --git a/frontend/components/InfoBanner/_styles.scss b/frontend/components/InfoBanner/_styles.scss
index 5902cba3dba1..b4c98e5816a9 100644
--- a/frontend/components/InfoBanner/_styles.scss
+++ b/frontend/components/InfoBanner/_styles.scss
@@ -26,6 +26,20 @@
width: auto;
}
+ &__border-radius-large {
+ border-radius: $border-radius-large;
+ }
+
+ &__border-radius-xlarge {
+ border-radius: $border-radius-xlarge;
+ }
+
+ &__info {
+ display: flex;
+ flex-direction: column;
+ gap: $pad-small;
+ }
+
&__cta {
display: flex;
align-items: center;
@@ -51,4 +65,8 @@
}
}
}
+
+ p {
+ margin: 0;
+ }
}
diff --git a/frontend/components/StatusIndicatorWithIcon/StatusIndicatorWithIcon.tsx b/frontend/components/StatusIndicatorWithIcon/StatusIndicatorWithIcon.tsx
index e510748a7a35..95ae8d5659e6 100644
--- a/frontend/components/StatusIndicatorWithIcon/StatusIndicatorWithIcon.tsx
+++ b/frontend/components/StatusIndicatorWithIcon/StatusIndicatorWithIcon.tsx
@@ -23,7 +23,10 @@ interface IStatusIndicatorWithIconProps {
tooltipText: string | JSX.Element;
position?: "top" | "bottom";
};
+ layout?: "horizontal" | "vertical";
className?: string;
+ /** Classname to add to the value text */
+ valueClassName?: string;
}
const statusIconNameMapping: Record = {
@@ -38,13 +41,18 @@ const StatusIndicatorWithIcon = ({
status,
value,
tooltip,
+ layout = "horizontal",
className,
+ valueClassName,
}: IStatusIndicatorWithIconProps) => {
const classNames = classnames(baseClass, className);
const id = `status-${uniqueId()}`;
+ const valueClasses = classnames(`${baseClass}__value`, valueClassName, {
+ [`${baseClass}__value-vertical`]: layout === "vertical",
+ });
const valueContent = (
-
+ {value}
diff --git a/frontend/components/StatusIndicatorWithIcon/_styles.scss b/frontend/components/StatusIndicatorWithIcon/_styles.scss
index 6dea8de69713..12d60c0f2d63 100644
--- a/frontend/components/StatusIndicatorWithIcon/_styles.scss
+++ b/frontend/components/StatusIndicatorWithIcon/_styles.scss
@@ -1,4 +1,5 @@
.status-indicator-with-icon {
+ // default layout is horizontal
&__value {
display: inline-flex;
align-items: center;
@@ -8,4 +9,10 @@
margin-right: $pad-xsmall;
}
}
+
+ // overrides for different layout
+ &__value-vertical {
+ flex-direction: column;
+ gap: $pad-xsmall;
+ }
}
diff --git a/frontend/interfaces/config.ts b/frontend/interfaces/config.ts
index c604629c0c79..2bfbe6fada8e 100644
--- a/frontend/interfaces/config.ts
+++ b/frontend/interfaces/config.ts
@@ -1,95 +1,11 @@
/* Config interface is a flattened version of the fleet/config API response */
-
import {
IWebhookHostStatus,
IWebhookFailingPolicies,
IWebhookSoftwareVulnerabilities,
} from "interfaces/webhook";
-import PropTypes from "prop-types";
import { IIntegrations } from "./integration";
-export default PropTypes.shape({
- org_name: PropTypes.string,
- org_logo_url: PropTypes.string,
- contact_url: PropTypes.string,
- server_url: PropTypes.string,
- live_query_disabled: PropTypes.bool,
- enable_analytics: PropTypes.bool,
- enable_smtp: PropTypes.bool,
- configured: PropTypes.bool,
- sender_address: PropTypes.string,
- server: PropTypes.string,
- port: PropTypes.number,
- authentication_type: PropTypes.string,
- user_name: PropTypes.string,
- password: PropTypes.string,
- enable_ssl_tls: PropTypes.bool,
- authentication_method: PropTypes.string,
- domain: PropTypes.string,
- verify_sll_certs: PropTypes.bool,
- enable_start_tls: PropTypes.bool,
- entity_id: PropTypes.string,
- idp_image_url: PropTypes.string,
- metadata: PropTypes.string,
- metadata_url: PropTypes.string,
- idp_name: PropTypes.string,
- enable_sso: PropTypes.bool,
- enable_sso_idp_login: PropTypes.bool,
- enable_jit_provisioning: PropTypes.bool,
- host_expiry_enabled: PropTypes.bool,
- host_expiry_window: PropTypes.number,
- agent_options: PropTypes.string,
- tier: PropTypes.string,
- organization: PropTypes.string,
- device_count: PropTypes.number,
- expiration: PropTypes.string,
- mdm: PropTypes.shape({
- enabled_and_configured: PropTypes.bool,
- apple_bm_terms_expired: PropTypes.bool,
- apple_bm_enabled_and_configured: PropTypes.bool,
- windows_enabled_and_configured: PropTypes.bool,
- macos_updates: PropTypes.shape({
- minimum_version: PropTypes.string,
- deadline: PropTypes.string,
- }),
- }),
- note: PropTypes.string,
- // vulnerability_settings: PropTypes.any, TODO
- enable_host_status_webhook: PropTypes.bool,
- destination_url: PropTypes.string,
- host_percentage: PropTypes.number,
- days_count: PropTypes.number,
- logging: PropTypes.shape({
- debug: PropTypes.bool,
- json: PropTypes.bool,
- result: PropTypes.shape({
- plugin: PropTypes.string,
- config: PropTypes.shape({
- status_log_file: PropTypes.string,
- result_log_file: PropTypes.string,
- enable_log_rotation: PropTypes.bool,
- enable_log_compression: PropTypes.bool,
- }),
- }),
- status: PropTypes.shape({
- plugin: PropTypes.string,
- config: PropTypes.shape({
- status_log_file: PropTypes.string,
- result_log_file: PropTypes.string,
- enable_log_rotation: PropTypes.bool,
- enable_log_compression: PropTypes.bool,
- }),
- }),
- }),
- email: PropTypes.shape({
- backend: PropTypes.string,
- config: PropTypes.shape({
- region: PropTypes.string,
- source_arn: PropTypes.string,
- }),
- }),
-});
-
export interface ILicense {
tier: string;
device_count: number;
@@ -113,6 +29,7 @@ export interface IMacOsMigrationSettings {
}
export interface IMdmConfig {
+ enable_disk_encryption: boolean;
enabled_and_configured: boolean;
apple_bm_default_team?: string;
apple_bm_terms_expired: boolean;
@@ -285,7 +202,10 @@ export interface IConfig {
};
};
mdm: IMdmConfig;
- mdm_enabled?: boolean; // TODO: remove when windows MDM is released. Only used for windows MDM dev currently.
+ /** This is the flag that determines if the windwos mdm feature flag is enabled.
+ TODO: WINDOWS FEATURE FLAG: remove when windows MDM is released. Only used for windows MDM dev currently.
+ */
+ mdm_enabled?: boolean;
}
export interface IWebhookSettings {
diff --git a/frontend/interfaces/host.ts b/frontend/interfaces/host.ts
index 1927351b7dd8..ebfde247f461 100644
--- a/frontend/interfaces/host.ts
+++ b/frontend/interfaces/host.ts
@@ -8,9 +8,10 @@ import hostQueryResult from "./campaign";
import queryStatsInterface, { IQueryStats } from "./query_stats";
import { ILicense, IDeviceGlobalConfig } from "./config";
import {
- IHostMacMdmProfile,
+ IHostMdmProfile,
MdmEnrollmentStatus,
BootstrapPackageStatus,
+ DiskEncryptionStatus,
} from "./mdm";
export default PropTypes.shape({
@@ -90,18 +91,16 @@ export interface IMunkiData {
version: string;
}
-type MacDiskEncryptionState =
- | "applied"
- | "action_required"
- | "enforcing"
- | "failed"
- | "removing_enforcement"
- | null;
-
type MacDiskEncryptionActionRequired = "log_out" | "rotate_key" | null;
+export interface IOSSettings {
+ disk_encryption: {
+ status: DiskEncryptionStatus | null;
+ };
+}
+
interface IMdmMacOsSettings {
- disk_encryption: MacDiskEncryptionState | null;
+ disk_encryption: DiskEncryptionStatus | null;
action_required: MacDiskEncryptionActionRequired | null;
}
@@ -117,7 +116,8 @@ export interface IHostMdmData {
name?: string;
server_url: string | null;
id?: number;
- profiles: IHostMacMdmProfile[] | null;
+ profiles: IHostMdmProfile[] | null;
+ os_settings?: IOSSettings;
macos_settings?: IMdmMacOsSettings;
macos_setup?: IMdmMacOsSetup;
}
@@ -210,7 +210,7 @@ export interface IHost {
osquery_version: string;
os_version: string;
build: string;
- platform_like: string;
+ platform_like: string; // TODO: replace with more specific union type
code_name: string;
uptime: number;
memory: number;
diff --git a/frontend/interfaces/mdm.ts b/frontend/interfaces/mdm.ts
index 25f0f0d7ec8b..1120e1ab625c 100644
--- a/frontend/interfaces/mdm.ts
+++ b/frontend/interfaces/mdm.ts
@@ -22,8 +22,6 @@ export const MDM_ENROLLMENT_STATUS = {
export type MdmEnrollmentStatus = keyof typeof MDM_ENROLLMENT_STATUS;
-export type ProfileSummaryResponse = Record;
-
export interface IMdmStatusCardData {
status: MdmEnrollmentStatus;
hosts: number;
@@ -74,16 +72,15 @@ export type MdmProfileStatus = "verified" | "verifying" | "pending" | "failed";
export type MacMdmProfileOperationType = "remove" | "install";
-export interface IHostMacMdmProfile {
+export interface IHostMdmProfile {
profile_id: number;
name: string;
- // identifier?: string; // TODO: add when API is updated to return this
- operation_type: MacMdmProfileOperationType;
+ operation_type: MacMdmProfileOperationType | null;
status: MdmProfileStatus;
detail: string;
}
-export type FileVaultProfileStatus =
+export type DiskEncryptionStatus =
| "verified"
| "verifying"
| "action_required"
@@ -91,9 +88,18 @@ export type FileVaultProfileStatus =
| "failed"
| "removing_enforcement";
-// // TODO: update when list profiles API returns identifier
-// export const FLEET_FILEVAULT_PROFILE_IDENTIFIER =
-// "com.fleetdm.fleet.mdm.filevault";
+/** Currently windows disk enxryption status will only be one of these four
+values. In the future we may add more. */
+export type IWindowsDiskEncryptionStatus = Extract<
+ DiskEncryptionStatus,
+ "verified" | "verifying" | "enforcing" | "failed"
+>;
+
+export const isWindowsDiskEncryptionStatus = (
+ status: DiskEncryptionStatus
+): status is IWindowsDiskEncryptionStatus => {
+ return !["action_required", "removing_enforcement"].includes(status);
+};
export const FLEET_FILEVAULT_PROFILE_DISPLAY_NAME = "Disk encryption";
diff --git a/frontend/interfaces/team.ts b/frontend/interfaces/team.ts
index 3c06c11c36c8..4487dba48d86 100644
--- a/frontend/interfaces/team.ts
+++ b/frontend/interfaces/team.ts
@@ -44,6 +44,7 @@ export interface ITeam extends ITeamSummary {
secrets?: IEnrollSecret[];
role?: UserRole; // role value is included when the team is in the context of a user
mdm?: {
+ enable_disk_encryption: boolean;
macos_updates: {
minimum_version: string;
deadline: string;
diff --git a/frontend/pages/LoginSuccessfulPage/_styles.scss b/frontend/pages/LoginSuccessfulPage/_styles.scss
index 07e1429fa755..b3b962d3c9b9 100644
--- a/frontend/pages/LoginSuccessfulPage/_styles.scss
+++ b/frontend/pages/LoginSuccessfulPage/_styles.scss
@@ -3,7 +3,7 @@
margin-top: 20px;
padding: $pad-xxlarge;
text-align: center;
- border-radius: 10px;
+ border-radius: $border-radius-xlarge;
z-index: 0;
align-self: center;
transform: translateY(80px);
diff --git a/frontend/pages/ManageControlsPage/OSSettings/AggregateMacSettingsIndicators/AggregateMacSettingsIndicators.tsx b/frontend/pages/ManageControlsPage/OSSettings/AggregateMacSettingsIndicators/AggregateMacSettingsIndicators.tsx
deleted file mode 100644
index 7c4b4906011b..000000000000
--- a/frontend/pages/ManageControlsPage/OSSettings/AggregateMacSettingsIndicators/AggregateMacSettingsIndicators.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import React from "react";
-
-import paths from "router/paths";
-import { buildQueryStringFromParams } from "utilities/url";
-import { MdmProfileStatus, ProfileSummaryResponse } from "interfaces/mdm";
-import MacSettingsIndicator from "pages/hosts/details/MacSettingsIndicator";
-
-import { IconNames } from "components/icons";
-import Spinner from "components/Spinner";
-
-const baseClass = "aggregate-mac-settings-indicators";
-
-interface IAggregateDisplayOption {
- value: MdmProfileStatus;
- text: string;
- iconName: IconNames;
- tooltipText: string;
-}
-
-const AGGREGATE_STATUS_DISPLAY_OPTIONS: IAggregateDisplayOption[] = [
- {
- value: "verified",
- text: "Verified",
- iconName: "success",
- tooltipText:
- "These hosts installed all configuration profiles. Fleet verified with osquery.",
- },
- {
- value: "verifying",
- text: "Verifying",
- iconName: "success-partial",
- tooltipText:
- "These hosts acknowledged all MDM commands to install configuration profiles. " +
- "Fleet is verifying the profiles are installed with osquery.",
- },
- {
- value: "pending",
- text: "Pending",
- iconName: "pending-partial",
- tooltipText:
- "These hosts will receive MDM commands to install configuration profiles when the hosts come online.",
- },
- {
- value: "failed",
- text: "Failed",
- iconName: "error",
- tooltipText:
- "These hosts failed to install configuration profiles. Click on a host to view error(s).",
- },
-];
-
-interface AggregateMacSettingsIndicatorsProps {
- isLoading: boolean;
- teamId: number;
- aggregateProfileStatusData?: ProfileSummaryResponse;
-}
-
-const AggregateMacSettingsIndicators = ({
- isLoading,
- teamId,
- aggregateProfileStatusData,
-}: AggregateMacSettingsIndicatorsProps) => {
- const indicators = AGGREGATE_STATUS_DISPLAY_OPTIONS.map((status) => {
- if (!aggregateProfileStatusData) return null;
-
- const { value, text, iconName, tooltipText } = status;
- const count = aggregateProfileStatusData[value];
-
- return (
-
;
+};
+
+export default ProfileStatusAggregate;
diff --git a/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/ProfileStatusAggregateOptions.ts b/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/ProfileStatusAggregateOptions.ts
new file mode 100644
index 000000000000..8dbe94abf8fe
--- /dev/null
+++ b/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/ProfileStatusAggregateOptions.ts
@@ -0,0 +1,43 @@
+import { MdmProfileStatus } from "interfaces/mdm";
+import { IndicatorStatus } from "components/StatusIndicatorWithIcon/StatusIndicatorWithIcon";
+
+interface IAggregateDisplayOption {
+ value: MdmProfileStatus;
+ text: string;
+ iconName: IndicatorStatus;
+ tooltipText: string;
+}
+
+const AGGREGATE_STATUS_DISPLAY_OPTIONS: IAggregateDisplayOption[] = [
+ {
+ value: "verified",
+ text: "Verified",
+ iconName: "success",
+ tooltipText:
+ "These hosts applied all OS settings. Fleet verified with osquery.",
+ },
+ {
+ value: "verifying",
+ text: "Verifying",
+ iconName: "successPartial",
+ tooltipText:
+ "These hosts acknowledged all MDM commands to apply OS settings. " +
+ "Fleet is verifying the OS settings are applied with osquery.",
+ },
+ {
+ value: "pending",
+ text: "Pending",
+ iconName: "pendingPartial",
+ tooltipText:
+ "These hosts will receive MDM command to apply OS settings when the host come online.",
+ },
+ {
+ value: "failed",
+ text: "Failed",
+ iconName: "error",
+ tooltipText:
+ "These host failed to apply the latest OS settings. Click on a host to view error(s).",
+ },
+];
+
+export default AGGREGATE_STATUS_DISPLAY_OPTIONS;
diff --git a/frontend/pages/ManageControlsPage/OSSettings/AggregateMacSettingsIndicators/_styles.scss b/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/_styles.scss
similarity index 73%
rename from frontend/pages/ManageControlsPage/OSSettings/AggregateMacSettingsIndicators/_styles.scss
rename to frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/_styles.scss
index 76659544939a..89744cf6cc71 100644
--- a/frontend/pages/ManageControlsPage/OSSettings/AggregateMacSettingsIndicators/_styles.scss
+++ b/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/_styles.scss
@@ -1,16 +1,16 @@
-.aggregate-mac-settings-indicators {
+.profile-status-aggregate {
display: flex;
height: 94px;
border-top: 1px solid #e2e4ea;
border-bottom: 1px solid #e2e4ea;
border-left: 1px solid #e2e4ea;
- border-radius: 6px;
+ border-radius: $border-radius-large;
&__loading-spinner {
margin: auto;
}
- .aggregate-mac-settings-indicator {
+ &__profile-status-count {
flex-grow: 1;
display: flex;
@@ -29,13 +29,17 @@
font-weight: $regular;
}
- .settings-indicator {
+ .profile-status-indicator {
flex-direction: column;
}
}
- .aggregate-mac-settings-indicator:last-child {
+ &__profile-status-count:last-child {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
+
+ &__status-indicator-value {
+ font-weight: $bold;
+ }
}
diff --git a/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/index.ts b/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/index.ts
new file mode 100644
index 000000000000..a29bd5e10d5f
--- /dev/null
+++ b/frontend/pages/ManageControlsPage/OSSettings/ProfileStatusAggregate/index.ts
@@ -0,0 +1 @@
+export { default } from "./ProfileStatusAggregate";
diff --git a/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/DiskEncryption.tsx b/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/DiskEncryption.tsx
index 6edd4f35f5f2..c8cd1d2bc37b 100644
--- a/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/DiskEncryption.tsx
+++ b/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/DiskEncryption.tsx
@@ -31,7 +31,7 @@ const DiskEncryption = ({
const defaultShowDiskEncryption = currentTeamId
? false
- : config?.mdm.macos_settings.enable_disk_encryption ?? false;
+ : config?.mdm.enable_disk_encryption ?? false;
const [isLoadingTeam, setIsLoadingTeam] = useState(true);
@@ -67,8 +67,7 @@ const DiskEncryption = ({
enabled: currentTeamId !== 0,
select: (res) => res.team,
onSuccess: (res) => {
- const enableDiskEncryption =
- res.mdm?.macos_settings.enable_disk_encryption ?? false;
+ const enableDiskEncryption = res.mdm?.enable_disk_encryption ?? false;
setDiskEncryptionEnabled(enableDiskEncryption);
setShowAggregate(enableDiskEncryption);
setIsLoadingTeam(false);
@@ -100,6 +99,19 @@ const DiskEncryption = ({
setIsLoadingTeam(false);
}
+ const createDescriptionText = () => {
+ // table is showing disk encryption status.
+ if (showAggregate) {
+ return "If turned on, hosts' disk encryption keys will be stored in Fleet. ";
+ }
+
+ const isWindowsFeatureFlagEnabled = config?.mdm_enabled ?? false;
+ const dynamicText = isWindowsFeatureFlagEnabled
+ ? " and “BitLocker” on Windows"
+ : "";
+ return `Also known as “FileVault” on macOS${dynamicText}. If turned on, hosts' disk encryption keys will be stored in Fleet. `;
+ };
+
return (
Disk encryption
@@ -124,8 +136,7 @@ const DiskEncryption = ({
On
- Apple calls this “FileVault.” If turned on, hosts' disk
- encryption keys will be stored in Fleet.{" "}
+ {createDescriptionText()}
{
+ const { config } = useContext(AppContext);
+
const {
data: diskEncryptionStatusData,
error: diskEncryptionStatusError,
- } = useQuery(
+ } = useQuery(
["disk-encryption-summary", currentTeamId],
- () => mdmAPI.getDiskEncryptionAggregate(currentTeamId),
+ () => mdmAPI.getDiskEncryptionSummary(currentTeamId),
{
refetchOnWindowFocus: false,
retry: false,
}
);
- const tableHeaders = generateTableHeaders();
-
- const tableData = generateTableData(diskEncryptionStatusData, currentTeamId);
+ // TODO: WINDOWS FEATURE FLAG: remove this when windows feature flag is removed.
+ // this is used to conditianlly show "View all hosts" link in table cells.
+ const windowsFeatureFlagEnabled = config?.mdm_enabled ?? false;
+ const tableHeaders = generateTableHeaders(windowsFeatureFlagEnabled);
+ const tableData = generateTableData(
+ windowsFeatureFlagEnabled,
+ diskEncryptionStatusData,
+ currentTeamId
+ );
if (diskEncryptionStatusError) {
return ;
@@ -53,8 +59,7 @@ const DiskEncryptionTable = ({ currentTeamId }: IDiskEncryptionTableProps) => {
isLoading={false}
showMarkAllPages={false}
isAllPagesSelected={false}
- defaultSortHeader={DEFAULT_SORT_HEADER}
- defaultSortDirection={DEFAULT_SORT_DIRECTION}
+ manualSortBy
disableTableHeader
disablePagination
disableCount
diff --git a/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/DiskEncryptionTableConfig.tsx b/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/DiskEncryptionTableConfig.tsx
index 068459d69cfb..9a5b7baf5dbe 100644
--- a/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/DiskEncryptionTableConfig.tsx
+++ b/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/DiskEncryptionTableConfig.tsx
@@ -1,7 +1,11 @@
import React from "react";
-import { FileVaultProfileStatus } from "interfaces/mdm";
-import { IFileVaultSummaryResponse } from "services/entities/mdm";
+import { DiskEncryptionStatus } from "interfaces/mdm";
+import {
+ IDiskEncryptionStatusAggregate,
+ IDiskEncryptionSummaryResponse,
+} from "services/entities/mdm";
+import { DISK_ENCRYPTION_QUERY_PARAM_NAME } from "services/entities/hosts";
import TextCell from "components/TableContainer/DataTable/TextCell";
import HeaderCell from "components/TableContainer/DataTable/HeaderCell";
@@ -12,7 +16,7 @@ import { IndicatorStatus } from "components/StatusIndicatorWithIcon/StatusIndica
interface IStatusCellValue {
displayName: string;
statusName: IndicatorStatus;
- value: FileVaultProfileStatus;
+ value: DiskEncryptionStatus;
tooltip?: string | JSX.Element;
}
@@ -28,6 +32,7 @@ interface ICellProps {
};
row: {
original: {
+ includeWindows: boolean;
status: IStatusCellValue;
teamId: number;
};
@@ -72,15 +77,53 @@ const defaultTableHeaders: IDataColumn[] = [
},
},
{
- title: "Hosts",
+ title: "macOS hosts",
Header: (cellProps: IHeaderProps) => (
),
- accessor: "hosts",
+ disableSortBy: true,
+ accessor: "macosHosts",
+ Cell: ({
+ cell: { value: aggregateCount },
+ row: { original },
+ }: ICellProps) => {
+ return (
+
+ <>{val}>} />
+ {/* TODO: WINDOWS FEATURE FLAG: remove this conditional when windows mdm
+ is released. the view all UI will show in the windows column when we
+ release the feature. */}
+ {!original.includeWindows && (
+
+ )}
+
+ );
+ },
+ },
+];
+
+const windowsTableHeader: IDataColumn[] = [
+ {
+ title: "Windows hosts",
+ Header: (cellProps: IHeaderProps) => (
+
+ ),
+ disableSortBy: true,
+ accessor: "windowsHosts",
Cell: ({
cell: { value: aggregateCount },
row: { original },
@@ -91,7 +134,7 @@ const defaultTableHeaders: IDataColumn[] = [
@@ -101,15 +144,17 @@ const defaultTableHeaders: IDataColumn[] = [
},
];
-type StatusNames = keyof IFileVaultSummaryResponse;
-
-type StatusEntry = [StatusNames, number];
-
-export const generateTableHeaders = (): IDataColumn[] => {
+// TODO: WINDOWS FEATURE FLAG: return all headers when windows feature flag is removed.
+export const generateTableHeaders = (
+ includeWindows: boolean
+): IDataColumn[] => {
+ return includeWindows
+ ? [...defaultTableHeaders, ...windowsTableHeader]
+ : defaultTableHeaders;
return defaultTableHeaders;
};
-const STATUS_CELL_VALUES: Record = {
+const STATUS_CELL_VALUES: Record = {
verified: {
displayName: "Verified",
statusName: "success",
@@ -122,8 +167,8 @@ const STATUS_CELL_VALUES: Record = {
statusName: "successPartial",
value: "verifying",
tooltip:
- "These hosts acknowledged the MDM command to install disk encryption profile. " +
- "Fleet is verifying with osquery and retrieving the disk encryption key. This may take up to one hour.",
+ "These hosts acknowledged the MDM command to turn on disk encryption. Fleet is verifying with " +
+ "osquery and retrieving the disk encryption key. This may take up to one hour.",
},
action_required: {
displayName: "Action required (pending)",
@@ -141,7 +186,7 @@ const STATUS_CELL_VALUES: Record = {
statusName: "pendingPartial",
value: "enforcing",
tooltip:
- "These hosts will receive the MDM command to install the disk encryption profile when the hosts come online.",
+ "These hosts will receive the MDM command to turn on disk encryption when the hosts come online.",
},
failed: {
displayName: "Failed",
@@ -153,21 +198,41 @@ const STATUS_CELL_VALUES: Record = {
statusName: "pendingPartial",
value: "removing_enforcement",
tooltip:
- "These hosts will receive the MDM command to remove the disk encryption profile when the hosts come online.",
+ "These hosts will receive the MDM command to turn off disk encryption when the hosts come online.",
},
};
+type StatusEntry = [DiskEncryptionStatus, IDiskEncryptionStatusAggregate];
+
+// Order of the status column. We want the order to always be the same.
+const STATUS_ORDER = [
+ "verified",
+ "verifying",
+ "failed",
+ "action_required",
+ "enforcing",
+ "removing_enforcement",
+] as const;
+
export const generateTableData = (
- data?: IFileVaultSummaryResponse,
+ // TODO: WINDOWS FEATURE FLAG: remove includeWindows when windows feature flag is removed.
+ // This is used to conditionally show "View all hosts" link in table cells.
+ includeWindows: boolean,
+ data?: IDiskEncryptionSummaryResponse,
currentTeamId?: number
) => {
if (!data) return [];
- const entries = Object.entries(data) as StatusEntry[];
- return entries.map(([status, numHosts]) => ({
- // eslint-disable-next-line object-shorthand
+ const rowFromStatusEntry = (
+ status: DiskEncryptionStatus,
+ statusAggregate: IDiskEncryptionStatusAggregate
+ ) => ({
+ includeWindows,
status: STATUS_CELL_VALUES[status],
- hosts: numHosts,
+ macosHosts: statusAggregate.macos,
+ windowsHosts: statusAggregate.windows,
teamId: currentTeamId,
- }));
+ });
+
+ return STATUS_ORDER.map((status) => rowFromStatusEntry(status, data[status]));
};
diff --git a/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/_styles.scss b/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/_styles.scss
index ee3e1c025ea8..c2e35efe6b8b 100644
--- a/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/_styles.scss
+++ b/frontend/pages/ManageControlsPage/OSSettings/cards/DiskEncryption/components/DiskEncryptionTable/_styles.scss
@@ -1,7 +1,4 @@
.disk-encryption-table {
- padding: $pad-xxlarge;
- border: 1px solid $ui-fleet-black-10;
- border-radius: $border-radius;
margin-bottom: $pad-xxlarge;
.data-table-block .data-table tbody td .w250 {
diff --git a/frontend/pages/ManageControlsPage/components/TurnOnMdmMessage/TurnOnMdmMessage.tsx b/frontend/pages/ManageControlsPage/components/TurnOnMdmMessage/TurnOnMdmMessage.tsx
index 545887a8f5d2..ce052c31e180 100644
--- a/frontend/pages/ManageControlsPage/components/TurnOnMdmMessage/TurnOnMdmMessage.tsx
+++ b/frontend/pages/ManageControlsPage/components/TurnOnMdmMessage/TurnOnMdmMessage.tsx
@@ -30,7 +30,7 @@ const TurnOnMdmMessage = ({ router }: ITurnOnMdmMessageProps) => {
return (
diff --git a/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx b/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx
index 2fbaac795a75..b4102d321e83 100644
--- a/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/HostsPageConfig.tsx
@@ -1,6 +1,7 @@
import React from "react";
import Icon from "components/Icon";
+import { DISK_ENCRYPTION_QUERY_PARAM_NAME } from "services/entities/hosts";
export const MANAGE_HOSTS_PAGE_FILTER_KEYS = [
"query",
@@ -17,7 +18,7 @@ export const MANAGE_HOSTS_PAGE_FILTER_KEYS = [
"os_version",
"munki_issue_id",
"low_disk_space",
- "macos_settings_disk_encryption",
+ DISK_ENCRYPTION_QUERY_PARAM_NAME,
"bootstrap_package",
] as const;
diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
index ab6a3b4debcd..6eedf30627c1 100644
--- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
@@ -18,6 +18,7 @@ import labelsAPI, { ILabelsResponse } from "services/entities/labels";
import teamsAPI, { ILoadTeamsResponse } from "services/entities/teams";
import globalPoliciesAPI from "services/entities/global_policies";
import hostsAPI, {
+ DISK_ENCRYPTION_QUERY_PARAM_NAME,
ILoadHostsQueryKey,
ILoadHostsResponse,
ISortOption,
@@ -49,7 +50,7 @@ import { IOperatingSystemVersion } from "interfaces/operating_system";
import { IPolicy, IStoredPolicyResponse } from "interfaces/policy";
import { ITeam } from "interfaces/team";
import { IEmptyTableProps } from "interfaces/empty_table";
-import { FileVaultProfileStatus, BootstrapPackageStatus } from "interfaces/mdm";
+import { DiskEncryptionStatus, BootstrapPackageStatus } from "interfaces/mdm";
import sortUtils from "utilities/sort";
import {
@@ -232,8 +233,8 @@ const ManageHostsPage = ({
? parseInt(queryParams.low_disk_space, 10)
: undefined;
const missingHosts = queryParams?.status === "missing";
- const diskEncryptionStatus: FileVaultProfileStatus | undefined =
- queryParams?.macos_settings_disk_encryption;
+ const diskEncryptionStatus: DiskEncryptionStatus | undefined =
+ queryParams?.[DISK_ENCRYPTION_QUERY_PARAM_NAME];
const bootstrapPackageStatus: BootstrapPackageStatus | undefined =
queryParams?.bootstrap_package;
@@ -558,7 +559,7 @@ const ManageHostsPage = ({
};
const handleChangeDiskEncryptionStatusFilter = (
- newStatus: FileVaultProfileStatus
+ newStatus: DiskEncryptionStatus
) => {
handleResetPageIndex();
@@ -569,7 +570,7 @@ const ManageHostsPage = ({
routeParams,
queryParams: {
...queryParams,
- macos_settings_disk_encryption: newStatus,
+ [DISK_ENCRYPTION_QUERY_PARAM_NAME]: newStatus,
page: 0, // resets page index
},
})
@@ -768,7 +769,7 @@ const ManageHostsPage = ({
newQueryParams.os_version = osVersion;
} else if (diskEncryptionStatus && isPremiumTier) {
// Premium feature only
- newQueryParams.macos_settings_disk_encryption = diskEncryptionStatus;
+ newQueryParams[DISK_ENCRYPTION_QUERY_PARAM_NAME] = diskEncryptionStatus;
} else if (bootstrapPackageStatus && isPremiumTier) {
newQueryParams.bootstrap_package = bootstrapPackageStatus;
}
diff --git a/frontend/pages/hosts/ManageHostsPage/components/CustomLabelGroupHeading/_styles.scss b/frontend/pages/hosts/ManageHostsPage/components/CustomLabelGroupHeading/_styles.scss
index 38a15997083d..d4cb6bed093e 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/CustomLabelGroupHeading/_styles.scss
+++ b/frontend/pages/hosts/ManageHostsPage/components/CustomLabelGroupHeading/_styles.scss
@@ -33,7 +33,7 @@
line-height: 1.5;
background-color: $ui-light-grey;
border: solid 1px $ui-fleet-black-10;
- border-radius: 4px;
+ border-radius: $border-radius;
font-size: $small;
padding: 9.5px 12px 9.5px 36px;
color: $core-fleet-blue;
@@ -70,7 +70,7 @@
color: $core-vibrant-red;
border: 1px solid $core-vibrant-red;
box-sizing: border-box;
- border-radius: 4px;
+ border-radius: $border-radius;
&:focus {
border-color: $ui-error;
diff --git a/frontend/pages/hosts/ManageHostsPage/components/DiskEncryptionStatusFilter/DiskEncryptionStatusFilter.tsx b/frontend/pages/hosts/ManageHostsPage/components/DiskEncryptionStatusFilter/DiskEncryptionStatusFilter.tsx
index 2405fd6d151b..4e49123919f1 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/DiskEncryptionStatusFilter/DiskEncryptionStatusFilter.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/components/DiskEncryptionStatusFilter/DiskEncryptionStatusFilter.tsx
@@ -4,7 +4,7 @@ import { IDropdownOption } from "interfaces/dropdownOption";
// @ts-ignore
import Dropdown from "components/forms/fields/Dropdown";
-import { FileVaultProfileStatus } from "interfaces/mdm";
+import { DiskEncryptionStatus } from "interfaces/mdm";
const baseClass = "disk-encryption-status-filter";
@@ -42,8 +42,8 @@ const DISK_ENCRYPTION_STATUS_OPTIONS: IDropdownOption[] = [
];
interface IDiskEncryptionStatusFilterProps {
- diskEncryptionStatus: FileVaultProfileStatus;
- onChange: (value: FileVaultProfileStatus) => void;
+ diskEncryptionStatus: DiskEncryptionStatus;
+ onChange: (value: DiskEncryptionStatus) => void;
}
const DiskEncryptionStatusFilter = ({
diff --git a/frontend/pages/hosts/ManageHostsPage/components/FilterPill/_styles.scss b/frontend/pages/hosts/ManageHostsPage/components/FilterPill/_styles.scss
index a7badf53a1f1..8f4a9c76a377 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/FilterPill/_styles.scss
+++ b/frontend/pages/hosts/ManageHostsPage/components/FilterPill/_styles.scss
@@ -4,7 +4,7 @@
align-items: center;
padding: 6px 12px;
border: 1px solid $ui-fleet-black-25;
- border-radius: 4px;
+ border-radius: $border-radius;
box-shadow: none;
color: $core-fleet-black;
font-size: $xx-small;
diff --git a/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx b/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx
index 0e64c52c744f..1ff7287cb3c8 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/components/HostsFilterBlock/HostsFilterBlock.tsx
@@ -7,7 +7,7 @@ import {
IOperatingSystemVersion,
} from "interfaces/operating_system";
import {
- FileVaultProfileStatus,
+ DiskEncryptionStatus,
BootstrapPackageStatus,
IMdmSolution,
MDM_ENROLLMENT_STATUS,
@@ -15,7 +15,10 @@ import {
import { IMunkiIssuesAggregate } from "interfaces/macadmins";
import { ISoftware } from "interfaces/software";
import { IPolicy } from "interfaces/policy";
-import { MacSettingsStatusQueryParam } from "services/entities/hosts";
+import {
+ DISK_ENCRYPTION_QUERY_PARAM_NAME,
+ MacSettingsStatusQueryParam,
+} from "services/entities/hosts";
import {
PLATFORM_LABEL_DISPLAY_NAMES,
@@ -60,7 +63,7 @@ interface IHostsFilterBlockProps {
osVersions?: IOperatingSystemVersion[];
softwareDetails: ISoftware | null;
mdmSolutionDetails: IMdmSolution | null;
- diskEncryptionStatus?: FileVaultProfileStatus;
+ diskEncryptionStatus?: DiskEncryptionStatus;
bootstrapPackageStatus?: BootstrapPackageStatus;
};
selectedLabel?: ILabel;
@@ -68,9 +71,7 @@ interface IHostsFilterBlockProps {
handleClearRouteParam: () => void;
handleClearFilter: (omitParams: string[]) => void;
onChangePoliciesFilter: (response: PolicyResponse) => void;
- onChangeDiskEncryptionStatusFilter: (
- response: FileVaultProfileStatus
- ) => void;
+ onChangeDiskEncryptionStatusFilter: (response: DiskEncryptionStatus) => void;
onChangeBootstrapPackageStatusFilter: (
response: BootstrapPackageStatus
) => void;
@@ -376,8 +377,8 @@ const HostsFilterBlock = ({
onChange={onChangeDiskEncryptionStatusFilter}
/>
handleClearFilter(["macos_settings_disk_encryption"])}
+ label="OS settings: Disk encryption"
+ onClear={() => handleClearFilter([DISK_ENCRYPTION_QUERY_PARAM_NAME])}
/>
>
);
diff --git a/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx b/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx
index 285c0f8908ad..d5550026d577 100644
--- a/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx
+++ b/frontend/pages/hosts/details/DeviceUserPage/DeviceUserPage.tsx
@@ -417,6 +417,7 @@ const DeviceUserPage = ({
showRefetchSpinner={showRefetchSpinner}
onRefetchHost={onRefetchHost}
renderActionButtons={renderActionButtons}
+ osSettings={host?.mdm.os_settings}
deviceUser
/>
@@ -489,6 +490,7 @@ const DeviceUserPage = ({
)}
{showMacSettingsModal && (
diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
index 0d1a0b6b46d3..e388493de6d4 100644
--- a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
+++ b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
@@ -65,6 +65,7 @@ import HostActionDropdown from "./HostActionsDropdown/HostActionsDropdown";
import MacSettingsModal from "../MacSettingsModal";
import BootstrapPackageModal from "./modals/BootstrapPackageModal";
import SelectQueryModal from "./modals/SelectQueryModal";
+import { isSupportedPlatform } from "./modals/DiskEncryptionKeyModal/DiskEncryptionKeyModal";
const baseClass = "host-details";
@@ -720,6 +721,7 @@ const HostDetailsPage = ({
showRefetchSpinner={showRefetchSpinner}
onRefetchHost={onRefetchHost}
renderActionButtons={renderActionButtons}
+ osSettings={host?.mdm.os_settings}
/>
@@ -852,12 +855,15 @@ const HostDetailsPage = ({
{showUnenrollMdmModal && !!host && (
)}
- {showDiskEncryptionModal && host && (
- setShowDiskEncryptionModal(false)}
- />
- )}
+ {showDiskEncryptionModal &&
+ host &&
+ isSupportedPlatform(host.platform) && (
+ setShowDiskEncryptionModal(false)}
+ />
+ )}
{showBootstrapPackageModal &&
bootstrapPackageData.details &&
bootstrapPackageData.name && (
diff --git a/frontend/pages/hosts/details/HostDetailsPage/modals/DiskEncryptionKeyModal/DiskEncryptionKeyModal.tsx b/frontend/pages/hosts/details/HostDetailsPage/modals/DiskEncryptionKeyModal/DiskEncryptionKeyModal.tsx
index 8acdc6622ebd..1046822673b2 100644
--- a/frontend/pages/hosts/details/HostDetailsPage/modals/DiskEncryptionKeyModal/DiskEncryptionKeyModal.tsx
+++ b/frontend/pages/hosts/details/HostDetailsPage/modals/DiskEncryptionKeyModal/DiskEncryptionKeyModal.tsx
@@ -9,15 +9,32 @@ import CustomLink from "components/CustomLink";
import Button from "components/buttons/Button";
import InputFieldHiddenContent from "components/forms/fields/InputFieldHiddenContent";
import DataError from "components/DataError";
+import { SupportedPlatform } from "interfaces/platform";
const baseClass = "disk-encryption-key-modal";
+// currently these are the only supported platforms for the disk encryption
+// key modal.
+export type ModalSupportedPlatform = Extract<
+ SupportedPlatform,
+ "darwin" | "windows"
+>;
+
+// Checks to see if the platform is supported by the modal.
+export const isSupportedPlatform = (
+ platform: string
+): platform is ModalSupportedPlatform => {
+ return ["darwin", "windows"].includes(platform);
+};
+
interface IDiskEncryptionKeyModal {
+ platform: ModalSupportedPlatform;
hostId: number;
onCancel: () => void;
}
const DiskEncryptionKeyModal = ({
+ platform,
hostId,
onCancel,
}: IDiskEncryptionKeyModal) => {
@@ -33,6 +50,18 @@ const DiskEncryptionKeyModal = ({
select: (data) => data.encryption_key.key,
});
+ const isMacOS = platform === "darwin";
+ const descriptionText = isMacOS
+ ? "The disk encryption key refers to the FileVault recovery key for macOS."
+ : "The disk encryption key refers to the BitLocker recovery key for Windows.";
+
+ const recoveryText = isMacOS
+ ? "Use this key to log in to the host if you forgot the password."
+ : "Use this key to unlock the encrypted drive.";
+ const recoveryUrl = isMacOS
+ ? "https://fleetdm.com/docs/using-fleet/mdm-disk-encryption#reset-a-macos-hosts-password-using-the-disk-encryption-key"
+ : "https://fleetdm.com/docs/using-fleet/mdm-disk-encryption#unlock-a-windows-hosts-drive-using-the-disk-encryption-key";
+
return (
{encryptionKeyError ? (
@@ -40,15 +69,12 @@ const DiskEncryptionKeyModal = ({
) : (
<>
+
{descriptionText}
- The disk encryption key refers to the FileVault recovery key for
- macOS.
-
-
- Use this key to log in to the host if you forgot the password.{" "}
+ {recoveryText}{" "}
diff --git a/frontend/pages/hosts/details/HostDetailsPage/modals/OSPolicyModal/_styles.scss b/frontend/pages/hosts/details/HostDetailsPage/modals/OSPolicyModal/_styles.scss
index 7f2f5f1ff1b7..c0b6053f3043 100644
--- a/frontend/pages/hosts/details/HostDetailsPage/modals/OSPolicyModal/_styles.scss
+++ b/frontend/pages/hosts/details/HostDetailsPage/modals/OSPolicyModal/_styles.scss
@@ -42,7 +42,7 @@
&__copy-message {
background-color: $ui-light-grey;
border: solid 1px #e2e4ea;
- border-radius: 10px;
+ border-radius: $border-radius-xlarge;
padding: 2px 6px;
}
}
diff --git a/frontend/pages/hosts/details/MacSettingsIndicator/index.ts b/frontend/pages/hosts/details/MacSettingsIndicator/index.ts
deleted file mode 100644
index 47e97520648e..000000000000
--- a/frontend/pages/hosts/details/MacSettingsIndicator/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from "./MacSettingsIndicator";
diff --git a/frontend/pages/hosts/details/MacSettingsModal/MacSettingsModal.tsx b/frontend/pages/hosts/details/MacSettingsModal/MacSettingsModal.tsx
index a055bae71536..eab9e92bbbe0 100644
--- a/frontend/pages/hosts/details/MacSettingsModal/MacSettingsModal.tsx
+++ b/frontend/pages/hosts/details/MacSettingsModal/MacSettingsModal.tsx
@@ -7,20 +7,28 @@ import MacSettingsTable from "./MacSettingsTable";
import { generateTableData } from "./MacSettingsTable/MacSettingsTableConfig";
interface IMacSettingsModalProps {
- hostMDMData?: Pick;
+ platform?: string;
+ hostMDMData?: IHostMdmData;
onClose: () => void;
}
const baseClass = "mac-settings-modal";
-const MacSettingsModal = ({ hostMDMData, onClose }: IMacSettingsModalProps) => {
- const memoizedTableData = useMemo(() => generateTableData(hostMDMData), [
- hostMDMData,
- ]);
+const MacSettingsModal = ({
+ platform,
+ hostMDMData,
+ onClose,
+}: IMacSettingsModalProps) => {
+ const memoizedTableData = useMemo(
+ () => generateTableData(hostMDMData, platform),
+ [hostMDMData, platform]
+ );
+
+ if (!platform) return null;
return (
innerProps.isDiskEncryptionProfile
- ? "The host will receive the MDM command to install the disk encryption profile when the " +
- "host comes online."
+ ? "The hosts will receive the MDM command to turn on disk encryption " +
+ "when the hosts come online."
: "The host will receive the MDM command to install the configuration profile when the " +
"host comes online.",
},
@@ -56,8 +59,8 @@ const PROFILE_DISPLAY_CONFIG: ProfileDisplayConfig = {
iconName: "success",
tooltip: (innerProps) =>
innerProps.isDiskEncryptionProfile
- ? "The host turned disk encryption on and " +
- "sent their key to Fleet. Fleet verified with osquery."
+ ? "The host turned disk encryption on and sent the key to Fleet. " +
+ "Fleet verified with osquery."
: "The host installed the configuration profile. Fleet verified with osquery.",
},
verifying: {
@@ -65,8 +68,9 @@ const PROFILE_DISPLAY_CONFIG: ProfileDisplayConfig = {
iconName: "success-partial",
tooltip: (innerProps) =>
innerProps.isDiskEncryptionProfile
- ? "The host acknowledged the MDM command to install disk encryption profile. Fleet is " +
- "verifying with osquery and retrieving the disk encryption key. This may take up to one hour."
+ ? "The host acknowledged the MDM command to turn on disk encryption. " +
+ "Fleet is verifying with osquery and retrieving the disk encryption key. " +
+ "This may take up to one hour."
: "The host acknowledged the MDM command to install the configuration profile. Fleet is " +
"verifying with osquery.",
},
@@ -98,9 +102,41 @@ const PROFILE_DISPLAY_CONFIG: ProfileDisplayConfig = {
},
};
+type WindowsDiskEncryptionDisplayConfig = Omit<
+ OperationTypeOption,
+ "action_required"
+>;
+
+const WINDOWS_DISK_ENCRYPTION_DISPLAY_CONFIG: WindowsDiskEncryptionDisplayConfig = {
+ verified: {
+ statusText: "Verified",
+ iconName: "success",
+ tooltip: () =>
+ "The host turned disk encryption on and sent the key to Fleet. Fleet verified with osquery.",
+ },
+ verifying: {
+ statusText: "Verifying",
+ iconName: "success-partial",
+ tooltip: () =>
+ "The host acknowledged the MDM command to turn on disk encryption. Fleet is verifying with osquery and retrieving " +
+ "the disk encryption key. This may take up to one hour.",
+ },
+ pending: {
+ statusText: "Enforcing (pending)",
+ iconName: "pending-partial",
+ tooltip: () =>
+ "The host will receive the MDM command to turn on disk encryption when the host comes online.",
+ },
+ failed: {
+ statusText: "Failed",
+ iconName: "error",
+ tooltip: null,
+ },
+};
+
interface IMacSettingStatusCellProps {
status: MacSettingsTableStatusValue;
- operationType: MacMdmProfileOperationType;
+ operationType: MacMdmProfileOperationType | null;
profileName: string;
}
@@ -108,8 +144,18 @@ const MacSettingStatusCell = ({
status,
operationType,
profileName = "",
-}: IMacSettingStatusCellProps): JSX.Element => {
- const diplayOption = PROFILE_DISPLAY_CONFIG[operationType]?.[status];
+}: IMacSettingStatusCellProps) => {
+ let displayOption: ProfileDisplayOption = null;
+
+ // windows hosts do not have an operation type at the moment and their display options are
+ // different than mac hosts.
+ if (!operationType && isMdmProfileStatus(status)) {
+ displayOption = WINDOWS_DISK_ENCRYPTION_DISPLAY_CONFIG[status];
+ }
+
+ if (operationType) {
+ displayOption = PROFILE_DISPLAY_CONFIG[operationType]?.[status];
+ }
const isDeviceUser = window.location.pathname
.toLowerCase()
@@ -118,8 +164,8 @@ const MacSettingStatusCell = ({
const isDiskEncryptionProfile =
profileName === FLEET_FILEVAULT_PROFILE_DISPLAY_NAME;
- if (diplayOption) {
- const { statusText, iconName, tooltip } = diplayOption;
+ if (displayOption) {
+ const { statusText, iconName, tooltip } = displayOption;
const tooltipId = uniqueId();
return (
diff --git a/frontend/pages/hosts/details/MacSettingsModal/MacSettingsTable/MacSettingsTableConfig.tsx b/frontend/pages/hosts/details/MacSettingsModal/MacSettingsTable/MacSettingsTableConfig.tsx
index 39bd021222b4..7b2364af255c 100644
--- a/frontend/pages/hosts/details/MacSettingsModal/MacSettingsTable/MacSettingsTableConfig.tsx
+++ b/frontend/pages/hosts/details/MacSettingsModal/MacSettingsTable/MacSettingsTableConfig.tsx
@@ -5,20 +5,27 @@ import { IHostMdmData } from "interfaces/host";
import {
FLEET_FILEVAULT_PROFILE_DISPLAY_NAME,
// FLEET_FILEVAULT_PROFILE_IDENTIFIER,
- IHostMacMdmProfile,
+ IHostMdmProfile,
MdmProfileStatus,
+ isWindowsDiskEncryptionStatus,
} from "interfaces/mdm";
import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants";
import TruncatedTextCell from "components/TableContainer/DataTable/TruncatedTextCell";
import MacSettingStatusCell from "./MacSettingStatusCell";
+import { generateWinDiskEncryptionProfile } from "../../helpers";
-export interface IMacSettingsTableRow
- extends Omit {
+export interface IMacSettingsTableRow extends Omit {
status: MacSettingsTableStatusValue;
}
export type MacSettingsTableStatusValue = MdmProfileStatus | "action_required";
+export const isMdmProfileStatus = (
+ status: string
+): status is MdmProfileStatus => {
+ return status !== "action_required";
+};
+
interface IHeaderProps {
column: {
title: string;
@@ -92,20 +99,41 @@ const tableHeaders: IDataColumn[] = [
];
export const generateTableData = (
- hostMDMData?: Pick
+ hostMDMData?: IHostMdmData,
+ platform?: string
) => {
+ if (!platform) return [];
+
let rows: IMacSettingsTableRow[] = [];
if (!hostMDMData) {
return rows;
}
+ if (
+ platform === "windows" &&
+ hostMDMData.os_settings?.disk_encryption.status &&
+ isWindowsDiskEncryptionStatus(
+ hostMDMData.os_settings.disk_encryption.status
+ )
+ ) {
+ rows.push(
+ generateWinDiskEncryptionProfile(
+ hostMDMData.os_settings.disk_encryption.status
+ )
+ );
+ return rows;
+ }
+
const { profiles, macos_settings } = hostMDMData;
+
if (!profiles) {
return rows;
}
- rows = profiles;
- if (macos_settings?.disk_encryption === "action_required") {
+ if (
+ platform === "darwin" &&
+ macos_settings?.disk_encryption === "action_required"
+ ) {
rows = profiles.map((p) => {
// TODO: this is a brittle check for the filevault profile
// it would be better to match on the identifier but it is not
diff --git a/frontend/pages/hosts/details/MacSettingsIndicator/MacSettingsIndicator.tests.tsx b/frontend/pages/hosts/details/ProfileStatusIndicator/ProfileStatusIndicator.tests.tsx
similarity index 87%
rename from frontend/pages/hosts/details/MacSettingsIndicator/MacSettingsIndicator.tests.tsx
rename to frontend/pages/hosts/details/ProfileStatusIndicator/ProfileStatusIndicator.tests.tsx
index a71467903cec..73044dd21805 100644
--- a/frontend/pages/hosts/details/MacSettingsIndicator/MacSettingsIndicator.tests.tsx
+++ b/frontend/pages/hosts/details/ProfileStatusIndicator/ProfileStatusIndicator.tests.tsx
@@ -1,12 +1,15 @@
import React from "react";
import { fireEvent, render, screen } from "@testing-library/react";
-import MacSettingsIndicator from "./MacSettingsIndicator";
+import ProfileStatusIndicator from "./ProfileStatusIndicator";
-describe("MacSettingsIndicator", () => {
+describe("ProfileStatusIndicator component", () => {
it("Renders the text and icon", () => {
const indicatorText = "test text";
render(
-
+
);
const renderedIndicatorText = screen.getByText(indicatorText);
const renderedIcon = screen.getByTestId("success-icon");
@@ -19,7 +22,7 @@ describe("MacSettingsIndicator", () => {
const indicatorText = "test text";
const tooltipText = "test tooltip text";
render(
- {
document.body.appendChild(newDiv);
};
render(
- {
diff --git a/frontend/pages/hosts/details/MacSettingsIndicator/MacSettingsIndicator.tsx b/frontend/pages/hosts/details/ProfileStatusIndicator/ProfileStatusIndicator.tsx
similarity index 92%
rename from frontend/pages/hosts/details/MacSettingsIndicator/MacSettingsIndicator.tsx
rename to frontend/pages/hosts/details/ProfileStatusIndicator/ProfileStatusIndicator.tsx
index 473745ee3344..f3bbe6cd024c 100644
--- a/frontend/pages/hosts/details/MacSettingsIndicator/MacSettingsIndicator.tsx
+++ b/frontend/pages/hosts/details/ProfileStatusIndicator/ProfileStatusIndicator.tsx
@@ -4,9 +4,9 @@ import { IconNames } from "components/icons";
import Icon from "components/Icon";
import Button from "components/buttons/Button";
-const baseClass = "settings-indicator";
+const baseClass = "profile-status-indicator";
-export interface IMacSettingsIndicator {
+export interface IProfileStatusIndicatorProps {
indicatorText: string;
iconName: IconNames;
onClick?: () => void;
@@ -16,12 +16,12 @@ export interface IMacSettingsIndicator {
};
}
-const MacSettingsIndicator = ({
+const ProfileStatusIndicator = ({
indicatorText,
iconName,
onClick,
tooltip,
-}: IMacSettingsIndicator): JSX.Element => {
+}: IProfileStatusIndicatorProps) => {
const getIndicatorTextWrapped = () => {
if (onClick && tooltip?.tooltipText) {
return (
@@ -103,4 +103,4 @@ const MacSettingsIndicator = ({
);
};
-export default MacSettingsIndicator;
+export default ProfileStatusIndicator;
diff --git a/frontend/pages/hosts/details/MacSettingsIndicator/_styles.scss b/frontend/pages/hosts/details/ProfileStatusIndicator/_styles.scss
similarity index 88%
rename from frontend/pages/hosts/details/MacSettingsIndicator/_styles.scss
rename to frontend/pages/hosts/details/ProfileStatusIndicator/_styles.scss
index fce8265c95eb..a7ed40ad9155 100644
--- a/frontend/pages/hosts/details/MacSettingsIndicator/_styles.scss
+++ b/frontend/pages/hosts/details/ProfileStatusIndicator/_styles.scss
@@ -1,4 +1,4 @@
-.settings-indicator {
+.profile-status-indicator {
display: flex;
gap: 4px;
diff --git a/frontend/pages/hosts/details/ProfileStatusIndicator/index.ts b/frontend/pages/hosts/details/ProfileStatusIndicator/index.ts
new file mode 100644
index 000000000000..99de4100ca68
--- /dev/null
+++ b/frontend/pages/hosts/details/ProfileStatusIndicator/index.ts
@@ -0,0 +1 @@
+export { default } from "./ProfileStatusIndicator";
diff --git a/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx b/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx
index f18194844c59..45be0eaba57b 100644
--- a/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx
+++ b/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx
@@ -1,7 +1,12 @@
import React from "react";
-
import ReactTooltip from "react-tooltip";
-import { IHostMacMdmProfile, BootstrapPackageStatus } from "interfaces/mdm";
+
+import {
+ IHostMdmProfile,
+ BootstrapPackageStatus,
+ isWindowsDiskEncryptionStatus,
+} from "interfaces/mdm";
+import { IOSSettings } from "interfaces/host";
import getHostStatusTooltipText from "pages/hosts/helpers";
import TooltipWrapper from "components/TooltipWrapper";
@@ -9,6 +14,7 @@ import Button from "components/buttons/Button";
import Icon from "components/Icon/Icon";
import DiskSpaceGraph from "components/DiskSpaceGraph";
import HumanTimeDiffWithDateTip from "components/HumanTimeDiffWithDateTip";
+import PremiumFeatureIconWithTooltip from "components/PremiumFeatureIconWithTooltip";
import {
getHostDiskEncryptionTooltipMessage,
humanHostMemory,
@@ -16,10 +22,11 @@ import {
} from "utilities/helpers";
import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants";
import StatusIndicator from "components/StatusIndicator";
-import PremiumFeatureIconWithTooltip from "components/PremiumFeatureIconWithTooltip";
+
import MacSettingsIndicator from "./MacSettingsIndicator";
import HostSummaryIndicator from "./HostSummaryIndicator";
import BootstrapPackageIndicator from "./BootstrapPackageIndicator/BootstrapPackageIndicator";
+import { generateWinDiskEncryptionProfile } from "../../helpers";
const baseClass = "host-summary";
@@ -38,7 +45,7 @@ interface IHostSummaryProps {
toggleOSPolicyModal?: () => void;
toggleMacSettingsModal?: () => void;
toggleBootstrapPackageModal?: () => void;
- hostMdmProfiles?: IHostMacMdmProfile[];
+ hostMdmProfiles?: IHostMdmProfile[];
mdmName?: string;
showRefetchSpinner: boolean;
onRefetchHost: (
@@ -46,6 +53,7 @@ interface IHostSummaryProps {
) => void;
renderActionButtons: () => JSX.Element | null;
deviceUser?: boolean;
+ osSettings?: IOSSettings;
}
const HostSummary = ({
@@ -64,8 +72,9 @@ const HostSummary = ({
onRefetchHost,
renderActionButtons,
deviceUser,
+ osSettings,
}: IHostSummaryProps): JSX.Element => {
- const { status, id, platform } = titleData;
+ const { status, platform } = titleData;
const renderRefetch = () => {
const isOnline = titleData.status === "online";
@@ -179,6 +188,22 @@ const HostSummary = ({
};
const renderSummary = () => {
+ // for windows hosts we have to manually add a profile for disk encryption
+ // as this is not currently included in the `profiles` value from the API
+ // response for windows hosts.
+ if (
+ platform === "windows" &&
+ osSettings?.disk_encryption?.status &&
+ isWindowsDiskEncryptionStatus(osSettings.disk_encryption.status)
+ ) {
+ const winDiskEncryptionProfile: IHostMdmProfile = generateWinDiskEncryptionProfile(
+ osSettings.disk_encryption.status
+ );
+ hostMdmProfiles = hostMdmProfiles
+ ? [...hostMdmProfiles, winDiskEncryptionProfile]
+ : [winDiskEncryptionProfile];
+ }
+
return (
@@ -198,12 +223,15 @@ const HostSummary = ({
{isPremiumTier && renderHostTeam()}
- {platform === "darwin" &&
+ {/* Rendering of OS Settings data */}
+ {(platform === "darwin" || platform === "windows") &&
isPremiumTier &&
- mdmName === "Fleet" && // show if 1 - host is enrolled in Fleet MDM, and
+ // TODO: API INTEGRATION: change this when we figure out why the API is
+ // returning "Fleet" or "FleetDM" for the MDM name.
+ mdmName?.includes("Fleet") && // show if 1 - host is enrolled in Fleet MDM, and
hostMdmProfiles &&
hostMdmProfiles.length > 0 && ( // 2 - host has at least one setting (profile) enforced
-
+ {
const statuses = hostMacSettings.map((setting) => setting.status);
if (statuses.includes("failed")) {
@@ -68,7 +68,7 @@ const getMacProfileStatus = (
};
interface IMacSettingsIndicatorProps {
- profiles: IHostMacMdmProfile[];
+ profiles: IHostMdmProfile[];
onClick?: () => void;
}
const MacSettingsIndicator = ({
diff --git a/frontend/pages/hosts/details/cards/Policies/HostPoliciesTable/PolicyFailingCount/PolicyFailingCount.tsx b/frontend/pages/hosts/details/cards/Policies/HostPoliciesTable/PolicyFailingCount/PolicyFailingCount.tsx
index ecb1f1b7c5f1..24a184a0d12b 100644
--- a/frontend/pages/hosts/details/cards/Policies/HostPoliciesTable/PolicyFailingCount/PolicyFailingCount.tsx
+++ b/frontend/pages/hosts/details/cards/Policies/HostPoliciesTable/PolicyFailingCount/PolicyFailingCount.tsx
@@ -2,6 +2,7 @@ import { IHostPolicy } from "interfaces/policy";
import React from "react";
import Icon from "components/Icon/Icon";
+import InfoBanner from "components/InfoBanner";
const baseClass = "policy-failing-count";
@@ -18,7 +19,7 @@ const PolicyFailingCount = ({
}, 0);
return failCount ? (
-
+
This device is failing
@@ -27,10 +28,10 @@ const PolicyFailingCount = ({
Click a policy below to see if there are steps you can take to resolve
the issue
- {failCount > 1 ? "s" : ""}.{" "}
+ {failCount > 1 ? "s" : ""}.
{deviceUser && " Once resolved, click “Refetch” above to confirm."}