Skip to content

feat: add prompt to proceed if http proxy is set and https proxy unset #2186

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 30, 2025
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
27 changes: 24 additions & 3 deletions cmd/installer/cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ func waitForInstallAPI(ctx context.Context, addr string) error {
}

func runInstall(ctx context.Context, name string, flags InstallCmdFlags, metricsReporter preflights.MetricsReporter) error {
if err := runInstallVerifyAndPrompt(ctx, name, &flags); err != nil {
if err := runInstallVerifyAndPrompt(ctx, name, &flags, prompts.New()); err != nil {
return err
}

Expand Down Expand Up @@ -687,7 +687,7 @@ func markUIInstallComplete(password string, managerPort int) error {
return nil
}

func runInstallVerifyAndPrompt(ctx context.Context, name string, flags *InstallCmdFlags) error {
func runInstallVerifyAndPrompt(ctx context.Context, name string, flags *InstallCmdFlags, prompt prompts.Prompt) error {
logrus.Debugf("checking if k0s is already installed")
err := verifyNoInstallation(name, "reinstall")
if err != nil {
Expand All @@ -712,7 +712,7 @@ func runInstallVerifyAndPrompt(ctx context.Context, name string, flags *InstallC
}

if !flags.isAirgap {
if err := maybePromptForAppUpdate(ctx, prompts.New(), license, flags.assumeYes); err != nil {
if err := maybePromptForAppUpdate(ctx, prompt, license, flags.assumeYes); err != nil {
if errors.As(err, &ErrorNothingElseToAdd{}) {
return err
}
Expand All @@ -722,6 +722,11 @@ func runInstallVerifyAndPrompt(ctx context.Context, name string, flags *InstallC
}
}

if err := verifyProxyConfig(flags.proxy, prompt, flags.assumeYes); err != nil {
return err
}
logrus.Debug("User confirmed prompt to proceed installing with `http_proxy` set and `https_proxy` unset")

if err := preflights.ValidateApp(); err != nil {
return err
}
Expand Down Expand Up @@ -1107,6 +1112,22 @@ func maybePromptForAppUpdate(ctx context.Context, prompt prompts.Prompt, license
return nil
}

// verifyProxyConfig prompts for confirmation when HTTP proxy is set without HTTPS proxy,
// returning an error if the user declines to proceed.
func verifyProxyConfig(proxy *ecv1beta1.ProxySpec, prompt prompts.Prompt, assumeYes bool) error {
if proxy != nil && proxy.HTTPProxy != "" && proxy.HTTPSProxy == "" && !assumeYes {
message := "Typically --https-proxy should be set if --http-proxy is set. Installation failures are likely otherwise. Do you want to continue anyway?"
confirmed, err := prompt.Confirm(message, false)
if err != nil {
return fmt.Errorf("failed to confirm proxy settings: %w", err)
}
if !confirmed {
return NewErrorNothingElseToAdd(errors.New("user aborted: HTTP proxy configured without HTTPS proxy"))
}
}
return nil
}

// Minimum character length for the Admin Console password
const minAdminPasswordLength = 6

Expand Down
3 changes: 2 additions & 1 deletion cmd/installer/cli/install_runpreflights.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/replicatedhq/embedded-cluster/pkg/configutils"
"github.com/replicatedhq/embedded-cluster/pkg/netutils"
"github.com/replicatedhq/embedded-cluster/pkg/preflights"
"github.com/replicatedhq/embedded-cluster/pkg/prompts"
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -50,7 +51,7 @@ func InstallRunPreflightsCmd(ctx context.Context, name string) *cobra.Command {
}

func runInstallRunPreflights(ctx context.Context, name string, flags InstallCmdFlags) error {
if err := runInstallVerifyAndPrompt(ctx, name, &flags); err != nil {
if err := runInstallVerifyAndPrompt(ctx, name, &flags, prompts.New()); err != nil {
return err
}

Expand Down
80 changes: 80 additions & 0 deletions cmd/installer/cli/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"time"

"github.com/replicatedhq/embedded-cluster/api"
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
"github.com/replicatedhq/embedded-cluster/pkg-new/tlsutils"
"github.com/replicatedhq/embedded-cluster/pkg/prompts"
"github.com/replicatedhq/embedded-cluster/pkg/prompts/plain"
Expand Down Expand Up @@ -616,3 +617,82 @@ kind: Application
assert.ErrorIs(t, <-errCh, http.ErrServerClosed)
t.Logf("Install API exited")
}

func Test_verifyProxyConfig(t *testing.T) {
tests := []struct {
name string
proxy *ecv1beta1.ProxySpec
confirm bool
assumeYes bool
wantErr bool
isErrNothingElseToAdd bool
}{
{
name: "no proxy set",
proxy: nil,
wantErr: false,
},
{
name: "http proxy set without https proxy and user confirms",
proxy: &ecv1beta1.ProxySpec{
HTTPProxy: "http://proxy:8080",
},
confirm: true,
wantErr: false,
},
{
name: "http proxy set without https proxy and user declines",
proxy: &ecv1beta1.ProxySpec{
HTTPProxy: "http://proxy:8080",
},
confirm: false,
wantErr: true,
isErrNothingElseToAdd: true,
},
{
name: "http proxy set without https proxy and assumeYes is true",
proxy: &ecv1beta1.ProxySpec{
HTTPProxy: "http://proxy:8080",
},
assumeYes: true,
wantErr: false,
},
{
name: "both proxies set",
proxy: &ecv1beta1.ProxySpec{
HTTPProxy: "http://proxy:8080",
HTTPSProxy: "https://proxy:8080",
},
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var in *bytes.Buffer
if tt.confirm {
in = bytes.NewBuffer([]byte("y\n"))
} else {
in = bytes.NewBuffer([]byte("n\n"))
}
out := bytes.NewBuffer([]byte{})
mockPrompt := plain.New(plain.WithIn(in), plain.WithOut(out))

prompts.SetTerminal(true)
t.Cleanup(func() { prompts.SetTerminal(false) })

err := verifyProxyConfig(tt.proxy, mockPrompt, tt.assumeYes)
if tt.wantErr {
require.Error(t, err)
if tt.isErrNothingElseToAdd {
assert.ErrorAs(t, err, &ErrorNothingElseToAdd{})
}
if tt.proxy != nil && tt.proxy.HTTPProxy != "" && tt.proxy.HTTPSProxy == "" && !tt.assumeYes {
assert.Contains(t, out.String(), "Typically --https-proxy should be set if --http-proxy is set")
}
} else {
assert.NoError(t, err)
}
})
}
}