mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
Add config support for disabling telemetry (#226)
* Add config-driven telemetry disable and surface telemetry status * Update config/config_template_test.go Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com> --------- Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com> Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
544b38b278
commit
996d9aeca0
@@ -225,4 +225,6 @@ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for gui
|
|||||||
## Telemetry
|
## Telemetry
|
||||||
|
|
||||||
PMG collects anonymous usage data to improve project stability and reliability.
|
PMG collects anonymous usage data to improve project stability and reliability.
|
||||||
To disable: `export PMG_DISABLE_TELEMETRY=true`.
|
To disable, either:
|
||||||
|
- Set `disable_telemetry: true` in your PMG config file, or
|
||||||
|
- Export `PMG_DISABLE_TELEMETRY=true`.
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ func runSync(cmd *cobra.Command, args []string) error {
|
|||||||
cfg := config.Get()
|
cfg := config.Get()
|
||||||
|
|
||||||
if analytics.IsDisabled() {
|
if analytics.IsDisabled() {
|
||||||
ui.Infof("Cloud sync is disabled because telemetry is disabled (PMG_DISABLE_TELEMETRY)")
|
ui.Infof("Cloud sync is disabled because telemetry is disabled (disable_telemetry or PMG_DISABLE_TELEMETRY)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/safedep/pmg/config"
|
"github.com/safedep/pmg/config"
|
||||||
"github.com/safedep/pmg/internal/alias"
|
"github.com/safedep/pmg/internal/alias"
|
||||||
|
"github.com/safedep/pmg/internal/analytics"
|
||||||
"github.com/safedep/pmg/internal/ui"
|
"github.com/safedep/pmg/internal/ui"
|
||||||
"github.com/safedep/pmg/internal/version"
|
"github.com/safedep/pmg/internal/version"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -38,6 +39,7 @@ func executeSetupInfo() error {
|
|||||||
configEntries := make(map[string]string)
|
configEntries := make(map[string]string)
|
||||||
configEntries["Config File"] = cfg.ConfigFilePath()
|
configEntries["Config File"] = cfg.ConfigFilePath()
|
||||||
configEntries["Proxy Mode"] = strconv.FormatBool(cfg.IsProxyModeEnabled())
|
configEntries["Proxy Mode"] = strconv.FormatBool(cfg.IsProxyModeEnabled())
|
||||||
|
configEntries["Proxy Install Only"] = strconv.FormatBool(cfg.Config.ProxyInstallOnly)
|
||||||
ui.PrintInfoSection("Configuration", configEntries)
|
ui.PrintInfoSection("Configuration", configEntries)
|
||||||
|
|
||||||
// Shell Integration section
|
// Shell Integration section
|
||||||
@@ -89,6 +91,7 @@ func executeSetupInfo() error {
|
|||||||
|
|
||||||
securityEntries["Dependency Cooldown"] = strconv.FormatBool(cfg.Config.DependencyCooldown.Enabled)
|
securityEntries["Dependency Cooldown"] = strconv.FormatBool(cfg.Config.DependencyCooldown.Enabled)
|
||||||
securityEntries["Dependency Cooldown Days"] = strconv.Itoa(cfg.Config.DependencyCooldown.Days)
|
securityEntries["Dependency Cooldown Days"] = strconv.Itoa(cfg.Config.DependencyCooldown.Days)
|
||||||
|
securityEntries["Telemetry"] = strconv.FormatBool(!analytics.IsDisabled())
|
||||||
securityEntries["Event Logging"] = strconv.FormatBool(!cfg.Config.SkipEventLogging)
|
securityEntries["Event Logging"] = strconv.FormatBool(!cfg.Config.SkipEventLogging)
|
||||||
securityEntries["Event Log Directory"] = cfg.EventLogDir()
|
securityEntries["Event Log Directory"] = cfg.EventLogDir()
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ type Config struct {
|
|||||||
// Paranoid enables high-security defaults (e.g., treating suspicious behavior as malicious).
|
// Paranoid enables high-security defaults (e.g., treating suspicious behavior as malicious).
|
||||||
Paranoid bool `mapstructure:"paranoid"`
|
Paranoid bool `mapstructure:"paranoid"`
|
||||||
|
|
||||||
|
// DisableTelemetry allows turning off telemetry collection.
|
||||||
|
DisableTelemetry bool `mapstructure:"disable_telemetry"`
|
||||||
|
|
||||||
// TrustedPackages allows for trusting a suspicious package and ignoring the suspicious behaviour for the package in future installations
|
// TrustedPackages allows for trusting a suspicious package and ignoring the suspicious behaviour for the package in future installations
|
||||||
TrustedPackages []TrustedPackage `mapstructure:"trusted_packages"`
|
TrustedPackages []TrustedPackage `mapstructure:"trusted_packages"`
|
||||||
|
|
||||||
@@ -242,6 +245,7 @@ func DefaultConfig() RuntimeConfig {
|
|||||||
TransitiveDepth: 5,
|
TransitiveDepth: 5,
|
||||||
IncludeDevDependencies: false,
|
IncludeDevDependencies: false,
|
||||||
Paranoid: false,
|
Paranoid: false,
|
||||||
|
DisableTelemetry: false,
|
||||||
EventLogRetentionDays: 7,
|
EventLogRetentionDays: 7,
|
||||||
SkipEventLogging: false,
|
SkipEventLogging: false,
|
||||||
ExperimentalProxyMode: false,
|
ExperimentalProxyMode: false,
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ verbosity: normal
|
|||||||
# as malicious packages
|
# as malicious packages
|
||||||
paranoid: false
|
paranoid: false
|
||||||
|
|
||||||
|
# Disable anonymous telemetry. Default is false.
|
||||||
|
disable_telemetry: false
|
||||||
|
|
||||||
# Skip event logging. Default is false.
|
# Skip event logging. Default is false.
|
||||||
# When skip_event_logging is false, all events will be logged to file. These events are useful for audit
|
# When skip_event_logging is false, all events will be logged to file. These events are useful for audit
|
||||||
# trail and incident response on systems using PMG. Set this config to true to disable event logging.
|
# trail and incident response on systems using PMG. Set this config to true to disable event logging.
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ func TestTemplateParsesAsYAML(t *testing.T) {
|
|||||||
assert.Equal(t, 5, cfg.TransitiveDepth, "expected TransitiveDepth 5")
|
assert.Equal(t, 5, cfg.TransitiveDepth, "expected TransitiveDepth 5")
|
||||||
assert.False(t, false, cfg.IncludeDevDependencies, "expected IncludeDevDependencies false")
|
assert.False(t, false, cfg.IncludeDevDependencies, "expected IncludeDevDependencies false")
|
||||||
assert.False(t, false, cfg.Paranoid, "expected Paranoid false")
|
assert.False(t, false, cfg.Paranoid, "expected Paranoid false")
|
||||||
|
assert.False(t, cfg.DisableTelemetry, "expected DisableTelemetry false")
|
||||||
assert.False(t, false, cfg.SkipEventLogging, "expected SkipEventLogging false")
|
assert.False(t, false, cfg.SkipEventLogging, "expected SkipEventLogging false")
|
||||||
assert.Equal(t, 7, cfg.EventLogRetentionDays, "expected EventLogRetentionDays 7")
|
assert.Equal(t, 7, cfg.EventLogRetentionDays, "expected EventLogRetentionDays 7")
|
||||||
assert.Len(t, cfg.TrustedPackages, 1)
|
assert.Len(t, cfg.TrustedPackages, 1)
|
||||||
@@ -52,6 +53,7 @@ func TestTemplateMatchesDefaults(t *testing.T) {
|
|||||||
assert.Equal(t, def.TransitiveDepth, parsed.TransitiveDepth, "transitive_depth mismatch")
|
assert.Equal(t, def.TransitiveDepth, parsed.TransitiveDepth, "transitive_depth mismatch")
|
||||||
assert.Equal(t, def.IncludeDevDependencies, parsed.IncludeDevDependencies, "include_dev_dependencies mismatch")
|
assert.Equal(t, def.IncludeDevDependencies, parsed.IncludeDevDependencies, "include_dev_dependencies mismatch")
|
||||||
assert.Equal(t, def.Paranoid, parsed.Paranoid, "paranoid mismatch")
|
assert.Equal(t, def.Paranoid, parsed.Paranoid, "paranoid mismatch")
|
||||||
|
assert.Equal(t, def.DisableTelemetry, parsed.DisableTelemetry, "disable_telemetry mismatch")
|
||||||
assert.Equal(t, def.SkipEventLogging, parsed.SkipEventLogging, "skip_event_logging mismatch")
|
assert.Equal(t, def.SkipEventLogging, parsed.SkipEventLogging, "skip_event_logging mismatch")
|
||||||
assert.Equal(t, def.EventLogRetentionDays, parsed.EventLogRetentionDays, "event_log_retention_days mismatch")
|
assert.Equal(t, def.EventLogRetentionDays, parsed.EventLogRetentionDays, "event_log_retention_days mismatch")
|
||||||
assert.Equal(t, def.Verbosity, parsed.Verbosity, "verbosity mismatch")
|
assert.Equal(t, def.Verbosity, parsed.Verbosity, "verbosity mismatch")
|
||||||
|
|||||||
@@ -154,6 +154,19 @@ func TestConfigPrecedence(t *testing.T) {
|
|||||||
assert.Equal(t, true, Get().Config.ProxyInstallOnly, "config file should override default")
|
assert.Equal(t, true, Get().Config.ProxyInstallOnly, "config file should override default")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("telemetry can be disabled via config", func(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
t.Setenv("PMG_CONFIG_DIR", tmpDir)
|
||||||
|
t.Setenv("PMG_DISABLE_TELEMETRY", "")
|
||||||
|
|
||||||
|
configPath := filepath.Join(tmpDir, "config.yml")
|
||||||
|
err := os.WriteFile(configPath, []byte("disable_telemetry: true\n"), 0o644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
initConfig()
|
||||||
|
assert.Equal(t, true, Get().Config.DisableTelemetry, "config file should disable telemetry")
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("env var works when key is absent from config file", func(t *testing.T) {
|
t.Run("env var works when key is absent from config file", func(t *testing.T) {
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
t.Setenv("PMG_CONFIG_DIR", tmpDir)
|
t.Setenv("PMG_CONFIG_DIR", tmpDir)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/posthog/posthog-go"
|
"github.com/posthog/posthog-go"
|
||||||
|
"github.com/safedep/pmg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -47,6 +48,10 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isTelemetryDisabled() bool {
|
func isTelemetryDisabled() bool {
|
||||||
|
if config.Get().Config.DisableTelemetry {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
val := os.Getenv(telemetryDisableEnvKey)
|
val := os.Getenv(telemetryDisableEnvKey)
|
||||||
if booleanVal, err := strconv.ParseBool(val); err == nil {
|
if booleanVal, err := strconv.ParseBool(val); err == nil {
|
||||||
return booleanVal
|
return booleanVal
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/safedep/pmg/config"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,8 +17,18 @@ func TestIsDisabled(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns false if PMG_DISABLE_TELEMETRY is not set", func(t *testing.T) {
|
t.Run("returns false if PMG_DISABLE_TELEMETRY is not set", func(t *testing.T) {
|
||||||
|
config.Get().Config.DisableTelemetry = false
|
||||||
assert.False(t, IsDisabled())
|
assert.False(t, IsDisabled())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("returns true if telemetry is disabled in config", func(t *testing.T) {
|
||||||
|
config.Get().Config.DisableTelemetry = true
|
||||||
|
t.Cleanup(func() {
|
||||||
|
config.Get().Config.DisableTelemetry = false
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.True(t, IsDisabled())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCloseIsImmutable(t *testing.T) {
|
func TestCloseIsImmutable(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user