Skip to content

Commit

Permalink
feat: Add proxy support to Argo CLI API client
Browse files Browse the repository at this point in the history
Signed-off-by: sakamoto <[email protected]>
  • Loading branch information
sakamoto authored and sakamoto committed Jan 16, 2024
1 parent de53da8 commit d78c157
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
13 changes: 13 additions & 0 deletions cmd/argo/commands/client/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package client
import (
"context"
"fmt"
"net/http"
"net/url"
"os"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -55,6 +57,15 @@ func AddAPIClientFlagsToCmd(cmd *cobra.Command) {
}

func NewAPIClient(ctx context.Context) (context.Context, apiclient.Client) {
var proxy func(*http.Request) (*url.URL, error)
if overrides.ClusterInfo.ProxyURL != "" {
proxyURL, err := url.Parse(overrides.ClusterInfo.ProxyURL)
if err != nil {
log.Fatal(err)
}
proxy = http.ProxyURL(proxyURL)
}

ctx, client, err := apiclient.NewClientFromOpts(
apiclient.Opts{
ArgoServerOpts: ArgoServerOpts,
Expand All @@ -66,6 +77,7 @@ func NewAPIClient(ctx context.Context) (context.Context, apiclient.Client) {
Offline: Offline,
OfflineFiles: OfflineFiles,
Context: ctx,
Proxy: proxy,
})
if err != nil {
log.Fatal(err)
Expand All @@ -88,6 +100,7 @@ func Namespace() string {
if err != nil {
log.Fatal(err)
}

return namespace
}

Expand Down
6 changes: 5 additions & 1 deletion pkg/apiclient/apiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package apiclient
import (
"context"
"fmt"
"net/http"
"net/url"

log "github.com/sirupsen/logrus"
"k8s.io/client-go/tools/clientcmd"
Expand Down Expand Up @@ -35,6 +37,7 @@ type Opts struct {
Offline bool
OfflineFiles []string
Context context.Context
Proxy func(*http.Request) (*url.URL, error)
}

func (o Opts) String() string {
Expand Down Expand Up @@ -73,7 +76,8 @@ func NewClientFromOpts(opts Opts) (context.Context, Client, error) {
if opts.AuthSupplier == nil {
return nil, nil, fmt.Errorf("AuthSupplier cannot be empty when connecting to Argo Server")
}
return newHTTP1Client(opts.ArgoServerOpts.GetURL(), opts.AuthSupplier(), opts.ArgoServerOpts.InsecureSkipVerify, opts.ArgoServerOpts.Headers)

return newHTTP1Client(opts.ArgoServerOpts.GetURL(), opts.AuthSupplier(), opts.ArgoServerOpts.InsecureSkipVerify, opts.ArgoServerOpts.Headers, opts.Proxy)
} else if opts.ArgoServerOpts.URL != "" {
if opts.AuthSupplier == nil {
return nil, nil, fmt.Errorf("AuthSupplier cannot be empty when connecting to Argo Server")
Expand Down
6 changes: 4 additions & 2 deletions pkg/apiclient/http1-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package apiclient

import (
"context"
"net/http"
"net/url"

"github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate"
cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow"
Expand Down Expand Up @@ -40,6 +42,6 @@ func (h httpClient) NewInfoServiceClient() (infopkg.InfoServiceClient, error) {
return http1.InfoServiceClient(h), nil
}

func newHTTP1Client(baseUrl string, auth string, insecureSkipVerify bool, headers []string) (context.Context, Client, error) {
return context.Background(), httpClient(http1.NewFacade(baseUrl, auth, insecureSkipVerify, headers)), nil
func newHTTP1Client(baseUrl string, auth string, insecureSkipVerify bool, headers []string, proxy func(*http.Request) (*url.URL, error)) (context.Context, Client, error) {
return context.Background(), httpClient(http1.NewFacade(baseUrl, auth, insecureSkipVerify, headers, proxy)), nil
}
19 changes: 17 additions & 2 deletions pkg/apiclient/http1/facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ type Facade struct {
authorization string
insecureSkipVerify bool
headers []string
proxy func(*http.Request) (*url.URL, error)
}

func NewFacade(baseUrl, authorization string, insecureSkipVerify bool, headers []string) Facade {
return Facade{baseUrl, authorization, insecureSkipVerify, headers}
func NewFacade(baseUrl, authorization string, insecureSkipVerify bool, headers []string, proxy func(*http.Request) (*url.URL, error)) Facade {
return Facade{baseUrl, authorization, insecureSkipVerify, headers, proxy}
}

func (h Facade) Get(in, out interface{}, path string) error {
Expand Down Expand Up @@ -65,6 +66,7 @@ func (h Facade) EventStreamReader(in interface{}, path string) (*bufio.Reader, e
req.Header.Set("Accept", "text/event-stream")
req.Header.Set("Authorization", h.authorization)
log.Debugf("curl -H 'Accept: text/event-stream' -H 'Authorization: ******' '%v'", u)

client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
Expand Down Expand Up @@ -108,8 +110,21 @@ func (h Facade) do(in interface{}, out interface{}, method string, path string)
req.Header = headers
req.Header.Set("Authorization", h.authorization)
log.Debugf("curl -X %s -H 'Authorization: ******' -d '%s' '%v'", method, string(data), u)

proxy := http.ProxyFromEnvironment

if h.proxy != nil {
proxy = h.proxy
}

proxyURL, err := proxy(req)
if err != nil {
return err
}

client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
TLSClientConfig: &tls.Config{
InsecureSkipVerify: h.insecureSkipVerify,
},
Expand Down

0 comments on commit d78c157

Please sign in to comment.