Add disk_encryption option to config and team YAML (#10185)
This commit is contained in:
@@ -38,7 +38,7 @@ CREATE TABLE `app_config_json` (
|
||||
UNIQUE KEY `id` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
INSERT INTO `app_config_json` VALUES (1,'{\"mdm\": {\"macos_updates\": {\"deadline\": \"\", \"minimum_version\": \"\"}, \"apple_bm_default_team\": \"\", \"apple_bm_terms_expired\": false, \"enabled_and_configured\": false}, \"features\": {\"enable_host_users\": true, \"enable_software_inventory\": false}, \"org_info\": {\"org_name\": \"\", \"org_logo_url\": \"\"}, \"integrations\": {\"jira\": null, \"zendesk\": null}, \"sso_settings\": {\"idp_name\": \"\", \"metadata\": \"\", \"entity_id\": \"\", \"enable_sso\": false, \"issuer_uri\": \"\", \"metadata_url\": \"\", \"idp_image_url\": \"\", \"enable_sso_idp_login\": false, \"enable_jit_provisioning\": false}, \"agent_options\": {\"config\": {\"options\": {\"logger_plugin\": \"tls\", \"pack_delimiter\": \"/\", \"logger_tls_period\": 10, \"distributed_plugin\": \"tls\", \"disable_distributed\": false, \"logger_tls_endpoint\": \"/api/osquery/log\", \"distributed_interval\": 10, \"distributed_tls_max_attempts\": 3}, \"decorators\": {\"load\": [\"SELECT uuid AS host_uuid FROM system_info;\", \"SELECT hostname AS hostname FROM system_info;\"]}}, \"overrides\": {}}, \"fleet_desktop\": {\"transparency_url\": \"\"}, \"smtp_settings\": {\"port\": 587, \"domain\": \"\", \"server\": \"\", \"password\": \"\", \"user_name\": \"\", \"configured\": false, \"enable_smtp\": false, \"enable_ssl_tls\": true, \"sender_address\": \"\", \"enable_start_tls\": true, \"verify_ssl_certs\": true, \"authentication_type\": \"0\", \"authentication_method\": \"0\"}, \"macos_settings\": {\"custom_settings\": null}, \"server_settings\": {\"server_url\": \"\", \"enable_analytics\": false, \"deferred_save_host\": false, \"live_query_disabled\": false}, \"webhook_settings\": {\"interval\": \"0s\", \"host_status_webhook\": {\"days_count\": 0, \"destination_url\": \"\", \"host_percentage\": 0, \"enable_host_status_webhook\": false}, \"vulnerabilities_webhook\": {\"destination_url\": \"\", \"host_batch_size\": 0, \"enable_vulnerabilities_webhook\": false}, \"failing_policies_webhook\": {\"policy_ids\": null, \"destination_url\": \"\", \"host_batch_size\": 0, \"enable_failing_policies_webhook\": false}}, \"host_expiry_settings\": {\"host_expiry_window\": 0, \"host_expiry_enabled\": false}, \"vulnerability_settings\": {\"databases_path\": \"\"}}','2020-01-01 01:01:01','2020-01-01 01:01:01');
|
||||
INSERT INTO `app_config_json` VALUES (1,'{\"mdm\": {\"macos_updates\": {\"deadline\": \"\", \"minimum_version\": \"\"}, \"macos_settings\": {\"custom_settings\": null, \"enable_disk_encryption\": false}, \"apple_bm_default_team\": \"\", \"apple_bm_terms_expired\": false, \"enabled_and_configured\": false}, \"features\": {\"enable_host_users\": true, \"enable_software_inventory\": false}, \"org_info\": {\"org_name\": \"\", \"org_logo_url\": \"\"}, \"integrations\": {\"jira\": null, \"zendesk\": null}, \"sso_settings\": {\"idp_name\": \"\", \"metadata\": \"\", \"entity_id\": \"\", \"enable_sso\": false, \"issuer_uri\": \"\", \"metadata_url\": \"\", \"idp_image_url\": \"\", \"enable_sso_idp_login\": false, \"enable_jit_provisioning\": false}, \"agent_options\": {\"config\": {\"options\": {\"logger_plugin\": \"tls\", \"pack_delimiter\": \"/\", \"logger_tls_period\": 10, \"distributed_plugin\": \"tls\", \"disable_distributed\": false, \"logger_tls_endpoint\": \"/api/osquery/log\", \"distributed_interval\": 10, \"distributed_tls_max_attempts\": 3}, \"decorators\": {\"load\": [\"SELECT uuid AS host_uuid FROM system_info;\", \"SELECT hostname AS hostname FROM system_info;\"]}}, \"overrides\": {}}, \"fleet_desktop\": {\"transparency_url\": \"\"}, \"smtp_settings\": {\"port\": 587, \"domain\": \"\", \"server\": \"\", \"password\": \"\", \"user_name\": \"\", \"configured\": false, \"enable_smtp\": false, \"enable_ssl_tls\": true, \"sender_address\": \"\", \"enable_start_tls\": true, \"verify_ssl_certs\": true, \"authentication_type\": \"0\", \"authentication_method\": \"0\"}, \"server_settings\": {\"server_url\": \"\", \"enable_analytics\": false, \"deferred_save_host\": false, \"live_query_disabled\": false}, \"webhook_settings\": {\"interval\": \"0s\", \"host_status_webhook\": {\"days_count\": 0, \"destination_url\": \"\", \"host_percentage\": 0, \"enable_host_status_webhook\": false}, \"vulnerabilities_webhook\": {\"destination_url\": \"\", \"host_batch_size\": 0, \"enable_vulnerabilities_webhook\": false}, \"failing_policies_webhook\": {\"policy_ids\": null, \"destination_url\": \"\", \"host_batch_size\": 0, \"enable_failing_policies_webhook\": false}}, \"host_expiry_settings\": {\"host_expiry_window\": 0, \"host_expiry_enabled\": false}, \"vulnerability_settings\": {\"databases_path\": \"\"}}','2020-01-01 01:01:01','2020-01-01 01:01:01');
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `carve_blocks` (
|
||||
|
||||
+47
-19
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"time"
|
||||
@@ -118,7 +119,8 @@ type MDM struct {
|
||||
// the server starts.
|
||||
EnabledAndConfigured bool `json:"enabled_and_configured"`
|
||||
|
||||
MacOSUpdates MacOSUpdates `json:"macos_updates"`
|
||||
MacOSUpdates MacOSUpdates `json:"macos_updates"`
|
||||
MacOSSettings MacOSSettings `json:"macos_settings"`
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// WARNING: If you add to this struct make sure it's taken into
|
||||
@@ -166,35 +168,64 @@ func (m MacOSUpdates) Validate() error {
|
||||
|
||||
// MacOSSettings contains settings specific to macOS.
|
||||
type MacOSSettings struct {
|
||||
CustomSettings []string `json:"custom_settings"`
|
||||
CustomSettings []string `json:"custom_settings"`
|
||||
EnableDiskEncryption bool `json:"enable_disk_encryption"`
|
||||
|
||||
// NOTE: make sure to update the ToMap/FromMap methods when adding/updating fields.
|
||||
}
|
||||
|
||||
func (s MacOSSettings) ToMap() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"custom_settings": s.CustomSettings,
|
||||
"custom_settings": s.CustomSettings,
|
||||
"enable_disk_encryption": s.EnableDiskEncryption,
|
||||
}
|
||||
}
|
||||
|
||||
// CustomSettingsFromMap sets the custom settings field from the provided map,
|
||||
// which is the map type from the ApplyTeams spec struct. It returns true if
|
||||
// the custom settings were set from the map, false if they were left
|
||||
// unchanged.
|
||||
func (s *MacOSSettings) CustomSettingsFromMap(m map[string]interface{}) bool {
|
||||
// FromMap sets the macOS settings from the provided map, which is the map type
|
||||
// from the ApplyTeams spec struct. It returns a map of fields that were set in
|
||||
// the map (ie. the key was present even if empty) or an error. If the
|
||||
// operation updates an existing team, it should be called on the existing
|
||||
// MacOSSettings so that its fields are replaced only if present in the map.
|
||||
func (s *MacOSSettings) FromMap(m map[string]interface{}) (map[string]bool, error) {
|
||||
set := make(map[string]bool)
|
||||
|
||||
if v, ok := m["custom_settings"]; ok {
|
||||
set["custom_settings"] = true
|
||||
|
||||
vals, ok := v.([]interface{})
|
||||
if v == nil || ok {
|
||||
strs := make([]string, 0, len(vals))
|
||||
for _, v := range vals {
|
||||
s, ok := v.(string)
|
||||
if ok && s != "" {
|
||||
strs = append(strs, s)
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
// error, must be a []string
|
||||
return nil, &json.UnmarshalTypeError{
|
||||
Value: fmt.Sprintf("%T", v),
|
||||
Type: reflect.TypeOf(s.CustomSettings),
|
||||
Field: "macos_settings.custom_settings",
|
||||
}
|
||||
}
|
||||
strs = append(strs, str)
|
||||
}
|
||||
s.CustomSettings = strs
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
if v, ok := m["enable_disk_encryption"]; ok {
|
||||
set["enable_disk_encryption"] = true
|
||||
b, ok := v.(bool)
|
||||
if !ok {
|
||||
// error, must be a bool
|
||||
return nil, &json.UnmarshalTypeError{
|
||||
Value: fmt.Sprintf("%T", v),
|
||||
Type: reflect.TypeOf(s.EnableDiskEncryption),
|
||||
Field: "macos_settings.enable_disk_encryption",
|
||||
}
|
||||
}
|
||||
s.EnableDiskEncryption = b
|
||||
}
|
||||
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// AppConfig holds server configuration that can be changed via the API.
|
||||
@@ -224,8 +255,6 @@ type AppConfig struct {
|
||||
|
||||
MDM MDM `json:"mdm"`
|
||||
|
||||
MacOSSettings MacOSSettings `json:"macos_settings"`
|
||||
|
||||
// when true, strictDecoding causes the UnmarshalJSON method to return an
|
||||
// error if there are unknown fields in the raw JSON.
|
||||
strictDecoding bool
|
||||
@@ -284,7 +313,6 @@ func (c *AppConfig) Copy() *AppConfig {
|
||||
// SSOSettings: nothing needs cloning
|
||||
// FleetDesktop: nothing needs cloning
|
||||
// VulnerabilitySettings: nothing needs cloning
|
||||
// MDM: nothing needs cloning
|
||||
|
||||
if c.WebhookSettings.FailingPoliciesWebhook.PolicyIDs != nil {
|
||||
clone.WebhookSettings.FailingPoliciesWebhook.PolicyIDs = make([]uint, len(c.WebhookSettings.FailingPoliciesWebhook.PolicyIDs))
|
||||
@@ -305,9 +333,9 @@ func (c *AppConfig) Copy() *AppConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if c.MacOSSettings.CustomSettings != nil {
|
||||
clone.MacOSSettings.CustomSettings = make([]string, len(c.MacOSSettings.CustomSettings))
|
||||
copy(clone.MacOSSettings.CustomSettings, c.MacOSSettings.CustomSettings)
|
||||
if c.MDM.MacOSSettings.CustomSettings != nil {
|
||||
clone.MDM.MacOSSettings.CustomSettings = make([]string, len(c.MDM.MacOSSettings.CustomSettings))
|
||||
copy(clone.MDM.MacOSSettings.CustomSettings, c.MDM.MacOSSettings.CustomSettings)
|
||||
}
|
||||
|
||||
return &clone
|
||||
|
||||
+24
-15
@@ -125,7 +125,6 @@ type TeamConfig struct {
|
||||
Integrations TeamIntegrations `json:"integrations"`
|
||||
Features Features `json:"features"`
|
||||
MDM TeamMDM `json:"mdm"`
|
||||
MacOSSettings MacOSSettings `json:"macos_settings"`
|
||||
}
|
||||
|
||||
type TeamWebhookSettings struct {
|
||||
@@ -133,7 +132,22 @@ type TeamWebhookSettings struct {
|
||||
}
|
||||
|
||||
type TeamMDM struct {
|
||||
MacOSUpdates MacOSUpdates `json:"macos_updates"`
|
||||
MacOSSettings MacOSSettings `json:"macos_settings"`
|
||||
// NOTE: TeamSpecMDM must be kept in sync with TeamMDM.
|
||||
}
|
||||
|
||||
type TeamSpecMDM struct {
|
||||
MacOSUpdates MacOSUpdates `json:"macos_updates"`
|
||||
|
||||
// A map is used for the macos settings so that we can easily detect if its
|
||||
// sub-keys were provided or not in an "apply" call. E.g. if the
|
||||
// custom_settings key is specified but empty, then we need to clear the
|
||||
// value, but if it isn't provided, we need to leave the existing value
|
||||
// unmodified.
|
||||
MacOSSettings map[string]interface{} `json:"macos_settings"`
|
||||
|
||||
// NOTE: TeamMDM must be kept in sync with TeamSpecMDM.
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface
|
||||
@@ -271,14 +285,7 @@ type TeamSpec struct {
|
||||
|
||||
Secrets []EnrollSecret `json:"secrets,omitempty"`
|
||||
Features *json.RawMessage `json:"features"`
|
||||
MDM TeamMDM `json:"mdm"`
|
||||
|
||||
// A map is used for the macos settings so that we can easily detect if its
|
||||
// sub-keys were provided or not in an "apply" call. E.g. if the
|
||||
// custom_settings key is specified but empty, then we need to clear the
|
||||
// value, but if it isn't provided, we need to leave the existing value
|
||||
// unmodified.
|
||||
MacOSSettings map[string]interface{} `json:"macos_settings"`
|
||||
MDM TeamSpecMDM `json:"mdm"`
|
||||
}
|
||||
|
||||
// TeamSpecFromTeam returns a TeamSpec constructed from the given Team.
|
||||
@@ -300,12 +307,14 @@ func TeamSpecFromTeam(t *Team) (*TeamSpec, error) {
|
||||
agentOptions = *t.Config.AgentOptions
|
||||
}
|
||||
|
||||
var mdmSpec TeamSpecMDM
|
||||
mdmSpec.MacOSUpdates = t.Config.MDM.MacOSUpdates
|
||||
mdmSpec.MacOSSettings = t.Config.MDM.MacOSSettings.ToMap()
|
||||
return &TeamSpec{
|
||||
Name: t.Name,
|
||||
AgentOptions: agentOptions,
|
||||
Features: &featuresJSON,
|
||||
Secrets: secrets,
|
||||
MDM: t.Config.MDM,
|
||||
MacOSSettings: t.Config.MacOSSettings.ToMap(),
|
||||
Name: t.Name,
|
||||
AgentOptions: agentOptions,
|
||||
Features: &featuresJSON,
|
||||
Secrets: secrets,
|
||||
MDM: mdmSpec,
|
||||
}, nil
|
||||
}
|
||||
|
||||
+21
-19
@@ -137,7 +137,6 @@ func getAppConfigEndpoint(ctx context.Context, request interface{}, svc fleet.Se
|
||||
WebhookSettings: config.WebhookSettings,
|
||||
Integrations: config.Integrations,
|
||||
MDM: config.MDM,
|
||||
MacOSSettings: config.MacOSSettings,
|
||||
},
|
||||
appConfigResponseFields: appConfigResponseFields{
|
||||
UpdateInterval: updateIntervalConfig,
|
||||
@@ -248,10 +247,6 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle
|
||||
}
|
||||
oldAppConfig := appConfig.Copy()
|
||||
|
||||
// keep this original values, as they cannot be modified via this request.
|
||||
origAppleBMTerms := oldAppConfig.MDM.AppleBMTermsExpired
|
||||
origMDMEnabled := oldAppConfig.MDM.EnabledAndConfigured
|
||||
|
||||
license, err := svc.License(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -273,24 +268,12 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle
|
||||
return nil, ctxerr.Wrap(ctx, err, "modify AppConfig")
|
||||
}
|
||||
|
||||
// TODO(mna): this ports the validations from the old validationMiddleware
|
||||
// correctly, but this could be optimized so that we don't unmarshal the
|
||||
// incoming bytes twice.
|
||||
invalid := &fleet.InvalidArgumentError{}
|
||||
var newAppConfig fleet.AppConfig
|
||||
if err := json.Unmarshal(p, &newAppConfig); err != nil {
|
||||
return nil, ctxerr.Wrap(ctx, &fleet.BadRequestError{Message: err.Error()})
|
||||
}
|
||||
|
||||
if len(newAppConfig.MacOSSettings.CustomSettings) != 0 {
|
||||
if !svc.config.MDMApple.Enable {
|
||||
// TODO(mna): eventually we should detect the minimum config required for
|
||||
// this to be allowed, probably just SCEP/APNs?
|
||||
invalid.Append("macos_settings.custom_settings", "cannot set custom settings: Fleet MDM is not enabled")
|
||||
return nil, ctxerr.Wrap(ctx, invalid)
|
||||
}
|
||||
}
|
||||
|
||||
if newAppConfig.FleetDesktop.TransparencyURL != "" {
|
||||
if license.Tier != "premium" {
|
||||
invalid.Append("transparency_url", ErrMissingLicense.Error())
|
||||
@@ -358,8 +341,8 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle
|
||||
// payload we don't return an error in this case because it would
|
||||
// prevent using the output of fleetctl get config as input to fleetctl
|
||||
// apply or this endpoint.
|
||||
appConfig.MDM.AppleBMTermsExpired = origAppleBMTerms
|
||||
appConfig.MDM.EnabledAndConfigured = origMDMEnabled
|
||||
appConfig.MDM.AppleBMTermsExpired = oldAppConfig.MDM.AppleBMTermsExpired
|
||||
appConfig.MDM.EnabledAndConfigured = oldAppConfig.MDM.EnabledAndConfigured
|
||||
|
||||
// do not send a test email in dry-run mode, so this is a good place to stop
|
||||
// (we also delete the removed integrations after that, which we don't want
|
||||
@@ -470,6 +453,25 @@ func (svc *Service) validateMDM(
|
||||
mdm *fleet.MDM,
|
||||
invalid *fleet.InvalidArgumentError,
|
||||
) {
|
||||
if mdm.MacOSSettings.EnableDiskEncryption && !license.IsPremium() {
|
||||
invalid.Append("macos_settings.enable_disk_encryption", ErrMissingLicense.Error())
|
||||
}
|
||||
|
||||
if !svc.config.MDMApple.Enable {
|
||||
// TODO(mna): eventually we should detect the minimum config required for
|
||||
// this to be allowed, probably just SCEP/APNs?
|
||||
|
||||
if len(mdm.MacOSSettings.CustomSettings) != 0 {
|
||||
invalid.Append("macos_settings.custom_settings",
|
||||
`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.`)
|
||||
}
|
||||
|
||||
if mdm.MacOSSettings.EnableDiskEncryption {
|
||||
invalid.Append("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.`)
|
||||
}
|
||||
}
|
||||
|
||||
if name := mdm.AppleBMDefaultTeam; name != "" && name != oldMdm.AppleBMDefaultTeam {
|
||||
if !license.IsPremium() {
|
||||
invalid.Append("mdm.apple_bm_default_team", ErrMissingLicense.Error())
|
||||
|
||||
@@ -393,7 +393,11 @@ func extractAppCfgMacOSCustomSettings(appCfg interface{}) []string {
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
mos, ok := asMap["macos_settings"].(map[string]interface{})
|
||||
mmdm, ok := asMap["mdm"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
mos, ok := mmdm["macos_settings"].(map[string]interface{})
|
||||
if !ok || mos == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -426,21 +430,23 @@ func extractTmSpecsMacOSCustomSettings(tmSpecs []json.RawMessage) map[string][]s
|
||||
var m map[string][]string
|
||||
for _, tm := range tmSpecs {
|
||||
var spec struct {
|
||||
Name string `json:"name"`
|
||||
MacOSSettings struct {
|
||||
CustomSettings json.RawMessage `json:"custom_settings"`
|
||||
} `json:"macos_settings"`
|
||||
Name string `json:"name"`
|
||||
MDM struct {
|
||||
MacOSSettings struct {
|
||||
CustomSettings json.RawMessage `json:"custom_settings"`
|
||||
} `json:"macos_settings"`
|
||||
} `json:"mdm"`
|
||||
}
|
||||
if err := json.Unmarshal(tm, &spec); err != nil {
|
||||
// ignore, this will fail in the call to apply team specs
|
||||
continue
|
||||
}
|
||||
if spec.Name != "" && len(spec.MacOSSettings.CustomSettings) > 0 {
|
||||
if spec.Name != "" && len(spec.MDM.MacOSSettings.CustomSettings) > 0 {
|
||||
if m == nil {
|
||||
m = make(map[string][]string)
|
||||
}
|
||||
var cs []string
|
||||
if err := json.Unmarshal(spec.MacOSSettings.CustomSettings, &cs); err != nil {
|
||||
if err := json.Unmarshal(spec.MDM.MacOSSettings.CustomSettings, &cs); err != nil {
|
||||
// ignore, will fail in apply team specs call
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ kind: config
|
||||
spec:
|
||||
org_info:
|
||||
org_name: "Fleet"
|
||||
macos_settings:
|
||||
mdm:
|
||||
macos_settings:
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
@@ -42,8 +43,9 @@ kind: config
|
||||
spec:
|
||||
org_info:
|
||||
org_name: "Fleet"
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
mdm:
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
`,
|
||||
[]string{},
|
||||
},
|
||||
@@ -55,10 +57,11 @@ kind: config
|
||||
spec:
|
||||
org_info:
|
||||
org_name: "Fleet"
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- "b"
|
||||
mdm:
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- "b"
|
||||
`,
|
||||
[]string{"a", "b"},
|
||||
},
|
||||
@@ -70,12 +73,13 @@ kind: config
|
||||
spec:
|
||||
org_info:
|
||||
org_name: "Fleet"
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- ""
|
||||
- 4
|
||||
- "c"
|
||||
mdm:
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- ""
|
||||
- 4
|
||||
- "c"
|
||||
`,
|
||||
[]string{"a", "c"},
|
||||
},
|
||||
@@ -116,14 +120,16 @@ kind: team
|
||||
spec:
|
||||
team:
|
||||
name: Fleet
|
||||
macos_settings:
|
||||
mdm:
|
||||
macos_settings:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: team
|
||||
spec:
|
||||
team:
|
||||
name: Fleet2
|
||||
macos_settings:
|
||||
mdm:
|
||||
macos_settings:
|
||||
`,
|
||||
nil,
|
||||
},
|
||||
@@ -135,16 +141,18 @@ kind: team
|
||||
spec:
|
||||
team:
|
||||
name: "Fleet"
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
mdm:
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: team
|
||||
spec:
|
||||
team:
|
||||
name: "Fleet2"
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
mdm:
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
`,
|
||||
map[string][]string{"Fleet": {}, "Fleet2": {}},
|
||||
},
|
||||
@@ -156,10 +164,11 @@ kind: team
|
||||
spec:
|
||||
team:
|
||||
name: "Fleet"
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- "b"
|
||||
mdm:
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- "b"
|
||||
`,
|
||||
map[string][]string{"Fleet": {"a", "b"}},
|
||||
},
|
||||
@@ -171,12 +180,13 @@ kind: team
|
||||
spec:
|
||||
team:
|
||||
name: "Fleet"
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- ""
|
||||
- 42
|
||||
- "c"
|
||||
mdm:
|
||||
macos_settings:
|
||||
custom_settings:
|
||||
- "a"
|
||||
- ""
|
||||
- 42
|
||||
- "c"
|
||||
`,
|
||||
map[string][]string{},
|
||||
},
|
||||
|
||||
@@ -4814,10 +4814,17 @@ func (s *integrationTestSuite) TestAppConfig() {
|
||||
|
||||
// set the macos custom settings fields, fails due to MDM not configured
|
||||
res := s.Do("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"macos_settings": { "custom_settings": ["foo", "bar"] }
|
||||
"mdm": { "macos_settings": { "custom_settings": ["foo", "bar"] } }
|
||||
}`), http.StatusUnprocessableEntity)
|
||||
errMsg := extractServerErrorText(res.Body)
|
||||
assert.Contains(t, errMsg, "Fleet MDM is not enabled")
|
||||
assert.Contains(t, errMsg, "Couldn't update macos_settings because MDM features aren't turned on in Fleet.")
|
||||
|
||||
// set the macos disk encryption field, fails due to license
|
||||
res = s.Do("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"mdm": { "macos_settings": { "enable_disk_encryption": true } }
|
||||
}`), http.StatusUnprocessableEntity)
|
||||
errMsg = extractServerErrorText(res.Body)
|
||||
assert.Contains(t, errMsg, "missing or invalid license")
|
||||
|
||||
// try to set the apple bm default team, which is premium only
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
|
||||
@@ -80,7 +80,7 @@ func (s *integrationEnterpriseTestSuite) TestTeamSpecs() {
|
||||
// updates a team, no secret is provided so it will keep the one generated
|
||||
// automatically when the team was created.
|
||||
agentOpts := json.RawMessage(`{"config": {"views": {"foo": "bar"}}, "overrides": {"platforms": {"darwin": {"views": {"bar": "qux"}}}}}`)
|
||||
mdm := fleet.TeamMDM{
|
||||
mdm := fleet.TeamSpecMDM{
|
||||
MacOSUpdates: fleet.MacOSUpdates{
|
||||
MinimumVersion: "10.15.0",
|
||||
Deadline: "2021-01-01",
|
||||
@@ -112,7 +112,12 @@ func (s *integrationEnterpriseTestSuite) TestTeamSpecs() {
|
||||
EnableSoftwareInventory: false,
|
||||
AdditionalQueries: ptr.RawMessage(json.RawMessage(`{"foo": "bar"}`)),
|
||||
}, team.Config.Features)
|
||||
require.Equal(t, mdm, team.Config.MDM)
|
||||
require.Equal(t, fleet.TeamMDM{
|
||||
MacOSUpdates: fleet.MacOSUpdates{
|
||||
MinimumVersion: "10.15.0",
|
||||
Deadline: "2021-01-01",
|
||||
},
|
||||
}, team.Config.MDM)
|
||||
|
||||
// an activity was created for team spec applied
|
||||
s.lastActivityMatches(fleet.ActivityTypeAppliedSpecTeam{}.ActivityName(), fmt.Sprintf(`{"teams": [{"id": %d, "name": %q}]}`, team.ID, team.Name), 0)
|
||||
@@ -141,10 +146,20 @@ func (s *integrationEnterpriseTestSuite) TestTeamSpecs() {
|
||||
|
||||
// dry-run with valid agent options and custom macos settings
|
||||
agentOpts = json.RawMessage(`{"config": {"views": {"foo": "qux"}}}`)
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: teamName, AgentOptions: agentOpts, MacOSSettings: map[string]interface{}{"custom_settings": []string{"foo", "bar"}}}}}
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: teamName, AgentOptions: agentOpts, MDM: fleet.TeamSpecMDM{MacOSSettings: map[string]interface{}{"custom_settings": []string{"foo", "bar"}}}}}}
|
||||
res = s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusUnprocessableEntity, "dry_run", "true")
|
||||
errMsg := extractServerErrorText(res.Body)
|
||||
require.Contains(t, errMsg, "Fleet MDM is not enabled")
|
||||
require.Contains(t, errMsg, "Couldn't update macos_settings because MDM features aren't turned on in Fleet.")
|
||||
|
||||
// dry-run with macos disk encryption set to false, no error
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: teamName, MDM: fleet.TeamSpecMDM{MacOSSettings: map[string]interface{}{"enable_disk_encryption": false}}}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK, "dry_run", "true")
|
||||
|
||||
// dry-run with macos disk encryption set to true
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: teamName, MDM: fleet.TeamSpecMDM{MacOSSettings: map[string]interface{}{"enable_disk_encryption": true}}}}}
|
||||
res = s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusUnprocessableEntity, "dry_run", "true")
|
||||
errMsg = extractServerErrorText(res.Body)
|
||||
require.Contains(t, errMsg, "Couldn't update macos_settings because MDM features aren't turned on in Fleet.")
|
||||
|
||||
// dry-run with valid agent options only
|
||||
agentOpts = json.RawMessage(`{"config": {"views": {"foo": "qux"}}}`)
|
||||
@@ -154,7 +169,8 @@ func (s *integrationEnterpriseTestSuite) TestTeamSpecs() {
|
||||
team, err = s.ds.TeamByName(context.Background(), teamName)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, string(*team.Config.AgentOptions), `"foo": "bar"`) // unchanged
|
||||
require.Empty(t, team.Config.MacOSSettings.CustomSettings) // unchanged
|
||||
require.Empty(t, team.Config.MDM.MacOSSettings.CustomSettings) // unchanged
|
||||
require.False(t, team.Config.MDM.MacOSSettings.EnableDiskEncryption) // unchanged
|
||||
|
||||
// apply without agent options specified
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{Name: teamName}}}
|
||||
|
||||
@@ -1114,36 +1114,78 @@ func (s *integrationMDMTestSuite) TestAppConfigMDMAppleProfiles() {
|
||||
// set the macos custom settings fields
|
||||
acResp := appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"macos_settings": { "custom_settings": ["foo", "bar"] }
|
||||
"mdm": { "macos_settings": { "custom_settings": ["foo", "bar"] } }
|
||||
}`), http.StatusOK, &acResp)
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MacOSSettings.CustomSettings)
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// check that they are returned by a GET /config
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("GET", "/api/latest/fleet/config", nil, http.StatusOK, &acResp)
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MacOSSettings.CustomSettings)
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// patch without specifying the macos custom settings fields, should not remove them
|
||||
// patch without specifying the macos custom settings fields and an unrelated
|
||||
// field, should not remove them
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"macos_settings": {}
|
||||
"mdm": { "macos_settings": {"enable_disk_encryption": true} }
|
||||
}`), http.StatusOK, &acResp)
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MacOSSettings.CustomSettings)
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// patch with explicitly empty macos custom settings fields, would remove
|
||||
// them but this is a dry-run
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"macos_settings": {"custom_settings": null}
|
||||
"mdm": { "macos_settings": { "custom_settings": null } }
|
||||
}`), http.StatusOK, &acResp, "dry_run", "true")
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MacOSSettings.CustomSettings)
|
||||
assert.Equal(t, []string{"foo", "bar"}, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// patch with explicitly empty macos custom settings fields, removes them
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"macos_settings": {"custom_settings": null}
|
||||
"mdm": { "macos_settings": { "custom_settings": null } }
|
||||
}`), http.StatusOK, &acResp)
|
||||
assert.Empty(t, acResp.MacOSSettings.CustomSettings)
|
||||
assert.Empty(t, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
}
|
||||
|
||||
func (s *integrationMDMTestSuite) TestAppConfigMDMAppleDiskEncryption() {
|
||||
t := s.T()
|
||||
|
||||
// set the macos disk encryption field
|
||||
acResp := appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"mdm": { "macos_settings": { "enable_disk_encryption": true } }
|
||||
}`), http.StatusOK, &acResp)
|
||||
assert.True(t, acResp.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
|
||||
// check that they are returned by a GET /config
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("GET", "/api/latest/fleet/config", nil, http.StatusOK, &acResp)
|
||||
assert.True(t, acResp.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
|
||||
// patch without specifying the macos disk encryption and an unrelated field,
|
||||
// should not alter it
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"mdm": { "macos_settings": {"custom_settings": ["a"]} }
|
||||
}`), http.StatusOK, &acResp)
|
||||
assert.True(t, acResp.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
assert.Equal(t, []string{"a"}, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// patch with false, would reset it but this is a dry-run
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"mdm": { "macos_settings": { "enable_disk_encryption": false } }
|
||||
}`), http.StatusOK, &acResp, "dry_run", "true")
|
||||
assert.True(t, acResp.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
assert.Equal(t, []string{"a"}, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// patch with false, resets it
|
||||
acResp = appConfigResponse{}
|
||||
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
|
||||
"mdm": { "macos_settings": { "enable_disk_encryption": false, "custom_settings": ["b"] } }
|
||||
}`), http.StatusOK, &acResp)
|
||||
assert.False(t, acResp.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
assert.Equal(t, []string{"b"}, acResp.MDM.MacOSSettings.CustomSettings)
|
||||
}
|
||||
|
||||
func (s *integrationMDMTestSuite) TestApplyTeamsMDMAppleProfiles() {
|
||||
@@ -1162,53 +1204,155 @@ func (s *integrationMDMTestSuite) TestApplyTeamsMDMAppleProfiles() {
|
||||
|
||||
// apply with custom macos settings
|
||||
teamSpecs := applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []string{"foo", "bar"}},
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []string{"foo", "bar"}},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
|
||||
// retrieving the team returns the custom macos settings
|
||||
var teamResp getTeamResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.Equal(t, []string{"foo", "bar"}, teamResp.Team.Config.MacOSSettings.CustomSettings)
|
||||
require.Equal(t, []string{"foo", "bar"}, teamResp.Team.Config.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// apply with invalid macos settings subfield should fail
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MacOSSettings: map[string]interface{}{"foo_bar": 123},
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"foo_bar": 123},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusBadRequest)
|
||||
res := s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusBadRequest)
|
||||
errMsg := extractServerErrorText(res.Body)
|
||||
assert.Contains(t, errMsg, `unsupported key provided: "foo_bar"`)
|
||||
|
||||
// apply without custom macos settings specified, should not replace existing settings
|
||||
// apply with some good and some bad macos settings subfield should fail
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MacOSSettings: map[string]interface{}{},
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []interface{}{"A", true}},
|
||||
},
|
||||
}}}
|
||||
res = s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusBadRequest)
|
||||
errMsg = extractServerErrorText(res.Body)
|
||||
assert.Contains(t, errMsg, `invalid value type at 'macos_settings.custom_settings': expected array of strings but got bool`)
|
||||
|
||||
// apply without custom macos settings specified and unrelated field, should
|
||||
// not replace existing settings
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"enable_disk_encryption": false},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
teamResp = getTeamResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.Equal(t, []string{"foo", "bar"}, teamResp.Team.Config.MacOSSettings.CustomSettings)
|
||||
require.Equal(t, []string{"foo", "bar"}, teamResp.Team.Config.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// apply with explicitly empty custom macos settings would clear the existing
|
||||
// settings, but dry-run
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []string{}},
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []string{}},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK, "dry_run", "true")
|
||||
teamResp = getTeamResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.Equal(t, []string{"foo", "bar"}, teamResp.Team.Config.MacOSSettings.CustomSettings)
|
||||
require.Equal(t, []string{"foo", "bar"}, teamResp.Team.Config.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// apply with explicitly empty custom macos settings clears the existing settings
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []string{}},
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []string{}},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
teamResp = getTeamResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.Equal(t, []string{}, teamResp.Team.Config.MacOSSettings.CustomSettings)
|
||||
require.Equal(t, []string{}, teamResp.Team.Config.MDM.MacOSSettings.CustomSettings)
|
||||
}
|
||||
|
||||
func (s *integrationMDMTestSuite) TestApplyTeamsMDMAppleDiskEncryption() {
|
||||
t := s.T()
|
||||
|
||||
// create a team through the service so it initializes the agent ops
|
||||
teamName := t.Name() + "team1"
|
||||
team := &fleet.Team{
|
||||
Name: teamName,
|
||||
Description: "desc team1",
|
||||
}
|
||||
var createTeamResp teamResponse
|
||||
s.DoJSON("POST", "/api/latest/fleet/teams", team, http.StatusOK, &createTeamResp)
|
||||
require.NotZero(t, createTeamResp.Team.ID)
|
||||
team = createTeamResp.Team
|
||||
|
||||
// apply with disk encryption
|
||||
teamSpecs := applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"enable_disk_encryption": true},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
|
||||
// retrieving the team returns the disk encryption setting
|
||||
var teamResp getTeamResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.True(t, teamResp.Team.Config.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
|
||||
// apply with invalid disk encryption value should fail
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"enable_disk_encryption": 123},
|
||||
},
|
||||
}}}
|
||||
res := s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusBadRequest)
|
||||
errMsg := extractServerErrorText(res.Body)
|
||||
assert.Contains(t, errMsg, `invalid value type at 'macos_settings.enable_disk_encryption': expected bool but got float64`)
|
||||
|
||||
// apply without disk encryption settings specified and unrelated field,
|
||||
// should not replace existing disk encryption
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"custom_settings": []string{"a"}},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
teamResp = getTeamResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.True(t, teamResp.Team.Config.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
require.Equal(t, []string{"a"}, teamResp.Team.Config.MDM.MacOSSettings.CustomSettings)
|
||||
|
||||
// apply with false would clear the existing setting, but dry-run
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"enable_disk_encryption": false},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK, "dry_run", "true")
|
||||
teamResp = getTeamResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.True(t, teamResp.Team.Config.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
|
||||
// apply with false clears the existing setting
|
||||
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
|
||||
Name: teamName,
|
||||
MDM: fleet.TeamSpecMDM{
|
||||
MacOSSettings: map[string]interface{}{"enable_disk_encryption": false},
|
||||
},
|
||||
}}}
|
||||
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
|
||||
teamResp = getTeamResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/teams/%d", team.ID), nil, http.StatusOK, &teamResp)
|
||||
require.False(t, teamResp.Team.Config.MDM.MacOSSettings.EnableDiskEncryption)
|
||||
}
|
||||
|
||||
func (s *integrationMDMTestSuite) TestBatchSetMDMAppleProfiles() {
|
||||
|
||||
@@ -193,7 +193,7 @@ func (req *applyTeamSpecsRequest) DecodeBody(ctx context.Context, r io.Reader) e
|
||||
// the MacOSSettings field must be validated separately, since it
|
||||
// JSON-decodes into a free-form map.
|
||||
for _, spec := range req.Specs {
|
||||
if spec == nil || spec.MacOSSettings == nil {
|
||||
if spec == nil || spec.MDM.MacOSSettings == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ func (req *applyTeamSpecsRequest) DecodeBody(ctx context.Context, r io.Reader) e
|
||||
validMap := macOSSettings.ToMap()
|
||||
|
||||
// the keys provided must be valid
|
||||
for k := range spec.MacOSSettings {
|
||||
for k := range spec.MDM.MacOSSettings {
|
||||
if _, ok := validMap[k]; !ok {
|
||||
return ctxerr.Wrap(ctx, fleet.NewUserMessageError(
|
||||
fmt.Errorf("json: unknown field %q", k),
|
||||
|
||||
Reference in New Issue
Block a user