diff --git a/changes/fleetctl-apply-to-fail-unknown-fields b/changes/fleetctl-apply-to-fail-unknown-fields new file mode 100644 index 0000000000..2c6b232d1b --- /dev/null +++ b/changes/fleetctl-apply-to-fail-unknown-fields @@ -0,0 +1 @@ +* Make `fleetctl apply` fail if there's an unknown field. diff --git a/cmd/fleetctl/apply_test.go b/cmd/fleetctl/apply_test.go index 84ec2fa996..a23227229c 100644 --- a/cmd/fleetctl/apply_test.go +++ b/cmd/fleetctl/apply_test.go @@ -234,3 +234,42 @@ spec: assert.True(t, savedAppConfig.HostSettings.EnableHostUsers) assert.True(t, savedAppConfig.HostSettings.EnableSoftwareInventory) } + +func TestApplyAppConfigUnknownFields(t *testing.T) { + _, ds := runServerWithMockedDS(t) + + ds.ListUsersFunc = func(ctx context.Context, opt fleet.UserListOptions) ([]*fleet.User, error) { + return userRoleSpecList, nil + } + + ds.UserByEmailFunc = func(ctx context.Context, email string) (*fleet.User, error) { + if email == "admin1@example.com" { + return userRoleSpecList[0], nil + } + return userRoleSpecList[1], nil + } + + ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) { + return &fleet.AppConfig{}, nil + } + + var savedAppConfig *fleet.AppConfig + ds.SaveAppConfigFunc = func(ctx context.Context, config *fleet.AppConfig) error { + savedAppConfig = config + return nil + } + + name := writeTmpYml(t, `--- +apiVersion: v1 +kind: config +spec: + host_settings: + enabled_software_inventory: false # typo, correct config is enable_software_inventory +`) + + runAppCheckErr(t, []string{"apply", "-f", name}, + "applying fleet config: apply config received status 400 Bad request: "+ + "json: unknown field \"enabled_software_inventory\"", + ) + require.Nil(t, savedAppConfig) +} diff --git a/server/service/service_appconfig.go b/server/service/service_appconfig.go index 60a35e121c..2e33332eaa 100644 --- a/server/service/service_appconfig.go +++ b/server/service/service_appconfig.go @@ -1,6 +1,7 @@ package service import ( + "bytes" "context" "encoding/json" "fmt" @@ -88,7 +89,6 @@ func (svc *Service) sendTestEmail(ctx context.Context, config *fleet.AppConfig) return mailError{message: err.Error()} } return nil - } func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte) (*fleet.AppConfig, error) { @@ -102,9 +102,10 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte) (*fleet.AppCo } // We apply the config that is incoming to the old one - err = json.Unmarshal(p, &appConfig) - if err != nil { - return nil, err + decoder := json.NewDecoder(bytes.NewReader(p)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&appConfig); err != nil { + return nil, &badRequestError{message: err.Error()} } if appConfig.SMTPSettings.SMTPEnabled || appConfig.SMTPSettings.SMTPConfigured {