Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Backport of Inspecting boolean env var values. into release/0.4.x #1742

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changelog/1699.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:improvement
core: Correct parsing of boolean environment variables
```

27 changes: 23 additions & 4 deletions internal/ceb/ceb.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/hashicorp/waypoint/internal/env"
"github.com/hashicorp/waypoint/internal/pkg/gatedwriter"
"github.com/hashicorp/waypoint/internal/plugin"
"github.com/hashicorp/waypoint/internal/server"
Expand Down Expand Up @@ -299,11 +300,29 @@ func WithEnvDefaults() Option {

cfg.URLServicePort = port
cfg.ServerAddr = os.Getenv(envServerAddr)
cfg.ServerRequired = os.Getenv(envCEBServerRequired) != ""
cfg.ServerTls = os.Getenv(envServerTls) != ""
cfg.ServerTlsSkipVerify = os.Getenv(envServerTlsSkipVerify) != ""

var err error
cfg.ServerRequired, err = env.GetBool(envCEBServerRequired, false)
if err != nil {
return err
}

cfg.ServerTls, err = env.GetBool(envServerTls, false)
if err != nil {
return err
}

cfg.ServerTlsSkipVerify, err = env.GetBool(envServerTlsSkipVerify, false)
if err != nil {
return err
}

cfg.InviteToken = os.Getenv(envCEBToken)
cfg.disable = os.Getenv(envCEBDisable) != ""

cfg.disable, err = env.GetBool(envCEBDisable, false)
if err != nil {
return err
}

ceb.deploymentId = os.Getenv(envDeploymentId)

Expand Down
7 changes: 6 additions & 1 deletion internal/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/mitchellh/go-glint"

"github.com/hashicorp/waypoint-plugin-sdk/terminal"
"github.com/hashicorp/waypoint/internal/env"
"github.com/hashicorp/waypoint/internal/pkg/signalcontext"
"github.com/hashicorp/waypoint/internal/version"
)
Expand Down Expand Up @@ -139,7 +140,11 @@ func Commands(
}

// Set plain mode if set
if os.Getenv(EnvPlain) != "" {
outputModeBool, err := env.GetBool(EnvPlain, false)
if err != nil {
log.Warn(err.Error())
}
if outputModeBool {
baseCommand.globalOptions = append(baseCommand.globalOptions,
WithUI(terminal.NonInteractiveUI(ctx)))
}
Expand Down
22 changes: 22 additions & 0 deletions internal/env/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package env

import (
"fmt"
"os"
"strconv"
"strings"
)

// GetBool Extracts a boolean from an env var. Falls back to the default
// if the key is unset or not a valid boolean.
func GetBool(key string, defaultValue bool) (bool, error) {
envVal := os.Getenv(key)
if envVal == "" {
return defaultValue, nil
}
value, err := strconv.ParseBool(strings.ToLower(envVal))
if err != nil {
return defaultValue, fmt.Errorf("failed to parse a boolean from environment variable %s=%s", key, envVal)
}
return value, nil
}
88 changes: 88 additions & 0 deletions internal/env/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package env

import (
"os"
"testing"
)

func TestGetBool(t *testing.T) {
envVarTestKey := "WAYPOINT_GET_ENV_BOOL_TEST"

tests := []struct {
name string
defaultVal bool
envVal string
want bool
wantErr bool
}{
{
name: "Empty env var returns default 1",
defaultVal: true,
envVal: "",
want: true,
wantErr: false,
},
{
name: "Empty env var returns default 2",
defaultVal: false,
envVal: "",
want: false,
wantErr: false,
},
{
name: "Non-truthy env var returns err",
defaultVal: false,
envVal: "unparseable",
want: false,
wantErr: true,
},
{
name: "'true' is true",
defaultVal: false,
envVal: "true",
want: true,
wantErr: false,
},
{
name: "'false' is true",
defaultVal: true,
envVal: "false",
want: false,
wantErr: false,
},
{
name: "1 is true",
defaultVal: false,
envVal: "1",
want: true,
wantErr: false,
},
{
name: "0 is false",
defaultVal: true,
envVal: "0",
want: false,
wantErr: false,
},
{
name: "Boolean parsing ignores capitalization",
defaultVal: false,
envVal: "tRuE",
want: true,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
os.Setenv(envVarTestKey, tt.envVal)
got, err := GetBool(envVarTestKey, tt.defaultVal)
if (err != nil) != tt.wantErr {
t.Errorf("GetBool() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("GetBool() got = %v, want %v", got, tt.want)
}
})
}
}
15 changes: 13 additions & 2 deletions internal/serverclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"google.golang.org/grpc/credentials"

"github.com/hashicorp/waypoint/internal/clicontext"
"github.com/hashicorp/waypoint/internal/env"
"github.com/hashicorp/waypoint/internal/protocolversion"
"github.com/hashicorp/waypoint/internal/serverconfig"
)
Expand Down Expand Up @@ -126,8 +127,18 @@ func FromEnv() ConnectOption {
return func(c *connectConfig) error {
if v := os.Getenv(EnvServerAddr); v != "" {
c.Addr = v
c.Tls = os.Getenv(EnvServerTls) != ""
c.TlsSkipVerify = os.Getenv(EnvServerTlsSkipVerify) != ""

var err error
c.Tls, err = env.GetBool(EnvServerTls, false)
if err != nil {
return err
}

c.TlsSkipVerify, err = env.GetBool(EnvServerTlsSkipVerify, false)
if err != nil {
return err
}

c.Auth = os.Getenv(EnvServerToken) != ""
}

Expand Down
6 changes: 3 additions & 3 deletions website/content/docs/automating-execution/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ configure the Waypoint CLI for communication with the Waypoint server.
- `WAYPOINT_SERVER_TOKEN`. Must be set to a Waypoint token, created with [`waypoint token new`](/commands/token-new)
- `WAYPOINT_SERVER_ADDR`. The address to the Waypoint server gRPC address. This must
be accessible from the network that the client is running on.
- `WAYPOINT_SERVER_TLS`. Should be set to `1` to configure the client to use TLS when
- `WAYPOINT_SERVER_TLS`. Should be set to a truthy value (e.g. "1") to configure the client to use TLS when
connecting to the server.
- `WAYPOINT_SERVER_TLS_SKIP_VERIFY`. Current must be set to `1` to disable TLS verification
- `WAYPOINT_SERVER_TLS_SKIP_VERIFY`. Current must be set to a truthy value (e.g. "1") to disable TLS verification
when communicating with the server.

~> The Waypoint server token is sensitive and should be
Expand All @@ -71,7 +71,7 @@ If Waypoint detects that the terminal does not support interactivity it will out
simpler "non-interactive" output mode. This output is easier to consume in
a CI/CD systems logging views, or through log archiving systems. This is automatic
and does not need to be explicitly configured, but can be forced by setting
the environment variable `WAYPOINT_PLAIN` to `1`.
the environment variable `WAYPOINT_PLAIN` to a truthy value (e.g. "1").

## Workspaces

Expand Down
4 changes: 2 additions & 2 deletions website/content/docs/entrypoint/disable.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ deployments and apps.
## Disable at Runtime

You can disable the entrypoint at runtime by setting the `WAYPOINT_CEB_DISABLE`
environment variable to any non-empty value.
environment variable to a truthy value (e.g. "1").

This environment variable is checked immediately on entrypoint startup. If
it is present and non-empty then the entrypoint will immediately execute the
the value is true, then the entrypoint will immediately execute the
child process. The entrypoint **will not** attempt to even connect to the
server and will not use any network or disk resources.

Expand Down
8 changes: 5 additions & 3 deletions website/content/docs/runner/run-manual.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ The environment variables specify how to connect to the server:
that the runner can reach. The port should be for the gRPC API, and
is typically 9701.

- `WAYPOINT_SERVER_TLS` should be set to "true" if the server is listening
on TLS. You may additionally set `WAYPOINT_SERVER_TLS_SKIP_VERIFY` to
a non-empty value if the TLS cert is invalid and can be safely ignored
- `WAYPOINT_SERVER_TLS` should be set to a truthy value (e.g. "1") if
the server is listening on TLS.

- `WAYPOINT_SERVER_TLS_SKIP_VERIFY` should be set to a truthy value
(e.g. "1") if the TLS cert is invalid and can be safely ignored,
such as in a development environment.

- `WAYPOINT_SERVER_TOKEN` should be an [auth token](/docs/server/auth)
Expand Down