package deployment_test import ( "testing" "time" "github.com/spf13/pflag" "github.com/stretchr/testify/require" "github.com/coder/coder/cli/config" "github.com/coder/coder/cli/deployment" "github.com/coder/coder/codersdk" ) // nolint:paralleltest func TestConfig(t *testing.T) { viper := deployment.NewViper() flagSet := pflag.NewFlagSet("", pflag.ContinueOnError) flagSet.String(config.FlagName, "", "") deployment.AttachFlags(flagSet, viper, true) for _, tc := range []struct { Name string Env map[string]string Valid func(config *codersdk.DeploymentConfig) }{{ Name: "Deployment", Env: map[string]string{ "CODER_ADDRESS": "0.0.0.0:8443", "CODER_ACCESS_URL": "https://dev.coder.com", "CODER_PG_CONNECTION_URL": "some-url", "CODER_PPROF_ADDRESS": "something", "CODER_PPROF_ENABLE": "true", "CODER_PROMETHEUS_ADDRESS": "hello-world", "CODER_PROMETHEUS_ENABLE": "true", "CODER_PROVISIONER_DAEMONS": "5", "CODER_PROVISIONER_DAEMON_POLL_INTERVAL": "5s", "CODER_PROVISIONER_DAEMON_POLL_JITTER": "1s", "CODER_SECURE_AUTH_COOKIE": "true", "CODER_SSH_KEYGEN_ALGORITHM": "potato", "CODER_TELEMETRY": "false", "CODER_TELEMETRY_TRACE": "false", "CODER_WILDCARD_ACCESS_URL": "something-wildcard.com", "CODER_UPDATE_CHECK": "false", }, Valid: func(config *codersdk.DeploymentConfig) { require.Equal(t, config.Address.Value, "0.0.0.0:8443") require.Equal(t, config.AccessURL.Value, "https://dev.coder.com") require.Equal(t, config.PostgresURL.Value, "some-url") require.Equal(t, config.Pprof.Address.Value, "something") require.Equal(t, config.Pprof.Enable.Value, true) require.Equal(t, config.Prometheus.Address.Value, "hello-world") require.Equal(t, config.Prometheus.Enable.Value, true) require.Equal(t, config.Provisioner.Daemons.Value, 5) require.Equal(t, config.Provisioner.DaemonPollInterval.Value, 5*time.Second) require.Equal(t, config.Provisioner.DaemonPollJitter.Value, 1*time.Second) require.Equal(t, config.SecureAuthCookie.Value, true) require.Equal(t, config.SSHKeygenAlgorithm.Value, "potato") require.Equal(t, config.Telemetry.Enable.Value, false) require.Equal(t, config.Telemetry.Trace.Value, false) require.Equal(t, config.WildcardAccessURL.Value, "something-wildcard.com") require.Equal(t, config.UpdateCheck.Value, false) }, }, { Name: "DERP", Env: map[string]string{ "CODER_DERP_CONFIG_PATH": "/example/path", "CODER_DERP_CONFIG_URL": "https://google.com", "CODER_DERP_SERVER_ENABLE": "false", "CODER_DERP_SERVER_REGION_CODE": "something", "CODER_DERP_SERVER_REGION_ID": "123", "CODER_DERP_SERVER_REGION_NAME": "Code-Land", "CODER_DERP_SERVER_RELAY_URL": "1.1.1.1", "CODER_DERP_SERVER_STUN_ADDRESSES": "google.org", }, Valid: func(config *codersdk.DeploymentConfig) { require.Equal(t, config.DERP.Config.Path.Value, "/example/path") require.Equal(t, config.DERP.Config.URL.Value, "https://google.com") require.Equal(t, config.DERP.Server.Enable.Value, false) require.Equal(t, config.DERP.Server.RegionCode.Value, "something") require.Equal(t, config.DERP.Server.RegionID.Value, 123) require.Equal(t, config.DERP.Server.RegionName.Value, "Code-Land") require.Equal(t, config.DERP.Server.RelayURL.Value, "1.1.1.1") require.Equal(t, config.DERP.Server.STUNAddresses.Value, []string{"google.org"}) }, }, { Name: "Enterprise", Env: map[string]string{ "CODER_AUDIT_LOGGING": "false", "CODER_BROWSER_ONLY": "true", "CODER_SCIM_API_KEY": "some-key", }, Valid: func(config *codersdk.DeploymentConfig) { require.Equal(t, config.AuditLogging.Value, false) require.Equal(t, config.BrowserOnly.Value, true) require.Equal(t, config.SCIMAPIKey.Value, "some-key") }, }, { Name: "TLS", Env: map[string]string{ "CODER_TLS_CERT_FILE": "/etc/acme-sh/dev.coder.com,/etc/acme-sh/*.dev.coder.com", "CODER_TLS_KEY_FILE": "/etc/acme-sh/dev.coder.com,/etc/acme-sh/*.dev.coder.com", "CODER_TLS_CLIENT_AUTH": "/some/path", "CODER_TLS_CLIENT_CA_FILE": "/some/path", "CODER_TLS_ENABLE": "true", "CODER_TLS_MIN_VERSION": "tls10", }, Valid: func(config *codersdk.DeploymentConfig) { require.Len(t, config.TLS.CertFiles.Value, 2) require.Equal(t, config.TLS.CertFiles.Value[0], "/etc/acme-sh/dev.coder.com") require.Equal(t, config.TLS.CertFiles.Value[1], "/etc/acme-sh/*.dev.coder.com") require.Len(t, config.TLS.KeyFiles.Value, 2) require.Equal(t, config.TLS.KeyFiles.Value[0], "/etc/acme-sh/dev.coder.com") require.Equal(t, config.TLS.KeyFiles.Value[1], "/etc/acme-sh/*.dev.coder.com") require.Equal(t, config.TLS.ClientAuth.Value, "/some/path") require.Equal(t, config.TLS.ClientCAFile.Value, "/some/path") require.Equal(t, config.TLS.Enable.Value, true) require.Equal(t, config.TLS.MinVersion.Value, "tls10") }, }, { Name: "Trace", Env: map[string]string{ "CODER_TRACE_ENABLE": "true", "CODER_TRACE_HONEYCOMB_API_KEY": "my-honeycomb-key", }, Valid: func(config *codersdk.DeploymentConfig) { require.Equal(t, config.Trace.Enable.Value, true) require.Equal(t, config.Trace.HoneycombAPIKey.Value, "my-honeycomb-key") }, }, { Name: "OIDC_Defaults", Env: map[string]string{}, Valid: func(config *codersdk.DeploymentConfig) { require.Empty(t, config.OIDC.IssuerURL.Value) require.Empty(t, config.OIDC.EmailDomain.Value) require.Empty(t, config.OIDC.ClientID.Value) require.Empty(t, config.OIDC.ClientSecret.Value) require.True(t, config.OIDC.AllowSignups.Value) require.ElementsMatch(t, config.OIDC.Scopes.Value, []string{"openid", "email", "profile"}) require.False(t, config.OIDC.IgnoreEmailVerified.Value) }, }, { Name: "OIDC", Env: map[string]string{ "CODER_OIDC_ISSUER_URL": "https://accounts.google.com", "CODER_OIDC_EMAIL_DOMAIN": "coder.com", "CODER_OIDC_CLIENT_ID": "client", "CODER_OIDC_CLIENT_SECRET": "secret", "CODER_OIDC_ALLOW_SIGNUPS": "false", "CODER_OIDC_SCOPES": "something,here", "CODER_OIDC_IGNORE_EMAIL_VERIFIED": "true", }, Valid: func(config *codersdk.DeploymentConfig) { require.Equal(t, config.OIDC.IssuerURL.Value, "https://accounts.google.com") require.Equal(t, config.OIDC.EmailDomain.Value, []string{"coder.com"}) require.Equal(t, config.OIDC.ClientID.Value, "client") require.Equal(t, config.OIDC.ClientSecret.Value, "secret") require.False(t, config.OIDC.AllowSignups.Value) require.Equal(t, config.OIDC.Scopes.Value, []string{"something", "here"}) require.True(t, config.OIDC.IgnoreEmailVerified.Value) }, }, { Name: "GitHub", Env: map[string]string{ "CODER_OAUTH2_GITHUB_CLIENT_ID": "client", "CODER_OAUTH2_GITHUB_CLIENT_SECRET": "secret", "CODER_OAUTH2_GITHUB_ALLOWED_ORGS": "coder", "CODER_OAUTH2_GITHUB_ALLOWED_TEAMS": "coder", "CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS": "true", }, Valid: func(config *codersdk.DeploymentConfig) { require.Equal(t, config.OAuth2.Github.ClientID.Value, "client") require.Equal(t, config.OAuth2.Github.ClientSecret.Value, "secret") require.Equal(t, []string{"coder"}, config.OAuth2.Github.AllowedOrgs.Value) require.Equal(t, []string{"coder"}, config.OAuth2.Github.AllowedTeams.Value) require.Equal(t, config.OAuth2.Github.AllowSignups.Value, true) }, }, { Name: "GitAuth", Env: map[string]string{ "CODER_GITAUTH_0_ID": "hello", "CODER_GITAUTH_0_TYPE": "github", "CODER_GITAUTH_0_CLIENT_ID": "client", "CODER_GITAUTH_0_CLIENT_SECRET": "secret", "CODER_GITAUTH_0_AUTH_URL": "https://auth.com", "CODER_GITAUTH_0_TOKEN_URL": "https://token.com", "CODER_GITAUTH_0_VALIDATE_URL": "https://validate.com", "CODER_GITAUTH_0_REGEX": "github.com", "CODER_GITAUTH_0_SCOPES": "read write", "CODER_GITAUTH_0_NO_REFRESH": "true", "CODER_GITAUTH_1_ID": "another", "CODER_GITAUTH_1_TYPE": "gitlab", "CODER_GITAUTH_1_CLIENT_ID": "client-2", "CODER_GITAUTH_1_CLIENT_SECRET": "secret-2", "CODER_GITAUTH_1_AUTH_URL": "https://auth-2.com", "CODER_GITAUTH_1_TOKEN_URL": "https://token-2.com", "CODER_GITAUTH_1_REGEX": "gitlab.com", }, Valid: func(config *codersdk.DeploymentConfig) { require.Len(t, config.GitAuth.Value, 2) require.Equal(t, []codersdk.GitAuthConfig{{ ID: "hello", Type: "github", ClientID: "client", ClientSecret: "secret", AuthURL: "https://auth.com", TokenURL: "https://token.com", ValidateURL: "https://validate.com", Regex: "github.com", Scopes: []string{"read", "write"}, NoRefresh: true, }, { ID: "another", Type: "gitlab", ClientID: "client-2", ClientSecret: "secret-2", AuthURL: "https://auth-2.com", TokenURL: "https://token-2.com", Regex: "gitlab.com", }}, config.GitAuth.Value) }, }, { Name: "Wrong env must not break default values", Env: map[string]string{ "CODER_PROMETHEUS_ENABLE": "true", "CODER_PROMETHEUS": "true", // Wrong env name, must not break prom addr. }, Valid: func(config *codersdk.DeploymentConfig) { require.Equal(t, config.Prometheus.Enable.Value, true) require.Equal(t, config.Prometheus.Address.Value, config.Prometheus.Address.Default) }, }} { tc := tc t.Run(tc.Name, func(t *testing.T) { t.Helper() for key, value := range tc.Env { t.Setenv(key, value) } config, err := deployment.Config(flagSet, viper) require.NoError(t, err) tc.Valid(config) }) } }