Add `shell-proxy` plugin (#8692)
parent
aada4d62bf
commit
5ea25e6736
5 changed files with 174 additions and 0 deletions
@ -0,0 +1,52 @@ |
|||||||
|
# Shell Proxy oh-my-zsh plugin |
||||||
|
|
||||||
|
This a pure user-space program, shell-proxy setter, written Python3 and Bash. |
||||||
|
|
||||||
|
100% only no side-effects, only effect **environment variables** and **aliases** |
||||||
|
|
||||||
|
## Key feature |
||||||
|
|
||||||
|
- Support Ubuntu, Archlinux, etc (Linux) |
||||||
|
- Support macOS |
||||||
|
- Support git via based-`$GIT_SSH` |
||||||
|
- Support ssh, sftp, scp, slogin and ssh-copy-id via based-`alias` |
||||||
|
- Built-in Auto-complete |
||||||
|
|
||||||
|
## Usage |
||||||
|
|
||||||
|
Method 1: |
||||||
|
|
||||||
|
`$DEFAULT_PROXY` is the proxy URL you will set |
||||||
|
|
||||||
|
Method 2: |
||||||
|
|
||||||
|
Write a program to `$HOME/.config/proxy` in the file. |
||||||
|
|
||||||
|
Example program: |
||||||
|
|
||||||
|
```bash |
||||||
|
#!/bin/bash |
||||||
|
# The file path: $HOME/.config/proxy |
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then |
||||||
|
echo "http://127.0.0.1:6152" # Surge Mac |
||||||
|
else |
||||||
|
echo "http://127.0.0.1:8123" # polipo |
||||||
|
fi |
||||||
|
``` |
||||||
|
|
||||||
|
Method 3: |
||||||
|
|
||||||
|
The working path of **Method 2** can be changed via `$CONFIG_PROXY` |
||||||
|
|
||||||
|
## Reference |
||||||
|
|
||||||
|
- `$GIT_SSH`: <https://www.git-scm.com/docs/git#Documentation/git.txt-codeGITSSHcode> |
||||||
|
- OpenSSH manual: <https://man.openbsd.org/ssh> |
||||||
|
|
||||||
|
## Maintainer |
||||||
|
|
||||||
|
- <https://github.com/septs> |
||||||
|
|
||||||
|
## The oh-my-zsh plugin (shell-proxy) |
||||||
|
|
||||||
|
Public Domain |
||||||
@ -0,0 +1,72 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import os |
||||||
|
import sys |
||||||
|
from subprocess import check_output, list2cmdline |
||||||
|
|
||||||
|
cwd = os.path.dirname(__file__) |
||||||
|
ssh_agent = os.path.join(cwd, "ssh-agent.py") |
||||||
|
user_proxy = os.environ.get("CONFIG_PROXY", os.path.expandvars("$HOME/.config/proxy")) |
||||||
|
|
||||||
|
|
||||||
|
def get_http_proxy(): |
||||||
|
if "DEFAULT_PROXY" in os.environ: |
||||||
|
return os.environ["DEFAULT_PROXY"] |
||||||
|
if os.path.isfile(user_proxy): |
||||||
|
return check_output(user_proxy).decode("utf-8").strip() |
||||||
|
raise Exception("Not found, Proxy configuration") |
||||||
|
|
||||||
|
|
||||||
|
def make_proxies(url: str): |
||||||
|
proxies = {"%s_PROXY" % _: url for _ in ("HTTP", "HTTPS", "FTP", "RSYNC", "ALL")} |
||||||
|
proxies.update({name.lower(): value for (name, value) in proxies.items()}) |
||||||
|
proxies["GIT_SSH"] = ssh_agent |
||||||
|
return proxies |
||||||
|
|
||||||
|
|
||||||
|
def merge(mapping: dict): |
||||||
|
return ("%s=%s" % _ for _ in mapping.items()) |
||||||
|
|
||||||
|
|
||||||
|
class CommandSet: |
||||||
|
proxies = make_proxies(get_http_proxy()) |
||||||
|
aliases = { |
||||||
|
_: "env NAME=%s %s" % (_, ssh_agent) |
||||||
|
for _ in ("ssh", "sftp", "scp", "slogin", "ssh-copy-id") |
||||||
|
} |
||||||
|
|
||||||
|
def enable(self): |
||||||
|
cmdline("export", *merge(self.proxies)) |
||||||
|
cmdline("alias", *merge(self.aliases)) |
||||||
|
|
||||||
|
def disable(self): |
||||||
|
cmdline("unset", *self.proxies.keys()) |
||||||
|
cmdline("unalias", *self.aliases.keys()) |
||||||
|
|
||||||
|
def status(self): |
||||||
|
proxies = ( |
||||||
|
"%11s = %s" % (name, os.environ[name]) |
||||||
|
for name in self.proxies.keys() |
||||||
|
if name in os.environ |
||||||
|
) |
||||||
|
for _ in proxies: |
||||||
|
cmdline("echo", _) |
||||||
|
|
||||||
|
def usage(self): |
||||||
|
cmdline("echo", "usage: proxy {enable,disable,status}") |
||||||
|
self.status() |
||||||
|
|
||||||
|
|
||||||
|
def cmdline(*items): |
||||||
|
print(list2cmdline(items)) |
||||||
|
|
||||||
|
|
||||||
|
def main(): |
||||||
|
command = CommandSet() |
||||||
|
if len(sys.argv) == 1: |
||||||
|
command.usage() |
||||||
|
sys.exit(-1) |
||||||
|
getattr(command, sys.argv[1], command.usage)() |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
main() |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
#!/usr/bin/bash |
||||||
|
# shellcheck disable=SC1090 |
||||||
|
|
||||||
|
__PROXY__="${0:A:h}/proxy.py" |
||||||
|
|
||||||
|
proxy() { |
||||||
|
source <("$__PROXY__" "$1") |
||||||
|
} |
||||||
|
|
||||||
|
_proxy() { |
||||||
|
local -r commands=('enable' 'disable' 'status') |
||||||
|
compset -P '*,' |
||||||
|
compadd -S '' "${commands[@]}" |
||||||
|
} |
||||||
|
|
||||||
|
compdef '_proxy' 'proxy' |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import os |
||||||
|
import subprocess |
||||||
|
import sys |
||||||
|
|
||||||
|
ssh_proxy = os.path.join(os.path.dirname(__file__), "ssh-proxy.py") |
||||||
|
|
||||||
|
argv = [ |
||||||
|
os.environ.get("NAME", "ssh"), |
||||||
|
"-o", |
||||||
|
"ProxyCommand={} %h %p".format(ssh_proxy), |
||||||
|
"-o", |
||||||
|
"Compression=yes", |
||||||
|
] |
||||||
|
|
||||||
|
subprocess.call(argv + sys.argv[1:], env=os.environ) |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import os |
||||||
|
import subprocess |
||||||
|
import sys |
||||||
|
import urllib.parse |
||||||
|
|
||||||
|
proxy = next(os.environ[_] for _ in ("HTTP_PROXY", "HTTPS_PROXY") if _ in os.environ) |
||||||
|
argv = [ |
||||||
|
"nc", |
||||||
|
"-X", |
||||||
|
"connect", |
||||||
|
"-x", |
||||||
|
urllib.parse.urlparse(proxy).netloc, # proxy-host:proxy-port |
||||||
|
sys.argv[1], # host |
||||||
|
sys.argv[2], # port |
||||||
|
] |
||||||
|
|
||||||
|
subprocess.call(argv) |
||||||
Loading…
Reference in new issue