Skip to content

Commit

Permalink
Merge pull request #1238 from cloudskiff/add_build_flag_to_disable_te…
Browse files Browse the repository at this point in the history
…lemetry

Add a global switch to disable third party
  • Loading branch information
eliecharra authored Nov 29, 2021
2 parents cbc6fd7 + c460a9e commit ede653f
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 52 deletions.
11 changes: 11 additions & 0 deletions build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@ package build

var env = "dev"

// This flag could be switched to false while building to create a binary without third party network calls
// That mean that following services will be disabled:
// - telemetry
// - version check
var enableUsageReporting = "true"

type BuildInterface interface {
IsRelease() bool
IsUsageReportingEnabled() bool
}

type Build struct{}

func (b Build) IsRelease() bool {
return env == "release"
}

func (b Build) IsUsageReportingEnabled() bool {
return enableUsageReporting == "true"
}
8 changes: 7 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ func run() int {

config.Init()
logger.Init()
build := build.Build{}
logrus.WithFields(logrus.Fields{
"isRelease": fmt.Sprintf("%t", build.IsRelease()),
"isUsageReportingEnabled": fmt.Sprintf("%t", build.IsUsageReportingEnabled()),
"version": version.Current(),
}).Debug("Build info")

driftctlCmd := cmd.NewDriftctlCmd(build.Build{})
driftctlCmd := cmd.NewDriftctlCmd(build)

checkVersion := driftctlCmd.ShouldCheckVersion()
latestVersionChan := make(chan string)
Expand Down
8 changes: 5 additions & 3 deletions pkg/cmd/driftctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ func NewDriftctlCmd(build build.BuildInterface) *DriftctlCmd {
cmd.SetUsageTemplate(usageTemplate)

cmd.PersistentFlags().BoolP("help", "h", false, "Display help for command")
cmd.PersistentFlags().BoolP("no-version-check", "", false, "Disable the version check")
cmd.PersistentFlags().BoolP("disable-telemetry", "", false, "Disable telemetry")
if cmd.build.IsUsageReportingEnabled() {
cmd.PersistentFlags().BoolP("no-version-check", "", false, "Disable the version check")
cmd.PersistentFlags().BoolP("disable-telemetry", "", false, "Disable telemetry")
}
cmd.PersistentFlags().BoolP("send-crash-report", "", false, "Enable error reporting. Crash data will be sent to us via Sentry.\nWARNING: may leak sensitive data (please read the documentation for more details)\nThis flag should be used only if an error occurs during execution")

cmd.AddCommand(NewScanCmd(&pkg.ScanOptions{}))
Expand All @@ -87,7 +89,7 @@ func (driftctlCmd DriftctlCmd) ShouldCheckVersion() bool {
hasVersionCmd := contains(os.Args[1:], "version")
hasCompletionCmd := contains(os.Args[1:], "completion")
isHelp := contains(os.Args[1:], "help") || contains(os.Args[1:], "--help") || contains(os.Args[1:], "-h")
return driftctlCmd.build.IsRelease() && !hasVersionCmd && !hasCompletionCmd && !noVersionCheckVal && !isHelp && !noVersionCheckEnv
return driftctlCmd.build.IsRelease() && driftctlCmd.build.IsUsageReportingEnabled() && !hasVersionCmd && !hasCompletionCmd && !noVersionCheckVal && !isHelp && !noVersionCheckEnv
}

func IsReportingEnabled(cmd *cobra.Command) bool {
Expand Down
106 changes: 62 additions & 44 deletions pkg/cmd/driftctl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,73 +165,91 @@ func TestDriftctlCmd_Invalid(t *testing.T) {

func TestDriftctlCmd_ShouldCheckVersion(t *testing.T) {
cases := []struct {
Name string
IsRelease bool
args []string
env map[string]string
expected bool
Name string
IsRelease bool
UsageReport bool
args []string
env map[string]string
expected bool
}{
{
Name: "When we are in release mode and no args, should check for update",
IsRelease: true,
args: []string{""},
expected: true,
Name: "When we are in release mode and no args, should check for update",
IsRelease: true,
UsageReport: true,
args: []string{""},
expected: true,
},
{
Name: "Don't check for update for version cmd",
IsRelease: true,
args: []string{"version"},
expected: false,
Name: "Do not check for update when usage reporting is disabled",
IsRelease: true,
UsageReport: false,
args: []string{""},
expected: false,
},
{
Name: "Don't check for update for help cmd",
IsRelease: true,
args: []string{"help"},
expected: false,
Name: "Don't check for update for version cmd",
IsRelease: true,
UsageReport: true,
args: []string{"version"},
expected: false,
},
{
Name: "Don't check for update for cmd --help",
IsRelease: true,
args: []string{"scan", "--help"},
expected: false,
Name: "Don't check for update for help cmd",
IsRelease: true,
UsageReport: true,
args: []string{"help"},
expected: false,
},
{
Name: "Don't check for update for cmd -h",
IsRelease: true,
args: []string{"scan", "-h"},
expected: false,
Name: "Don't check for update for cmd --help",
IsRelease: true,
UsageReport: true,
args: []string{"scan", "--help"},
expected: false,
},
{
Name: "Don't check for update when no check flag present",
IsRelease: true,
args: []string{"--no-version-check"},
expected: false,
Name: "Don't check for update for cmd -h",
IsRelease: true,
UsageReport: true,
args: []string{"scan", "-h"},
expected: false,
},
{
Name: "Don't check for update in dev mode",
IsRelease: false,
args: []string{""},
expected: false,
Name: "Don't check for update when no check flag present",
IsRelease: true,
UsageReport: true,
args: []string{"--no-version-check"},
expected: false,
},
{
Name: "Don't check for update when env DCTL_NO_VERSION_CHECK set",
IsRelease: true,
Name: "Don't check for update in dev mode",
IsRelease: false,
UsageReport: true,
args: []string{""},
expected: false,
},
{
Name: "Don't check for update when env DCTL_NO_VERSION_CHECK set",
IsRelease: true,
UsageReport: true,
env: map[string]string{
"DCTL_NO_VERSION_CHECK": "foo",
},
expected: false,
},
{
Name: "Should not return error when launching sub command",
IsRelease: false,
args: []string{"scan", "--from", "tfstate://terraform.tfstate"},
expected: false,
Name: "Should not return error when launching sub command",
IsRelease: false,
UsageReport: true,
args: []string{"scan", "--from", "tfstate://terraform.tfstate"},
expected: false,
},
{
Name: "Don't check for update for completion cmd",
IsRelease: true,
args: []string{"completion", "bash"},
expected: false,
Name: "Don't check for update for completion cmd",
IsRelease: true,
UsageReport: true,
args: []string{"completion", "bash"},
expected: false,
},
}

Expand All @@ -244,7 +262,7 @@ func TestDriftctlCmd_ShouldCheckVersion(t *testing.T) {
os.Setenv(key, val)
}

cmd := NewDriftctlCmd(mocks.MockBuild{Release: c.IsRelease})
cmd := NewDriftctlCmd(mocks.MockBuild{Release: c.IsRelease, UsageReporting: c.UsageReport})
os.Args = append([]string{"driftctl"}, c.args...)
result := cmd.ShouldCheckVersion()

Expand Down
4 changes: 3 additions & 1 deletion pkg/cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"syscall"
"time"

"github.com/cloudskiff/driftctl/build"
"github.com/cloudskiff/driftctl/pkg/analyser"
"github.com/cloudskiff/driftctl/pkg/memstore"
"github.com/cloudskiff/driftctl/pkg/remote/common"
Expand Down Expand Up @@ -309,7 +310,8 @@ func scanRun(opts *pkg.ScanOptions) error {
globaloutput.Printf(color.WhiteString("Provider version used to scan: %s. Use --tf-provider-version to use another version.\n"), resourceSchemaRepository.ProviderVersion.String())

if !opts.DisableTelemetry {
telemetry.SendTelemetry(store.Bucket(memstore.TelemetryBucket))
tl := telemetry.NewTelemetry(&build.Build{})
tl.SendTelemetry(store.Bucket(memstore.TelemetryBucket))
}

if !analysis.IsSync() {
Expand Down
17 changes: 16 additions & 1 deletion pkg/telemetry/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"runtime"

"github.com/cloudskiff/driftctl/build"
"github.com/cloudskiff/driftctl/pkg/memstore"
"github.com/cloudskiff/driftctl/pkg/version"
"github.com/sirupsen/logrus"
Expand All @@ -21,7 +22,21 @@ type telemetry struct {
ProviderName string `json:"provider_name"`
}

func SendTelemetry(store memstore.Bucket) {
type Telemetry struct {
build build.BuildInterface
}

func NewTelemetry(build build.BuildInterface) *Telemetry {
return &Telemetry{build: build}
}

func (te Telemetry) SendTelemetry(store memstore.Bucket) {

if !te.build.IsUsageReportingEnabled() {
logrus.Debug("Usage reporting is disabled on this build, telemetry skipped")
return
}

t := &telemetry{
Version: version.Current(),
Os: runtime.GOOS,
Expand Down
20 changes: 19 additions & 1 deletion pkg/telemetry/telemetry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/cloudskiff/driftctl/pkg/memstore"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/version"
"github.com/cloudskiff/driftctl/test/mocks"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -126,7 +127,24 @@ func TestSendTelemetry(t *testing.T) {
},
)
}
SendTelemetry(store)
tl := NewTelemetry(mocks.MockBuild{UsageReporting: true})
tl.SendTelemetry(store)
})
}
}

func TestTelemetryNotSend(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
store := memstore.New().Bucket(memstore.TelemetryBucket)

httpmock.RegisterResponder(
"POST",
"https://2lvzgmrf2e.execute-api.eu-west-3.amazonaws.com/telemetry",
httpmock.NewErrorResponder(nil),
)
tl := NewTelemetry(mocks.MockBuild{UsageReporting: false})
tl.SendTelemetry(store)

assert.Zero(t, httpmock.GetTotalCallCount())
}
4 changes: 4 additions & 0 deletions test/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ type Build struct{}
func (b Build) IsRelease() bool {
return false
}

func (b Build) IsUsageReportingEnabled() bool {
return false
}
7 changes: 6 additions & 1 deletion test/mocks/MockBuild.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package mocks

type MockBuild struct {
Release bool
Release bool
UsageReporting bool
}

func (m MockBuild) IsRelease() bool {
return m.Release
}

func (m MockBuild) IsUsageReportingEnabled() bool {
return m.UsageReporting
}

0 comments on commit ede653f

Please sign in to comment.