-
Notifications
You must be signed in to change notification settings - Fork 3
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
automatically detect node ip during install for noproxy #1186
Merged
laverya
merged 30 commits into
main
from
laverya/sc-111539/automatically-detect-node-ip-during-install
Sep 19, 2024
Merged
Changes from 22 commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
bf5bd9e
add a note to readme specifying a folder to place the license
laverya 4e17c8a
get default interface
laverya 95b484e
wip default noproxies and prompts
laverya 9479324
disable most tests
laverya e7f5491
prompt for new noproxy
laverya 978ca16
store provided noproxy values and total noproxy values independently
laverya 7030d94
dedup code
laverya b77595d
simplify noproxy subnet
laverya 18c599b
regen CRDs
laverya 1f3a106
update unit tests
laverya 1273355
fix no-prompt case
laverya 9cadfcd
?
laverya 1d1e1f8
FFFF
laverya 0948a2e
???
laverya 3ed457c
test bigger noproxy
laverya 65cdeae
reuse proxy object, don't rederive from flags
laverya 9ae2cc2
reorder imports
laverya 4b973ba
Revert "disable most tests"
laverya bfda1e5
misspelling
laverya fc36e37
rename to combineNoProxySuppliedValuesAndDefaults, remove debug logs
laverya 3fbaf4e
add link to k0s logic
laverya c22cbbf
recursively prompt for noproxy
laverya 9d6e4cf
remove prompts for proxy, just add the default subnet if the current …
laverya 296e592
maybePromptForNoProxy -> includeLocalIPInNoProxy
laverya b345951
check the noproxy config on node join
laverya 207f65e
test that should fail to ensure that join command preflights are work…
laverya 561883a
fix 'adding "blah" to the noproxy you provided' message
laverya ebb410b
test failed successfully, restoring it
laverya 060b3f2
restore all tests, again
laverya eac4573
Accept Alex's suggestions for noproxy messaging
laverya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,11 +1,16 @@ | ||||||
package main | ||||||
|
||||||
import ( | ||||||
"fmt" | ||||||
"net" | ||||||
"os" | ||||||
"strings" | ||||||
|
||||||
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1" | ||||||
"github.com/replicatedhq/embedded-cluster/pkg/defaults" | ||||||
"github.com/replicatedhq/embedded-cluster/pkg/netutils" | ||||||
"github.com/replicatedhq/embedded-cluster/pkg/prompts" | ||||||
"github.com/sirupsen/logrus" | ||||||
"github.com/urfave/cli/v2" | ||||||
) | ||||||
|
||||||
|
@@ -36,12 +41,12 @@ func withProxyFlags(flags []cli.Flag) []cli.Flag { | |||||
|
||||||
func getProxySpecFromFlags(c *cli.Context) *ecv1beta1.ProxySpec { | ||||||
proxy := &ecv1beta1.ProxySpec{} | ||||||
var noProxy []string | ||||||
var providedNoProxy []string | ||||||
if c.Bool("proxy") { | ||||||
proxy.HTTPProxy = os.Getenv("HTTP_PROXY") | ||||||
proxy.HTTPSProxy = os.Getenv("HTTPS_PROXY") | ||||||
if os.Getenv("NO_PROXY") != "" { | ||||||
noProxy = append(noProxy, os.Getenv("NO_PROXY")) | ||||||
providedNoProxy = append(providedNoProxy, os.Getenv("NO_PROXY")) | ||||||
} | ||||||
} | ||||||
if c.IsSet("http-proxy") { | ||||||
|
@@ -51,17 +56,26 @@ func getProxySpecFromFlags(c *cli.Context) *ecv1beta1.ProxySpec { | |||||
proxy.HTTPSProxy = c.String("https-proxy") | ||||||
} | ||||||
if c.String("no-proxy") != "" { | ||||||
noProxy = append(noProxy, c.String("no-proxy")) | ||||||
providedNoProxy = append(providedNoProxy, c.String("no-proxy")) | ||||||
} | ||||||
proxy.ProvidedNoProxy = strings.Join(providedNoProxy, ",") | ||||||
combineNoProxySuppliedValuesAndDefaults(c, proxy) | ||||||
if proxy.HTTPProxy == "" && proxy.HTTPSProxy == "" && proxy.NoProxy == "" { | ||||||
return nil | ||||||
} | ||||||
return proxy | ||||||
} | ||||||
|
||||||
func combineNoProxySuppliedValuesAndDefaults(c *cli.Context, proxy *ecv1beta1.ProxySpec) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. name is too long 😆, but i guess it's fine. i would've gone with something like
Suggested change
|
||||||
if proxy.ProvidedNoProxy == "" { | ||||||
return | ||||||
} | ||||||
noProxy := strings.Split(proxy.ProvidedNoProxy, ",") | ||||||
if len(noProxy) > 0 || proxy.HTTPProxy != "" || proxy.HTTPSProxy != "" { | ||||||
noProxy = append(defaults.DefaultNoProxy, noProxy...) | ||||||
noProxy = append(noProxy, c.String("pod-cidr"), c.String("service-cidr")) | ||||||
proxy.NoProxy = strings.Join(noProxy, ",") | ||||||
} | ||||||
if proxy.HTTPProxy == "" && proxy.HTTPSProxy == "" && proxy.NoProxy == "" { | ||||||
return nil | ||||||
} | ||||||
return proxy | ||||||
} | ||||||
|
||||||
// setProxyEnv sets the HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables based on the provided ProxySpec. | ||||||
|
@@ -80,3 +94,92 @@ func setProxyEnv(proxy *ecv1beta1.ProxySpec) { | |||||
os.Setenv("NO_PROXY", proxy.NoProxy) | ||||||
} | ||||||
} | ||||||
|
||||||
func maybePromptForNoProxy(c *cli.Context, proxy *ecv1beta1.ProxySpec) (*ecv1beta1.ProxySpec, error) { | ||||||
if proxy != nil && (proxy.HTTPProxy != "" || proxy.HTTPSProxy != "") { | ||||||
// if there is a proxy set, then there needs to be a no proxy set | ||||||
// if it is not set, prompt with a default (the local IP or subnet) | ||||||
// if it is set, we need to check that it covers the local IP | ||||||
defaultIPNet, err := netutils.GetDefaultIPNet() | ||||||
if err != nil { | ||||||
return nil, fmt.Errorf("failed to get default IPNet: %w", err) | ||||||
} | ||||||
cleanDefaultIPNet, err := cleanCIDR(defaultIPNet) | ||||||
if err != nil { | ||||||
return nil, fmt.Errorf("failed to clean subnet: %w", err) | ||||||
} | ||||||
if proxy.ProvidedNoProxy == "" { | ||||||
if c.Bool("no-prompt") { | ||||||
logrus.Infof("no-proxy was not set, using default no proxy %s", cleanDefaultIPNet) | ||||||
proxy.ProvidedNoProxy = cleanDefaultIPNet | ||||||
combineNoProxySuppliedValuesAndDefaults(c, proxy) | ||||||
return proxy, nil | ||||||
} else { | ||||||
return promptForNoProxy(c, proxy, cleanDefaultIPNet, defaultIPNet.IP.String(), 0) | ||||||
} | ||||||
} else { | ||||||
shouldPrompt := false | ||||||
isValid, err := validateNoProxy(proxy.NoProxy, defaultIPNet.IP.String()) | ||||||
if err != nil { | ||||||
logrus.Infof("The provided no-proxy %q failed to parse with error %q, falling back to prompt", proxy.NoProxy, err) | ||||||
shouldPrompt = true | ||||||
} else if !isValid { | ||||||
logrus.Infof("The provided no-proxy %q does not cover the local IP %q, falling back to prompt", proxy.NoProxy, defaultIPNet.IP.String()) | ||||||
shouldPrompt = true | ||||||
} | ||||||
if shouldPrompt { | ||||||
return promptForNoProxy(c, proxy, cleanDefaultIPNet, defaultIPNet.IP.String(), 0) | ||||||
} | ||||||
} | ||||||
} | ||||||
return proxy, nil | ||||||
} | ||||||
|
||||||
// cleanCIDR returns a `.0/x` subnet instead of a `.2/x` etc subnet | ||||||
func cleanCIDR(defaultIPNet *net.IPNet) (string, error) { | ||||||
_, newNet, err := net.ParseCIDR(defaultIPNet.String()) | ||||||
if err != nil { | ||||||
return "", fmt.Errorf("failed to parse local inet CIDR %q: %w", defaultIPNet.String(), err) | ||||||
} | ||||||
return newNet.String(), nil | ||||||
} | ||||||
|
||||||
func promptForNoProxy(c *cli.Context, proxy *ecv1beta1.ProxySpec, subnet, IP string, count int) (*ecv1beta1.ProxySpec, error) { | ||||||
if count == 0 { | ||||||
logrus.Infof("A no-proxy address is required when a proxy is set. We suggest either the node subnet %q or the addresses of every node that will be a member of the cluster. The current node's IP address is %q.", subnet, IP) | ||||||
} else if count >= 3 { | ||||||
return nil, fmt.Errorf("failed to prompt for no-proxy after 3 attempts") | ||||||
} | ||||||
newProxy := prompts.New().Input("No proxy:", "", true) | ||||||
isValid, err := validateNoProxy(newProxy, IP) | ||||||
if err != nil { | ||||||
logrus.Errorf("failed to validate no-proxy: %v", err) | ||||||
return promptForNoProxy(c, proxy, subnet, IP, count+1) | ||||||
} | ||||||
if !isValid { | ||||||
logrus.Errorf("provided no-proxy %q does not cover the local IP %q", newProxy, IP) | ||||||
return promptForNoProxy(c, proxy, subnet, IP, count+1) | ||||||
} | ||||||
proxy.ProvidedNoProxy = newProxy | ||||||
combineNoProxySuppliedValuesAndDefaults(c, proxy) | ||||||
return proxy, nil | ||||||
} | ||||||
|
||||||
func validateNoProxy(newNoProxy string, localIP string) (bool, error) { | ||||||
foundLocal := false | ||||||
for _, oneEntry := range strings.Split(newNoProxy, ",") { | ||||||
if oneEntry == localIP { | ||||||
foundLocal = true | ||||||
} else if strings.Contains(oneEntry, "/") { | ||||||
_, ipnet, err := net.ParseCIDR(oneEntry) | ||||||
if err != nil { | ||||||
return false, fmt.Errorf("failed to parse CIDR within no-proxy: %w", err) | ||||||
} | ||||||
if ipnet.Contains(net.ParseIP(localIP)) { | ||||||
foundLocal = true | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
return foundLocal, nil | ||||||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
take it or leave it: