-
Notifications
You must be signed in to change notification settings - Fork 24
Add NO_PROXY support for automatic proxy bypass based on target host #114
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||||||||||||||||||||||||||||||||||||
| import re | ||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| def check_is_file(destination): | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -64,3 +65,29 @@ def conditionalReplace( aMatch ) : | |||||||||||||||||||||||||||||||||||||||||
| result = '"' + result + '"' | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return result+' ' | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| def configure_proxy(arguments, winrmproxy, winrmnoproxy, endpoint, log): | ||||||||||||||||||||||||||||||||||||||||||
| from requests.utils import should_bypass_proxies | ||||||||||||||||||||||||||||||||||||||||||
|
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. This import will cause a runtime crash on environments running requests < 2.14.0. We need to wrap this in a try/except block to make the plugin stable for older systems.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if winrmproxy: | ||||||||||||||||||||||||||||||||||||||||||
| if winrmnoproxy: | ||||||||||||||||||||||||||||||||||||||||||
| # Delegate to requests via env vars so NO_PROXY matching works | ||||||||||||||||||||||||||||||||||||||||||
| os.environ['HTTP_PROXY'] = winrmproxy | ||||||||||||||||||||||||||||||||||||||||||
| os.environ['HTTPS_PROXY'] = winrmproxy | ||||||||||||||||||||||||||||||||||||||||||
| os.environ['NO_PROXY'] = winrmnoproxy | ||||||||||||||||||||||||||||||||||||||||||
| log.debug("Proxy via env vars: HTTP(S)_PROXY=%s, NO_PROXY=%s" % (winrmproxy, winrmnoproxy)) | ||||||||||||||||||||||||||||||||||||||||||
|
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. Let's avoid logging the raw proxy URL here to prevent leaking plain-text passwords in the debug logs.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if should_bypass_proxies(endpoint, no_proxy=winrmnoproxy): | ||||||||||||||||||||||||||||||||||||||||||
| log.info("Connecting to %s DIRECTLY (matched NO_PROXY: %s)" % (endpoint, winrmnoproxy)) | ||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+81
to
+83
|
||||||||||||||||||||||||||||||||||||||||||
| log.info("Connecting to %s via PROXY (%s)" % (endpoint, winrmproxy)) | ||||||||||||||||||||||||||||||||||||||||||
|
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. Let's use the _redact_proxy_url helper here. This safely hides the password but still shows the proxy host in the logs
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||
| # Legacy: explicit proxy for all connections | ||||||||||||||||||||||||||||||||||||||||||
| arguments["proxy"] = winrmproxy | ||||||||||||||||||||||||||||||||||||||||||
| log.info("Connecting to %s via PROXY (%s)" % (endpoint, winrmproxy)) | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+84
to
+88
|
||||||||||||||||||||||||||||||||||||||||||
| log.debug("Proxy via env vars: HTTP(S)_PROXY=%s, NO_PROXY=%s" % (winrmproxy, winrmnoproxy)) | |
| if should_bypass_proxies(endpoint, no_proxy=winrmnoproxy): | |
| log.info("Connecting to %s DIRECTLY (matched NO_PROXY: %s)" % (endpoint, winrmnoproxy)) | |
| else: | |
| log.info("Connecting to %s via PROXY (%s)" % (endpoint, winrmproxy)) | |
| else: | |
| # Legacy: explicit proxy for all connections | |
| arguments["proxy"] = winrmproxy | |
| log.info("Connecting to %s via PROXY (%s)" % (endpoint, winrmproxy)) | |
| log.debug("Proxy via env vars: HTTP(S)_PROXY set, NO_PROXY=%s" % winrmnoproxy) | |
| if should_bypass_proxies(endpoint, no_proxy=winrmnoproxy): | |
| log.info("Connecting to %s DIRECTLY (matched NO_PROXY: %s)" % (endpoint, winrmnoproxy)) | |
| else: | |
| log.info("Connecting to %s via PROXY" % endpoint) | |
| else: | |
| # Legacy: explicit proxy for all connections | |
| arguments["proxy"] = winrmproxy | |
| log.info("Connecting to %s via PROXY" % endpoint) |
Copilot
AI
Mar 6, 2026
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.
This branch logs "DIRECTLY (no proxy configured)", but the request may still go through a proxy if the Rundeck process already has HTTP(S)_PROXY set in its environment (requests/pywinrm will honor env proxies by default). Consider either (a) adjusting the message to clarify it's only about plugin config (not actual routing), or (b) detecting existing env proxies and logging the effective routing more accurately.
| log.info("Connecting to %s DIRECTLY (no proxy configured)" % endpoint) | |
| # No proxy configured via plugin; check for environment proxies that requests/pywinrm may still use | |
| http_proxy = os.environ.get('HTTP_PROXY') or os.environ.get('http_proxy') | |
| https_proxy = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy') | |
| if http_proxy or https_proxy: | |
| log.info( | |
| "Connecting to %s via PROXY from environment (HTTP_PROXY=%s, HTTPS_PROXY=%s)" | |
| % (endpoint, http_proxy, https_proxy) | |
| ) | |
| else: | |
| log.info( | |
| "Connecting to %s DIRECTLY (no proxy configured in plugin or environment)" % endpoint | |
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,15 @@ providers: | |
| renderingOptions: | ||
| groupName: Connection | ||
| instance-scope-node-attribute: "winrm-proxy" | ||
| - name: winrmnoproxy | ||
| title: No Proxy List | ||
| description: "Comma-separated list of hosts/IPs/CIDRs that bypass the proxy. Supports exact IPs, CIDR notation (192.168.1.0/24), domain suffixes (.internal.corp), and wildcard (*). Requires Proxy to also be set. It can be overwriting at node level using `winrm-noproxy`" | ||
| type: String | ||
|
Comment on lines
+113
to
+116
|
||
| required: false | ||
| scope: Instance | ||
| renderingOptions: | ||
| groupName: Connection | ||
| instance-scope-node-attribute: "winrm-noproxy" | ||
| - name: operationtimeout | ||
| title: operation timeout | ||
| description: "maximum allowed time in seconds for any single wsman HTTP operation (default 20). Note that operation timeouts while receiving output (the only wsman operation that should take any significant time, and where these timeouts are expected) will be silently retried indefinitely. It can be overwriting at node level using `winrm-operationtimeout`" | ||
|
|
@@ -380,6 +389,15 @@ providers: | |
| renderingOptions: | ||
| groupName: Connection | ||
| instance-scope-node-attribute: "winrm-proxy" | ||
| - name: winrmnoproxy | ||
| title: No Proxy List | ||
| description: "Comma-separated list of hosts/IPs/CIDRs that bypass the proxy. Supports exact IPs, CIDR notation (192.168.1.0/24), domain suffixes (.internal.corp), and wildcard (*). Requires Proxy to also be set. It can be overwriting at node level using `winrm-noproxy`" | ||
| type: String | ||
|
Comment on lines
+392
to
+395
|
||
| required: false | ||
| scope: Instance | ||
| renderingOptions: | ||
| groupName: Connection | ||
| instance-scope-node-attribute: "winrm-noproxy" | ||
| - name: enabledhttpdebug | ||
| title: Enable HTTP logging in debug mode | ||
| description: "Print extra http logging in debug mode" | ||
|
|
@@ -417,7 +435,7 @@ providers: | |
| plugin-type: script | ||
| script-interpreter: ${config.interpreter} -u | ||
| script-file: winrm-check.py | ||
| script-args: --username ${config.username} --hostname ${config.hostname} --password ${config.password_storage_path} --authentication ${config.authtype} --transport ${config.winrmtransport} --port ${config.winrmport} --nossl ${config.nossl} --debug ${config.debug} --certpath ${config.certpath} | ||
| script-args: --username ${config.username} --hostname ${config.hostname} --password ${config.password_storage_path} --authentication ${config.authtype} --transport ${config.winrmtransport} --port ${config.winrmport} --nossl ${config.nossl} --debug ${config.debug} --certpath ${config.certpath} --proxy ${config.winrmproxy} --noproxy ${config.winrmnoproxy} | ||
| config: | ||
| - name: interpreter | ||
| title: Python Interpreter | ||
|
|
@@ -512,4 +530,14 @@ providers: | |
| default: "false" | ||
| required: false | ||
| renderingOptions: | ||
| groupName: Kerberos | ||
| groupName: Kerberos | ||
| - name: winrmproxy | ||
| title: Proxy | ||
| description: "Specify a proxy address for communicating with Windows nodes. Example HTTP proxy strings are http://server:port and http://user:pass@server:port. An example SOCKS5 proxy string is socks5://user:pass@server:port." | ||
| type: String | ||
| required: false | ||
| - name: winrmnoproxy | ||
| title: No Proxy List | ||
| description: "Comma-separated list of hosts/IPs/CIDRs that bypass the proxy. Supports exact IPs, CIDR notation (192.168.1.0/24), domain suffixes (.internal.corp), and wildcard (*)." | ||
| type: String | ||
| required: false | ||
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.
We need to add a credential redaction helper here to ensure we don't leak proxy passwords into the Rundeck logs.