mirror of
https://codeberg.org/woodpecker-plugins/go-plugin
synced 2026-06-04 10:14:59 +08:00
feat(flags): adds support for http proxy config (#82)
Reviewed-on: https://codeberg.org/woodpecker-plugins/go-plugin/pulls/82 Reviewed-by: qwerty287 <qwerty287@noreply.codeberg.org> Co-authored-by: OCram85 <marco.blessing@googlemail.com> Co-committed-by: OCram85 <marco.blessing@googlemail.com>
This commit is contained in:
@@ -9,12 +9,40 @@ HTTP client library.
|
||||
## Builtin settings
|
||||
|
||||
| Settings Name | Environment variable | Default | Description |
|
||||
| ------------- | -------------------- | ------- | ---------------------------------------------------------------------------- | ------------------------------------ |
|
||||
| ------------- | -------------------- | ------- | ---------------------------------------------------------------------------- |
|
||||
| `log_level` | - | `info` | Sets log level (`panic`, `fatal`, `error`, `warn`, `info`, `debug`, `trace`) |
|
||||
| `skip_verify` | - | `false` | - | Skip verification of TLS certificate |
|
||||
| `skip_verify` | - | `false` | Skip verification of TLS certificate |
|
||||
| | `SOCKS_PROXY` | _none_ | SOCKS5 proxy to use for connections |
|
||||
| | `SOCKS_PROXY_OFF` | _none_ | Do not use SOCKS5 proxy |
|
||||
|
||||
### Optional: HTTP proxy support
|
||||
|
||||
HTTP proxy support is **opt-in** and must be explicitly enabled by the plugin author via `EnableHTTPProxy: true` in `plugin.Options`. When enabled, the following settings become available:
|
||||
|
||||
| Settings Name | Environment variable | Default | Description |
|
||||
| ------------- | -------------------- | ------- | ------------------------------------------------------ |
|
||||
| `http_proxy` | `HTTP_PROXY` | _none_ | HTTP proxy URL for outgoing connections |
|
||||
| `https_proxy` | `HTTPS_PROXY` | _none_ | HTTPS proxy URL for outgoing connections |
|
||||
| `no_proxy` | `NO_PROXY` | _none_ | Comma-separated list of hosts to exclude from proxying |
|
||||
|
||||
The settings are resolved in the following order of precedence:
|
||||
|
||||
1. **Plugin settings** — `PLUGIN_HTTP_PROXY`, `PLUGIN_HTTPS_PROXY`, `PLUGIN_NO_PROXY`
|
||||
2. **Lowercase env vars** — `http_proxy`, `https_proxy`, `no_proxy`
|
||||
3. **Uppercase env vars** — `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`
|
||||
|
||||
Example Woodpecker CI pipeline configuration:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: my-plugin
|
||||
image: my-plugin:latest
|
||||
settings:
|
||||
http_proxy: http://proxy.example.com:3128
|
||||
https_proxy: http://proxy.example.com:3128
|
||||
no_proxy: "localhost,internal.example.com"
|
||||
```
|
||||
|
||||
## Creating plugin
|
||||
|
||||
```go
|
||||
@@ -62,10 +90,11 @@ func main() {
|
||||
}
|
||||
|
||||
p.Plugin = plugin.New(plugin.Options{
|
||||
Name: "sample-plugin",
|
||||
Description: "Sample plugin",
|
||||
Flags: p.Flags(),
|
||||
Execute: p.Execute,
|
||||
Name: "sample-plugin",
|
||||
Description: "Sample plugin",
|
||||
Flags: p.Flags(),
|
||||
Execute: p.Execute,
|
||||
EnableHTTPProxy: true, // opt-in to HTTP proxy support
|
||||
})
|
||||
|
||||
p.Run()
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"crypto/x509"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -55,13 +56,60 @@ func httpClientFlags() []cli.Flag {
|
||||
}
|
||||
}
|
||||
|
||||
func HTTPClientFromContext(c *cli.Command) *http.Client {
|
||||
// httpProxyFlags returns the optional HTTP proxy flags.
|
||||
// Only added to the app when EnableHTTPProxy is set in Options.
|
||||
func httpProxyFlags() []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "transport.http-proxy",
|
||||
Usage: "HTTP proxy URL",
|
||||
Sources: cli.EnvVars(
|
||||
"PLUGIN_HTTP_PROXY",
|
||||
),
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "transport.https-proxy",
|
||||
Usage: "HTTPS proxy URL",
|
||||
Sources: cli.EnvVars(
|
||||
"PLUGIN_HTTPS_PROXY",
|
||||
),
|
||||
Hidden: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "transport.no-proxy",
|
||||
Usage: "Hosts to exclude from proxy (comma-separated)",
|
||||
Sources: cli.EnvVars(
|
||||
"PLUGIN_NO_PROXY",
|
||||
),
|
||||
Hidden: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func HTTPClientFromContext(c *cli.Command, httpProxyEnabled bool) *http.Client {
|
||||
var (
|
||||
skip = c.Bool("transport.skip-verify")
|
||||
socks = c.String("transport.socks-proxy")
|
||||
socksOff = c.Bool("transport.socks-proxy-off")
|
||||
)
|
||||
|
||||
if httpProxyEnabled {
|
||||
if v := c.String("transport.http-proxy"); v != "" {
|
||||
os.Setenv("HTTP_PROXY", v)
|
||||
os.Setenv("http_proxy", v)
|
||||
}
|
||||
if v := c.String("transport.https-proxy"); v != "" {
|
||||
os.Setenv("HTTPS_PROXY", v)
|
||||
os.Setenv("https_proxy", v)
|
||||
|
||||
}
|
||||
if v := c.String("transport.no-proxy"); v != "" {
|
||||
os.Setenv("NO_PROXY", v)
|
||||
os.Setenv("no_proxy", v)
|
||||
}
|
||||
}
|
||||
|
||||
certs, err := x509.SystemCertPool()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to find system CA certs")
|
||||
@@ -105,4 +153,4 @@ func HTTPClientFromContext(c *cli.Command) *http.Client {
|
||||
return &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,10 @@ type Options struct {
|
||||
Execute ExecuteFunc
|
||||
// Context the plugin will use while executing.
|
||||
Context context.Context
|
||||
// EnableHTTPProxy allows plugins to opt-in to HTTP/HTTPS proxy support.
|
||||
// When true, PLUGIN_HTTP_PROXY, PLUGIN_HTTPS_PROXY and PLUGIN_NO_PROXY
|
||||
// are accepted as settings and applied to the HTTP client.
|
||||
EnableHTTPProxy bool
|
||||
}
|
||||
|
||||
// Plugin defines the plugin instance.
|
||||
@@ -46,6 +50,8 @@ type Plugin struct {
|
||||
execute ExecuteFunc
|
||||
client *http.Client
|
||||
ctx context.Context
|
||||
// enableHTTPProxy controls whether HTTP proxy flags are registered and applied.
|
||||
enableHTTPProxy bool
|
||||
// Metadata of the current pipeline.
|
||||
Metadata Metadata
|
||||
}
|
||||
@@ -68,10 +74,16 @@ func New(opt Options) *Plugin {
|
||||
}
|
||||
|
||||
plugin := &Plugin{
|
||||
App: app,
|
||||
execute: opt.Execute,
|
||||
ctx: opt.Context,
|
||||
App: app,
|
||||
execute: opt.Execute,
|
||||
ctx: opt.Context,
|
||||
enableHTTPProxy: opt.EnableHTTPProxy,
|
||||
}
|
||||
|
||||
if opt.EnableHTTPProxy {
|
||||
app.Flags = append(app.Flags, httpProxyFlags()...)
|
||||
}
|
||||
|
||||
plugin.App.Action = plugin.action
|
||||
|
||||
if plugin.ctx == nil {
|
||||
@@ -87,7 +99,7 @@ func (p *Plugin) action(ctx context.Context, c *cli.Command) error {
|
||||
}
|
||||
|
||||
p.Metadata = MetadataFromContext(c)
|
||||
p.client = HTTPClientFromContext(c)
|
||||
p.client = HTTPClientFromContext(c, p.enableHTTPProxy)
|
||||
|
||||
if p.execute == nil {
|
||||
panic("plugin execute function is not set")
|
||||
@@ -107,4 +119,4 @@ func (p *Plugin) Run() {
|
||||
log.Error().Err(err).Msg("execution failed")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user