Add telemetry consent to preference (#4456)

* Add telemetry consent

* Add telemetry preference to view

* Add integration test for preference
This commit is contained in:
Parthvi Vala
2021-03-08 19:22:53 +05:30
committed by GitHub
parent f6a819c8ab
commit eed0087ba1
7 changed files with 135 additions and 32 deletions

View File

@@ -30,6 +30,7 @@ var (
%[1]s %[6]s 30
%[1]s %[7]s true
%[1]s %[8]s docker
%[1]s %[9]s true
`)
)
@@ -68,6 +69,7 @@ func (o *SetOptions) Run() (err error) {
if !o.configForceFlag {
if isSet := cfg.IsSet(o.paramName); isSet {
// TODO: could add a logic to check if the new value set by the user is not same as the current value
if !ui.Proceed(fmt.Sprintf("%v is already set. Do you want to override it in the config", o.paramName)) {
log.Info("Aborted by the user")
return nil
@@ -94,7 +96,7 @@ func NewCmdSet(name, fullName string) *cobra.Command {
Example: fmt.Sprintf(fmt.Sprint("\n", setExample), fullName,
preference.UpdateNotificationSetting, preference.NamePrefixSetting,
preference.TimeoutSetting, preference.BuildTimeoutSetting, preference.PushTimeoutSetting,
preference.ExperimentalSetting, preference.PushTargetSetting),
preference.ExperimentalSetting, preference.PushTargetSetting, preference.ConsentTelemetrySetting),
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return fmt.Errorf("please provide a parameter name and value")

View File

@@ -31,6 +31,7 @@ var (
%[1]s %[6]s
%[1]s %[7]s
%[1]s %[8]s
%[1]s %[9]s
`)
)
@@ -97,7 +98,7 @@ func NewCmdUnset(name, fullName string) *cobra.Command {
Example: fmt.Sprintf(fmt.Sprint("\n", unsetExample), fullName,
preference.UpdateNotificationSetting, preference.NamePrefixSetting,
preference.TimeoutSetting, preference.BuildTimeoutSetting, preference.PushTimeoutSetting,
preference.ExperimentalSetting, preference.PushTargetSetting),
preference.ExperimentalSetting, preference.PushTargetSetting, preference.ConsentTelemetrySetting),
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("please provide a parameter name")

View File

@@ -68,6 +68,7 @@ func (o *ViewOptions) Run() (err error) {
fmt.Fprintln(w, "Experimental", "\t", showBlankIfNil(cfg.OdoSettings.Experimental))
fmt.Fprintln(w, "PushTarget", "\t", showBlankIfNil(cfg.OdoSettings.PushTarget))
fmt.Fprintln(w, "Ephemeral", "\t", showBlankIfNil(cfg.OdoSettings.Ephemeral))
fmt.Fprintln(w, "ConsentTelemetry", "\t", showBlankIfNil(cfg.OdoSettings.ConsentTelemetry))
w.Flush()
return

View File

@@ -86,6 +86,13 @@ func toPreferenceItems(prefInfo PreferenceInfo) []PreferenceItem {
Type: getType(prefInfo.GetPushTarget()),
Description: PushTargetDescription,
},
{
Name: ConsentTelemetrySetting,
Value: odoSettings.ConsentTelemetry,
Default: DefaultConsentTelemetrySetting,
Type: getType(prefInfo.GetConsentTelemetry()),
Description: ConsentTelemetryDescription,
},
}
}

View File

@@ -90,6 +90,12 @@ const (
// DefaultEphemeralSettings is a default value for Ephemeral preference
DefaultEphemeralSettings = true
// ConsentTelemetrySettings specifies if the user consents to telemetry
ConsentTelemetrySetting = "ConsentTelemetry"
// DefaultConsentTelemetry is a default value for ConsentTelemetry preference
DefaultConsentTelemetrySetting = false
)
// TimeoutSettingDescription is human-readable description for the timeout setting
@@ -107,6 +113,9 @@ var RegistryCacheTimeDescription = fmt.Sprintf("For how long (in minutes) odo wi
// EphemeralDescription adds a description for EphemeralSourceVolume
var EphemeralDescription = fmt.Sprintf("If true odo will create a emptyDir volume to store source code (Default: %t)", DefaultEphemeralSettings)
//TelemetryConsentDescription adds a description for TelemetryConsentSetting
var ConsentTelemetryDescription = fmt.Sprintf("If true odo will collect telemetry for the user's odo usage (Default: %t)\n\t\t For more information: https://developers.redhat.com/article/tool-data-collection", DefaultConsentTelemetrySetting)
// This value can be provided to set a seperate directory for users 'homedir' resolution
// note for mocking purpose ONLY
var customHomeDir = os.Getenv("CUSTOM_HOMEDIR")
@@ -123,6 +132,7 @@ var (
PushTargetSetting: PushTargetDescription,
RegistryCacheTimeSetting: RegistryCacheTimeDescription,
EphemeralSetting: EphemeralDescription,
ConsentTelemetrySetting: ConsentTelemetryDescription,
}
// set-like map to quickly check if a parameter is supported
@@ -167,6 +177,9 @@ type OdoSettings struct {
// Ephemeral if true creates odo emptyDir to store odo source code
Ephemeral *bool `yaml:"Ephemeral,omitempty"`
// ConsentTelemetry if true collects telemetry for odo
ConsentTelemetry *bool `yaml:"ConsentTelemetry,omitempty"`
}
// Registry includes the registry metadata
@@ -411,6 +424,7 @@ func (c *PreferenceInfo) SetConfiguration(parameter string, value string) error
}
c.OdoSettings.UpdateNotification = &val
// TODO: should we add a validator here? What is the use of nameprefix?
case "nameprefix":
c.OdoSettings.NamePrefix = &value
@@ -434,6 +448,13 @@ func (c *PreferenceInfo) SetConfiguration(parameter string, value string) error
return errors.Errorf("cannot set pushtarget to values other than '%s' or '%s'", DockerPushTarget, KubePushTarget)
}
c.OdoSettings.PushTarget = &val
case "consenttelemetry":
val, err := strconv.ParseBool(strings.ToLower(value))
if err != nil {
return errors.Wrapf(err, "unable to set %s to %s", parameter, value)
}
c.OdoSettings.ConsentTelemetry = &val
}
} else {
return errors.Errorf("unknown parameter :'%s' is not a parameter in odo preference", parameter)
@@ -521,12 +542,19 @@ func (c *PreferenceInfo) GetExperimental() bool {
}
// GetPushTarget returns the value of PushTarget from preferences
// and if absent then returns defualt
// and if absent then returns default
// default value: kube, docker push target needs to be manually enabled
func (c *PreferenceInfo) GetPushTarget() string {
return util.GetStringOrDefault(c.OdoSettings.PushTarget, KubePushTarget)
}
// GetConsentTelemetry returns the value of ConsentTelemetry from preferences
// and if absent then returns default
// default value: false, consent telemetry is disabled by default
func (c *PreferenceInfo) GetConsentTelemetry() bool {
return util.GetBoolOrDefault(c.OdoSettings.ConsentTelemetry, DefaultConsentTelemetrySetting)
}
// FormatSupportedParameters outputs supported parameters and their description
func FormatSupportedParameters() (result string) {
for _, v := range GetSupportedParameters() {

View File

@@ -919,3 +919,57 @@ func TestHandleWithRegistryExist(t *testing.T) {
}
}
}
func TestGetConsentTelemetry(t *testing.T) {
tempConfigFile, err := ioutil.TempFile("", "odoconfig")
if err != nil {
t.Fatal(err)
}
defer tempConfigFile.Close()
os.Setenv(GlobalConfigEnvName, tempConfigFile.Name())
trueValue := true
falseValue := false
tests := []struct {
name string
existingConfig Preference
want bool
}{{
name: fmt.Sprintf("Case 1: %s nil", ConsentTelemetrySetting),
existingConfig: Preference{},
want: false,
},
{
name: fmt.Sprintf("Case 2: %s true", ConsentTelemetrySetting),
existingConfig: Preference{
OdoSettings: OdoSettings{
ConsentTelemetry: &trueValue,
},
},
want: true,
},
{
name: fmt.Sprintf("Case 3: %s false", ConsentTelemetrySetting),
existingConfig: Preference{
OdoSettings: OdoSettings{
ConsentTelemetry: &falseValue,
},
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := PreferenceInfo{
Preference: tt.existingConfig,
}
output := cfg.GetConsentTelemetry()
if output != tt.want {
t.Errorf("GetConsentTelemetry returned unexpeced value expected \ngot: %t \nexpected: %t\n", output, tt.want)
}
})
}
}

View File

@@ -55,42 +55,54 @@ var _ = Describe("odo preference and config command tests", func() {
Context("When viewing global config", func() {
It("should get the default global config keys", func() {
configOutput := helper.CmdShouldPass("odo", "preference", "view")
helper.MatchAllInOutput(configOutput, []string{"UpdateNotification", "NamePrefix", "Timeout", "PushTarget"})
updateNotificationValue := helper.GetPreferenceValue("UpdateNotification")
Expect(updateNotificationValue).To(BeEmpty())
namePrefixValue := helper.GetPreferenceValue("NamePrefix")
Expect(namePrefixValue).To(BeEmpty())
timeoutValue := helper.GetPreferenceValue("Timeout")
Expect(timeoutValue).To(BeEmpty())
preferences := []string{"UpdateNotification", "NamePrefix", "Timeout", "PushTarget", "BuildTimeout", "PushTimeout", "Experimental", "Ephemeral", "ConsentTelemetry"}
helper.MatchAllInOutput(configOutput, preferences)
for _, key := range preferences {
value := helper.GetPreferenceValue(key)
Expect(value).To(BeEmpty())
}
})
})
Context("When configuring global config values", func() {
preferences := []struct {
name, value, updateValue, invalidValue string
}{
{"UpdateNotification", "false", "true", "foo"},
{"Timeout", "5", "6", "foo"},
{"PushTarget", "docker", "kube", "smh"},
{"NamePrefix", "foo", "bar", ""},
{"BuildTimeout", "5", "7", "foo"},
{"Experimental", "false", "true", "foo"},
{"ConsentTelemetry", "false", "true", "foo"},
{"PushTimeout", "4", "6", "f00"},
}
It("should successfully updated", func() {
helper.CmdShouldPass("odo", "preference", "set", "updatenotification", "false")
helper.CmdShouldPass("odo", "preference", "set", "timeout", "5")
helper.CmdShouldPass("odo", "preference", "set", "pushtarget", "docker")
UpdateNotificationValue := helper.GetPreferenceValue("UpdateNotification")
Expect(UpdateNotificationValue).To(ContainSubstring("false"))
TimeoutValue := helper.GetPreferenceValue("Timeout")
Expect(TimeoutValue).To(ContainSubstring("5"))
PushTargetValue := helper.GetPreferenceValue("PushTarget")
Expect(PushTargetValue).To(ContainSubstring("docker"))
helper.CmdShouldPass("odo", "preference", "set", "-f", "pushtarget", "kube")
PushTargetValue = helper.GetPreferenceValue("PushTarget")
Expect(PushTargetValue).To(ContainSubstring("kube"))
helper.CmdShouldPass("odo", "preference", "unset", "-f", "timeout")
timeoutValue := helper.GetPreferenceValue("Timeout")
Expect(timeoutValue).To(BeEmpty())
helper.CmdShouldPass("odo", "preference", "unset", "-f", "pushtarget")
PushTargetValue = helper.GetPreferenceValue("PushTarget")
Expect(PushTargetValue).To(BeEmpty())
for _, pref := range preferences {
helper.CmdShouldPass("odo", "preference", "set", pref.name, pref.value)
value := helper.GetPreferenceValue(pref.name)
Expect(value).To(ContainSubstring(pref.value))
helper.CmdShouldPass("odo", "preference", "set", "-f", pref.name, pref.updateValue)
value = helper.GetPreferenceValue(pref.name)
Expect(value).To(ContainSubstring(pref.updateValue))
helper.CmdShouldPass("odo", "preference", "unset", "-f", pref.name)
value = helper.GetPreferenceValue(pref.name)
Expect(value).To(BeEmpty())
}
globalConfPath := os.Getenv("HOME")
os.RemoveAll(filepath.Join(globalConfPath, ".odo"))
})
It("should unsuccessfully update", func() {
helper.CmdShouldFail("odo", "preference", "set", "-f", "pushtarget", "invalid-value")
helper.CmdShouldFail("odo", "preference", "set", "-f", "updatenotification", "invalid-value")
for _, pref := range preferences {
// TODO: Remove this once we decide something on checking NamePrefix
if pref.name != "NamePrefix" {
helper.CmdShouldFail("odo", "preference", "set", "-f", pref.name, pref.invalidValue)
}
}
})
It("should show json output", func() {
@@ -99,9 +111,7 @@ var _ = Describe("odo preference and config command tests", func() {
values := gjson.GetMany(prefJSONOutput, "kind", "items.0.Description")
expected := []string{"PreferenceList", "Flag to control if an update notification is shown or not (Default: true)"}
Expect(helper.GjsonMatcher(values, expected)).To(Equal(true))
})
})
Context("when creating odo local config in the same config dir", func() {