diff --git a/api-tests/go.mod b/api-tests/go.mod index dd50350e63..55e2961e81 100644 --- a/api-tests/go.mod +++ b/api-tests/go.mod @@ -15,7 +15,7 @@ require ( github.com/go-openapi/runtime v0.19.20 github.com/go-openapi/spec v0.19.9 // indirect github.com/percona-platform/saas v0.0.0-20210122115803-1b32ca1828e1 - github.com/percona/pmm v0.0.0-20210707115905-36eb37dae44c + github.com/percona/pmm v0.0.0-20210827064257-db085a076f4f github.com/prometheus/client_golang v1.9.0 github.com/sirupsen/logrus v1.6.0 github.com/stretchr/testify v1.6.1 diff --git a/api-tests/go.sum b/api-tests/go.sum index 02eb9dcaf3..11ab584f04 100644 --- a/api-tests/go.sum +++ b/api-tests/go.sum @@ -224,8 +224,9 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -368,10 +369,11 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/percona-platform/saas v0.0.0-20210122115803-1b32ca1828e1 h1:VyKdL2wWYqwV79Sa4LHmLkQMjoSF+5uusQPBr4VoHWw= github.com/percona-platform/saas v0.0.0-20210122115803-1b32ca1828e1/go.mod h1:jJRyGMxxDJaSiU7AaHNS+8j1TFQQhX6lcYp8s0t8Knc= -github.com/percona/pmm v0.0.0-20210707115905-36eb37dae44c h1:6UtqOTbcZ02ekP8kIkbY2VEFR8h/j8ddby2z47dlfzw= -github.com/percona/pmm v0.0.0-20210707115905-36eb37dae44c/go.mod h1:Cm2JKvJMlMimtAhmF/1BUvz3qVJZ2O2zxQXRvtQh93Q= +github.com/percona/pmm v0.0.0-20210827064257-db085a076f4f h1:xI1aRNKiwRQM9+YxVbePfdriNxJWvqpzpFnUN5ZXgOI= +github.com/percona/pmm v0.0.0-20210827064257-db085a076f4f/go.mod h1:OmWayvQAavtvlzLkvpea5tAqaWGGNNyG+xj4MJUsNm4= github.com/percona/promconfig v0.2.1 h1:LBbCDSQRfy0aTHFJMgrVQIE2WvmPkMTkIoznTfBAvj8= github.com/percona/promconfig v0.2.1/go.mod h1:Y2uXi5QNk71+ceJHuI9poank+0S1kjxd3K105fXKVkg= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= @@ -457,17 +459,21 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.3.5 h1:S0ZOruh4YGHjD7JoN7mIsTrNjnQbOjrmgrx6l6pZN7I= -go.mongodb.org/mongo-driver v1.3.5/go.mod h1:Ual6Gkco7ZGQw8wE1t4tLnvBsf6yVSM60qW6TgOeJ5c= +go.mongodb.org/mongo-driver v1.7.1 h1:jwqTeEM3x6L9xDXrCxN0Hbg7vdGfPBOTIkr0+/LYZDA= +go.mongodb.org/mongo-driver v1.7.1/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -494,6 +500,7 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -573,8 +580,9 @@ golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/api-tests/server/settings_test.go b/api-tests/server/settings_test.go index 78e7899abe..a3fdd50404 100644 --- a/api-tests/server/settings_test.go +++ b/api-tests/server/settings_test.go @@ -59,6 +59,7 @@ func TestSettings(t *testing.T) { assert.Equal(t, expectedSTTCheckIntervals, res.Payload.Settings.SttCheckIntervals) assert.Equal(t, "2592000s", res.Payload.Settings.DataRetention) assert.Equal(t, []string{"aws"}, res.Payload.Settings.AWSPartitions) + assert.False(t, res.Payload.Settings.UpdatesDisabled) assert.True(t, res.Payload.Settings.AlertingEnabled) assert.Empty(t, res.Payload.Settings.EmailAlertingSettings) assert.Empty(t, res.Payload.Settings.SlackAlertingSettings) @@ -67,6 +68,53 @@ func TestSettings(t *testing.T) { defer restoreSettingsDefaults(t) + t.Run("Updates", func(t *testing.T) { + t.Run("DisableAndEnableUpdatesSettingsUpdate", func(t *testing.T) { + defer restoreSettingsDefaults(t) + res, err := serverClient.Default.Server.ChangeSettings(&server.ChangeSettingsParams{ + Body: server.ChangeSettingsBody{ + DisableUpdates: true, + }, + Context: pmmapitests.Context, + }) + require.NoError(t, err) + assert.True(t, res.Payload.Settings.UpdatesDisabled) + assert.Empty(t, err) + + resg, err := serverClient.Default.Server.GetSettings(nil) + require.NoError(t, err) + assert.True(t, resg.Payload.Settings.UpdatesDisabled) + + res, err = serverClient.Default.Server.ChangeSettings(&server.ChangeSettingsParams{ + Body: server.ChangeSettingsBody{ + EnableUpdates: true, + }, + Context: pmmapitests.Context, + }) + require.NoError(t, err) + assert.False(t, res.Payload.Settings.UpdatesDisabled) + assert.Empty(t, err) + + resg, err = serverClient.Default.Server.GetSettings(nil) + require.NoError(t, err) + assert.False(t, resg.Payload.Settings.UpdatesDisabled) + }) + + t.Run("InvalidBothEnableAndDisableUpdates", func(t *testing.T) { + defer restoreSettingsDefaults(t) + + res, err := serverClient.Default.Server.ChangeSettings(&server.ChangeSettingsParams{ + Body: server.ChangeSettingsBody{ + EnableUpdates: true, + DisableUpdates: true, + }, + Context: pmmapitests.Context, + }) + pmmapitests.AssertAPIErrorf(t, err, 400, codes.InvalidArgument, `Both enable_updates and disable_updates are present.`) + assert.Empty(t, res) + }) + }) + t.Run("ValidAlertingSettingsUpdate", func(t *testing.T) { defer restoreSettingsDefaults(t) diff --git a/go.mod b/go.mod index 456e12b581..5f939c0661 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/minio/minio-go/v7 v7.0.10 github.com/percona-platform/dbaas-api v0.0.0-20210726192627-670b3725d0ac github.com/percona-platform/saas v0.0.0-20210628125953-5bf84e6eefa0 - github.com/percona/pmm v0.0.0-20210826123440-dce1018c367d + github.com/percona/pmm v0.0.0-20210830094018-728af7854fbf github.com/percona/promconfig v0.2.1 github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 diff --git a/go.sum b/go.sum index adb023e892..caab865df4 100644 --- a/go.sum +++ b/go.sum @@ -440,8 +440,10 @@ github.com/percona-platform/dbaas-api v0.0.0-20210726192627-670b3725d0ac h1:AVIC github.com/percona-platform/dbaas-api v0.0.0-20210726192627-670b3725d0ac/go.mod h1:zgb9gTJusc8Jv2zRNAlWV0/XQ8IK+hwHMc9lIqfK0tM= github.com/percona-platform/saas v0.0.0-20210628125953-5bf84e6eefa0 h1:PwmQIqBMTsoYSSbpNjw6H1LYNULG6bxbj2OaAk3XnMk= github.com/percona-platform/saas v0.0.0-20210628125953-5bf84e6eefa0/go.mod h1:jJRyGMxxDJaSiU7AaHNS+8j1TFQQhX6lcYp8s0t8Knc= -github.com/percona/pmm v0.0.0-20210826123440-dce1018c367d h1:6tC3lPQ4odvVda/jxdHvH0CKkHZOIrYbbNuc0YlMDuw= -github.com/percona/pmm v0.0.0-20210826123440-dce1018c367d/go.mod h1:OmWayvQAavtvlzLkvpea5tAqaWGGNNyG+xj4MJUsNm4= +github.com/percona/pmm v0.0.0-20210827064257-db085a076f4f h1:xI1aRNKiwRQM9+YxVbePfdriNxJWvqpzpFnUN5ZXgOI= +github.com/percona/pmm v0.0.0-20210827064257-db085a076f4f/go.mod h1:OmWayvQAavtvlzLkvpea5tAqaWGGNNyG+xj4MJUsNm4= +github.com/percona/pmm v0.0.0-20210830094018-728af7854fbf h1:MXbL6/ZYFZHSGIRHOHpuU9Mi8KGHQodBHAK02A8GH9U= +github.com/percona/pmm v0.0.0-20210830094018-728af7854fbf/go.mod h1:OmWayvQAavtvlzLkvpea5tAqaWGGNNyG+xj4MJUsNm4= github.com/percona/promconfig v0.2.1 h1:LBbCDSQRfy0aTHFJMgrVQIE2WvmPkMTkIoznTfBAvj8= github.com/percona/promconfig v0.2.1/go.mod h1:Y2uXi5QNk71+ceJHuI9poank+0S1kjxd3K105fXKVkg= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= diff --git a/models/settings.go b/models/settings.go index 3f16e35f05..c955aad7c0 100644 --- a/models/settings.go +++ b/models/settings.go @@ -54,6 +54,10 @@ type IntegratedAlerting struct { type Settings struct { PMMPublicAddress string `json:"pmm_public_address"` + Updates struct { + Disabled bool `json:"disabled"` + } `json:"updates"` + Telemetry struct { Disabled bool `json:"disabled"` UUID string `json:"uuid"` diff --git a/models/settings_helpers.go b/models/settings_helpers.go index 1d4765c698..bccbdf26c4 100644 --- a/models/settings_helpers.go +++ b/models/settings_helpers.go @@ -48,8 +48,8 @@ func GetSettings(q reform.DBTX) (*Settings, error) { // ChangeSettingsParams contains values to change data in settings table. type ChangeSettingsParams struct { - // We don't save it to db DisableUpdates bool + EnableUpdates bool DisableTelemetry bool EnableTelemetry bool @@ -140,6 +140,12 @@ func UpdateSettings(q reform.DBTX, params *ChangeSettingsParams) (*Settings, err return nil, err } + if params.DisableUpdates { + settings.Updates.Disabled = true + } + if params.EnableUpdates { + settings.Updates.Disabled = false + } if params.DisableTelemetry { settings.Telemetry.Disabled = true settings.Telemetry.UUID = "" @@ -293,6 +299,9 @@ func UpdateSettings(q reform.DBTX, params *ChangeSettingsParams) (*Settings, err // ValidateSettings validates settings changes. func ValidateSettings(params *ChangeSettingsParams) error { + if params.EnableUpdates && params.DisableUpdates { + return fmt.Errorf("Both enable_updates and disable_updates are present.") //nolint:golint,stylecheck + } if params.EnableTelemetry && params.DisableTelemetry { return fmt.Errorf("Both enable_telemetry and disable_telemetry are present.") //nolint:golint,stylecheck } @@ -422,9 +431,8 @@ func validateSettingsConflicts(params *ChangeSettingsParams, settings *Settings) if params.DisableTelemetry && !params.DisableSTT && settings.SaaS.STTEnabled { return fmt.Errorf("Cannot disable telemetry while STT is enabled.") //nolint:golint,stylecheck } - if params.LogOut && (params.Email != "" || params.SessionID != "") { - return fmt.Errorf("Cannot loguot while updating Percona Platform user data.") //nolint:golint,stylecheck + return fmt.Errorf("Cannot logout while updating Percona Platform user data.") //nolint:golint,stylecheck } return nil diff --git a/models/settings_helpers_test.go b/models/settings_helpers_test.go index 88245f4880..fe0dbfcaec 100644 --- a/models/settings_helpers_test.go +++ b/models/settings_helpers_test.go @@ -169,6 +169,26 @@ func TestSettings(t *testing.T) { assert.EqualError(t, err, `data_retention: minimal resolution is 24h`) }) + t.Run("Updates validation", func(t *testing.T) { + ns, err := models.UpdateSettings(sqlDB, &models.ChangeSettingsParams{ + DisableUpdates: false, + }) + assert.NoError(t, err) + assert.False(t, ns.Updates.Disabled) + + _, err = models.UpdateSettings(sqlDB, &models.ChangeSettingsParams{ + EnableUpdates: true, + DisableUpdates: true, + }) + assert.EqualError(t, err, `Both enable_updates and disable_updates are present.`) + + ns, err = models.UpdateSettings(sqlDB, &models.ChangeSettingsParams{ + DisableUpdates: true, + }) + assert.NoError(t, err) + assert.True(t, ns.Updates.Disabled) + }) + t.Run("Telemetry and STT validation", func(t *testing.T) { // ensure initial default state ns, err := models.UpdateSettings(sqlDB, &models.ChangeSettingsParams{ diff --git a/services/server/server.go b/services/server/server.go index b8ad1678aa..890b83f8a8 100644 --- a/services/server/server.go +++ b/services/server/server.go @@ -427,7 +427,7 @@ func (s *Server) readUpdateAuthToken() (string, error) { // convertSettings merges database settings and settings from environment variables into API response. func (s *Server) convertSettings(settings *models.Settings) *serverpb.Settings { res := &serverpb.Settings{ - UpdatesDisabled: s.envSettings.DisableUpdates, + UpdatesDisabled: settings.Updates.Disabled, TelemetryEnabled: !settings.Telemetry.Disabled, MetricsResolutions: &serverpb.MetricsResolutions{ Hr: durationpb.New(settings.MetricsResolutions.HR), @@ -520,6 +520,10 @@ func (s *Server) validateChangeSettingsRequest(ctx context.Context, req *serverp // check request parameters compatibility with environment variables + if req.EnableUpdates && s.envSettings.DisableUpdates { + return status.Error(codes.FailedPrecondition, "Updates are disabled via DISABLE_UPDATES environment variable.") + } + // ignore req.DisableTelemetry and req.DisableStt even if they are present since that will not change anything if req.EnableTelemetry && s.envSettings.DisableTelemetry { return status.Error(codes.FailedPrecondition, "Telemetry is disabled via DISABLE_TELEMETRY environment variable.") @@ -580,6 +584,8 @@ func (s *Server) ChangeSettings(ctx context.Context, req *serverpb.ChangeSetting metricsRes := req.MetricsResolutions sttCheckIntervals := req.SttCheckIntervals settingsParams := &models.ChangeSettingsParams{ + DisableUpdates: req.DisableUpdates, + EnableUpdates: req.EnableUpdates, DisableTelemetry: req.DisableTelemetry, EnableTelemetry: req.EnableTelemetry, STTCheckIntervals: models.STTCheckIntervals{ diff --git a/services/server/server_test.go b/services/server/server_test.go index 34550c4f62..6eae8c2024 100644 --- a/services/server/server_test.go +++ b/services/server/server_test.go @@ -188,8 +188,16 @@ func TestServer(t *testing.T) { RemoveAlertManagerRules: true, })) - s.envSettings.DisableTelemetry = true + s.envSettings.DisableUpdates = true + expected = status.New(codes.FailedPrecondition, "Updates are disabled via DISABLE_UPDATES environment variable.") + tests.AssertGRPCError(t, expected, s.validateChangeSettingsRequest(ctx, &serverpb.ChangeSettingsRequest{ + EnableUpdates: true, + })) + assert.NoError(t, s.validateChangeSettingsRequest(ctx, &serverpb.ChangeSettingsRequest{ + DisableUpdates: true, + })) + s.envSettings.DisableTelemetry = true expected = status.New(codes.FailedPrecondition, "Telemetry is disabled via DISABLE_TELEMETRY environment variable.") tests.AssertGRPCError(t, expected, s.validateChangeSettingsRequest(ctx, &serverpb.ChangeSettingsRequest{ EnableTelemetry: true,