diff --git a/cmd/init.go b/cmd/init.go index 7c51371c..4851ca88 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -10,6 +10,7 @@ package cmd import ( "encoding/json" "fmt" + "os" "github.com/getsentry/sentry-go" "github.com/pkg/errors" @@ -34,14 +35,20 @@ var ( // and handles: // // 1. Loading the Config from the environment -// 2. Configuring Sentry -// 3. Configuring Logrus (+Logrus -> Sentry) +// 2. Checking for licence acceptance +// 3. Configuring Sentry +// 4. Configuring Logrus (+Logrus -> Sentry) func Init() (*config.Config, bool, error) { cfg, err := config.NewConfig() if err != nil { return nil, false, errors.Wrap(err, "Failed to build config") } + // If licence not accepted, fail on startup + if !cfg.Data.Licence.Accept && !handleSLULAEnvVar() { + return nil, false, errors.New("Please accept the terms of the Snowplow Limited Use License Agreement to proceed. See https://docs.snowplow.io/docs/destinations/forwarding-events/snowbridge/configuration/#license for more information on the license and how to configure this.") + } + // Configure Sentry sentryEnabled := cfg.Data.Sentry.Dsn != "" if sentryEnabled { @@ -78,3 +85,15 @@ func Init() (*config.Config, bool, error) { log.Debugf("Config: %+v", cfg) return cfg, sentryEnabled, nil } + +func handleSLULAEnvVar() bool { + foundVal := os.Getenv("ACCEPT_LIMITED_USE_LICENSE") + truthyVals := []string{"true", "yes", "on", "1"} + + for _, truthyVal := range truthyVals { + if foundVal == truthyVal { + return true + } + } + return false +} diff --git a/cmd/init_test.go b/cmd/init_test.go index 3663d93b..10152669 100644 --- a/cmd/init_test.go +++ b/cmd/init_test.go @@ -20,17 +20,47 @@ func TestMain(m *testing.M) { os.Exit(exitVal) } +func TestHandleSLULAEnvVar(t *testing.T) { + assert := assert.New(t) + + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "true") + assert.True(handleSLULAEnvVar()) + + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "yes") + assert.True(handleSLULAEnvVar()) + + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "1") + assert.True(handleSLULAEnvVar()) + + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "on") + assert.True(handleSLULAEnvVar()) +} + func TestInit_Success(t *testing.T) { assert := assert.New(t) + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "yes") + cfg, _, err := Init() assert.NotNil(cfg) assert.Nil(err) } +func TestInit_SLULAFailre(t *testing.T) { + assert := assert.New(t) + + cfg, _, err := Init() + assert.Nil(cfg) + assert.NotNil(err) + if err != nil { + assert.Equal("Please accept the terms of the Snowplow Limited Use License Agreement to proceed. See https://docs.snowplow.io/docs/destinations/forwarding-events/snowbridge/configuration/#license for more information on the license and how to configure this.", err.Error()) + } +} + func TestInit_Failure(t *testing.T) { assert := assert.New(t) + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "on") t.Setenv("STATS_RECEIVER_TIMEOUT_SEC", "debug") cfg, _, err := Init() @@ -44,6 +74,7 @@ func TestInit_Failure(t *testing.T) { func TestInit_Success_Sentry(t *testing.T) { assert := assert.New(t) + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "1") t.Setenv("SENTRY_DSN", "https://1111111111111111111111111111111d@sentry.snplow.net/28") t.Setenv("SENTRY_TAGS", "{\"client_name\":\"com.acme\"}") @@ -55,6 +86,7 @@ func TestInit_Success_Sentry(t *testing.T) { func TestInit_Failure_LogLevel(t *testing.T) { assert := assert.New(t) + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "true") t.Setenv("LOG_LEVEL", "DEBUG") cfg, _, err := Init() @@ -68,6 +100,7 @@ func TestInit_Failure_LogLevel(t *testing.T) { func TestInit_Failure_SentryDSN(t *testing.T) { assert := assert.New(t) + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "yes") t.Setenv("SENTRY_DSN", "blahblah") cfg, _, err := Init() @@ -81,6 +114,7 @@ func TestInit_Failure_SentryDSN(t *testing.T) { func TestInit_Failure_SentryTags(t *testing.T) { assert := assert.New(t) + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "yes") t.Setenv("SENTRY_DSN", "https://1111111111111111111111111111111d@sentry.snplow.net/28") t.Setenv("SENTRY_TAGS", "asdasdasd") diff --git a/config/config.go b/config/config.go index 9edb1146..df53ccfc 100644 --- a/config/config.go +++ b/config/config.go @@ -51,6 +51,7 @@ type configurationData struct { LogLevel string `hcl:"log_level,optional" env:"LOG_LEVEL"` UserProvidedID string `hcl:"user_provided_id,optional" env:"USER_PROVIDED_ID"` DisableTelemetry bool `hcl:"disable_telemetry,optional" env:"DISABLE_TELEMETRY"` + Licence *licenceConfig `hcl:"licence,block"` } // component is a type to abstract over configuration blocks. @@ -86,6 +87,10 @@ type statsConfig struct { BufferSec int `hcl:"buffer_sec,optional" env:"STATS_RECEIVER_BUFFER_SEC"` } +type licenceConfig struct { + Accept bool `hcl:"accept,optional"` +} + // defaultConfigData returns the initial main configuration target. func defaultConfigData() *configurationData { return &configurationData{ @@ -107,6 +112,9 @@ func defaultConfigData() *configurationData { Transformations: nil, LogLevel: "info", DisableTelemetry: false, + Licence: &licenceConfig{ + Accept: false, + }, } } diff --git a/config/config_test.go b/config/config_test.go index cf11413f..02e56c9d 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -15,7 +15,6 @@ import ( "github.com/stretchr/testify/assert" ) -// The GetSource part needs to move anyway - causes circular dep. func TestNewConfig(t *testing.T) { assert := assert.New(t) diff --git a/docs/configuration_monitoring_docs_test.go b/docs/configuration_monitoring_docs_test.go index ad85b588..f794448f 100644 --- a/docs/configuration_monitoring_docs_test.go +++ b/docs/configuration_monitoring_docs_test.go @@ -67,6 +67,7 @@ func testStatsDConfig(t *testing.T, configpath string, fullExample bool) { func testSentryConfig(t *testing.T, configpath string, fullExample bool) { assert := assert.New(t) t.Setenv("SNOWBRIDGE_CONFIG_FILE", configpath) + t.Setenv("ACCEPT_LIMITED_USE_LICENSE", "true") // Since sentry lives in cmd, we call Init to test it. cfgSentry, sentryEnabled, initErr := cmd.Init() diff --git a/release_test/e2e_common_test.go b/release_test/e2e_common_test.go index c5bd92d4..233da772 100644 --- a/release_test/e2e_common_test.go +++ b/release_test/e2e_common_test.go @@ -33,6 +33,7 @@ var cmdTemplate = `cat %s | docker run -i \ --add-host host.docker.internal:host-gateway \ --mount type=bind,source=%s,target=/config.hcl \ --env SNOWBRIDGE_CONFIG_FILE=/config.hcl %s \ +--env ACCEPT_LIMITED_USE_LICENSE=true \ snowplow/snowbridge:%s%s` // explanation of arguments: