Skip to content

Commit 5836f6f

Browse files
add NewClientWithProxy for client with proxy authentication
1 parent 5dddfb4 commit 5836f6f

File tree

8 files changed

+741
-74
lines changed

8 files changed

+741
-74
lines changed

download/downloader.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
"github.com/onsi/gomega/gbytes"
1515
"github.com/pivotal-cf/go-pivnet/v7/logger"
16-
"github.com/shirou/gopsutil/disk"
16+
"github.com/shirou/gopsutil/v3/disk"
1717
"golang.org/x/sync/errgroup"
1818
)
1919

example/proxy_basic_auth.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ func main() {
5555
// Create access token
5656
token := pivnet.NewAccessTokenOrLegacyToken(apiToken, config.Host, config.SkipSSLValidation)
5757

58-
// Create the client
59-
client := pivnet.NewClient(token, config, logger)
58+
// Create the client with proxy support
59+
client, err := pivnet.NewClientWithProxy(token, config, logger)
60+
if err != nil {
61+
log.Fatalf("Failed to create client with proxy: %v", err)
62+
}
6063

6164
// Example: List all products
6265
fmt.Println("Fetching products through authenticated proxy...")
@@ -89,4 +92,3 @@ func main() {
8992

9093
fmt.Println("\n✅ Basic proxy authentication example completed successfully!")
9194
}
92-

example/proxy_spnego_auth.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func main() {
5959
// Create access token
6060
token := pivnet.NewAccessTokenOrLegacyToken(apiToken, config.Host, config.SkipSSLValidation)
6161

62-
// Create the client
62+
// Create the client with proxy support
6363
fmt.Println("Initializing client with SPNEGO proxy authentication...")
6464
fmt.Printf("Proxy URL: %s\n", proxyURL)
6565
fmt.Printf("Username: %s\n", proxyUsername)
@@ -69,7 +69,10 @@ func main() {
6969
fmt.Println("Kerberos Config: Using default config")
7070
}
7171

72-
client := pivnet.NewClient(token, config, logger)
72+
client, err := pivnet.NewClientWithProxy(token, config, logger)
73+
if err != nil {
74+
log.Fatalf("Failed to create client with proxy: %v", err)
75+
}
7376

7477
// Example: List all products
7578
fmt.Println("\nFetching products through SPNEGO authenticated proxy...")
@@ -113,4 +116,3 @@ func main() {
113116

114117
fmt.Println("\n✅ SPNEGO proxy authentication example completed successfully!")
115118
}
116-

go.mod

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
module github.com/pivotal-cf/go-pivnet/v7
22

33
require (
4-
github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f // indirect
54
github.com/fatih/color v1.7.0 // indirect
6-
github.com/go-ole/go-ole v0.0.0-20180625085808-7a0fa49edf48 // indirect
75
github.com/jcmturner/gokrb5/v8 v8.4.4
86
github.com/kr/pretty v0.1.0 // indirect
97
github.com/mattn/go-colorable v0.0.9 // indirect
@@ -12,7 +10,7 @@ require (
1210
github.com/onsi/ginkgo v1.6.0
1311
github.com/onsi/gomega v1.4.2
1412
github.com/robdimsdale/sanitizer v0.0.0-20160522134901-ab2334cb7539
15-
github.com/shirou/gopsutil v0.0.0-20180927124308-a11c78ba2c13
13+
github.com/shirou/gopsutil/v3 v3.24.5
1614
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
1715
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
1816
gopkg.in/cheggaaa/pb.v1 v1.0.26

go.sum

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f h1:5ZfJxyXo8KyX8DgGXC5B7ILL8y51fci/qYz2B4j8iLY=
2-
github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
31
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
42
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
53
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
64
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
75
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
86
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
97
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
10-
github.com/go-ole/go-ole v0.0.0-20180625085808-7a0fa49edf48 h1:WRF1REuysYJdbHUefXfrTuwYdeuCYjjKdm0Kvu8n8fk=
11-
github.com/go-ole/go-ole v0.0.0-20180625085808-7a0fa49edf48/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
8+
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
9+
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
1210
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
1311
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
12+
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
13+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
14+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1415
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
1516
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
1617
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
@@ -37,6 +38,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
3738
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
3839
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
3940
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
41+
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
4042
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
4143
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
4244
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
@@ -49,19 +51,30 @@ github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
4951
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
5052
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5153
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
54+
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
55+
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
5256
github.com/robdimsdale/sanitizer v0.0.0-20160522134901-ab2334cb7539 h1:h3AVw1v3JIE9Y1HyjYyiPTG73ywlF4754oiIjkxPjNk=
5357
github.com/robdimsdale/sanitizer v0.0.0-20160522134901-ab2334cb7539/go.mod h1:tqCODtkKV+9Tfvt9JURvKCTxJ69bA/OU/QhsaQLK/rc=
54-
github.com/shirou/gopsutil v0.0.0-20180927124308-a11c78ba2c13 h1:hzFIj+Ky1KX599VGAVY//20nam1rYKwQwNVix1sYhXo=
55-
github.com/shirou/gopsutil v0.0.0-20180927124308-a11c78ba2c13/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
58+
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
59+
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
60+
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
61+
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
5662
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
5763
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
5864
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
65+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
5966
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
6067
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
6168
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
62-
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
6369
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
70+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
71+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
72+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
73+
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
74+
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
6475
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
76+
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
77+
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
6578
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
6679
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
6780
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
@@ -81,12 +94,17 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+v
8194
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8295
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
8396
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
97+
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8498
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
99+
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
85100
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
86101
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
87102
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
88-
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
89103
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
104+
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
105+
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
106+
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
107+
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
90108
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
91109
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
92110
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -99,6 +117,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
99117
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
100118
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
101119
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
120+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
102121
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
103122
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
104123
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

pivnet.go

Lines changed: 109 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -124,65 +124,83 @@ func NewAccessTokenOrLegacyToken(token string, host string, skipSSLValidation bo
124124
}
125125
}
126126

127+
// createProxyAuthTransport creates an HTTP transport with proxy authentication
128+
func createProxyAuthTransport(config ClientConfig) (http.RoundTripper, error) {
129+
// Validate required fields for proxy authentication
130+
if config.ProxyAuthConfig.ProxyURL == "" || config.ProxyAuthConfig.Username == "" || config.ProxyAuthConfig.Password == "" {
131+
return nil, fmt.Errorf("proxy URL, username, and password are required when proxy authentication is specified")
132+
}
133+
134+
// Parse proxy URL
135+
proxyURL, err := url.Parse(config.ProxyAuthConfig.ProxyURL)
136+
if err != nil {
137+
return nil, fmt.Errorf("failed to parse proxy URL: %w", err)
138+
}
139+
140+
// Create base transport
141+
transport := &http.Transport{
142+
TLSClientConfig: &tls.Config{
143+
InsecureSkipVerify: config.SkipSSLValidation,
144+
},
145+
Proxy: http.ProxyURL(proxyURL),
146+
}
147+
148+
// Create authenticator
149+
authenticator, err := NewProxyAuthenticator(config.ProxyAuthConfig)
150+
if err != nil {
151+
return nil, fmt.Errorf("failed to create proxy authenticator: %w", err)
152+
}
153+
154+
// Wrap transport with proxy authentication
155+
proxyAuthTransport, err := NewProxyAuthTransport(transport, authenticator)
156+
if err != nil {
157+
return nil, fmt.Errorf("failed to initialize proxy authentication: %w", err)
158+
}
159+
return proxyAuthTransport, nil
160+
}
161+
162+
// initializeClientServices initializes all service endpoints for the client
163+
func initializeClientServices(client *Client, lgr logger.Logger) {
164+
client.Auth = &AuthService{client: *client}
165+
client.EULA = &EULAsService{client: *client}
166+
client.ProductFiles = &ProductFilesService{client: *client}
167+
client.ArtifactReferences = &ArtifactReferencesService{client: *client}
168+
client.FederationToken = &FederationTokenService{client: *client}
169+
client.FileGroups = &FileGroupsService{client: *client}
170+
client.Releases = &ReleasesService{client: *client, l: lgr}
171+
client.Products = &ProductsService{client: *client, l: lgr}
172+
client.UserGroups = &UserGroupsService{client: *client}
173+
client.SubscriptionGroups = &SubscriptionGroupsService{client: *client}
174+
client.ReleaseTypes = &ReleaseTypesService{client: *client}
175+
client.ReleaseDependencies = &ReleaseDependenciesService{client: *client}
176+
client.DependencySpecifiers = &DependencySpecifiersService{client: *client}
177+
client.ReleaseUpgradePaths = &ReleaseUpgradePathsService{client: *client}
178+
client.UpgradePathSpecifiers = &UpgradePathSpecifiersService{client: *client}
179+
client.PivnetVersions = &PivnetVersionsService{client: *client}
180+
}
181+
127182
func NewClient(
128183
token AccessTokenService,
129184
config ClientConfig,
130185
lgr logger.Logger,
131186
) Client {
132187
baseURL := fmt.Sprintf("%s%s", config.Host, apiVersion)
133188

134-
// Create proxy function based on ProxyAuthConfig or environment
135-
proxyFunc := http.ProxyFromEnvironment
136-
if config.ProxyAuthConfig.ProxyURL != "" {
137-
proxyURL, err := url.Parse(config.ProxyAuthConfig.ProxyURL)
138-
if err != nil {
139-
lgr.Info("Failed to parse proxy URL, falling back to environment proxy", logger.Data{"error": err.Error(), "proxy_url": config.ProxyAuthConfig.ProxyURL})
140-
} else {
141-
proxyFunc = http.ProxyURL(proxyURL)
142-
}
143-
}
144-
145-
// Create base transport for connection pooling
146189
baseTransport := &http.Transport{
147190
TLSClientConfig: &tls.Config{
148191
InsecureSkipVerify: config.SkipSSLValidation,
149192
},
150-
Proxy: proxyFunc,
193+
Proxy: http.ProxyFromEnvironment,
151194
}
152195

153-
// Wrap with proxy authentication if configured
154-
httpTransport := http.RoundTripper(baseTransport)
155-
if config.ProxyAuthConfig.AuthType != "" {
156-
if config.ProxyAuthConfig.ProxyURL == "" {
157-
lgr.Info("Proxy URL is required when proxy authentication is specified", logger.Data{"auth_type": string(config.ProxyAuthConfig.AuthType)})
158-
} else if config.ProxyAuthConfig.Username == "" {
159-
lgr.Info("Proxy username is required when proxy authentication is specified", logger.Data{"auth_type": string(config.ProxyAuthConfig.AuthType)})
160-
} else if config.ProxyAuthConfig.Password == "" {
161-
lgr.Info("Proxy password is required when proxy authentication is specified", logger.Data{"auth_type": string(config.ProxyAuthConfig.AuthType)})
162-
} else {
163-
authenticator, err := NewProxyAuthenticator(config.ProxyAuthConfig)
164-
if err != nil {
165-
lgr.Info("Failed to create proxy authenticator", logger.Data{"error": err.Error(), "auth_type": string(config.ProxyAuthConfig.AuthType)})
166-
} else {
167-
proxyAuthTransport, err := NewProxyAuthTransport(baseTransport, authenticator)
168-
if err != nil {
169-
lgr.Info("Failed to initialize proxy authentication", logger.Data{"error": err.Error(), "auth_type": string(config.ProxyAuthConfig.AuthType)})
170-
} else {
171-
httpTransport = proxyAuthTransport
172-
}
173-
}
174-
}
175-
}
176-
177-
// Create HTTP client and download client with the same transport
178196
httpClient := &http.Client{
179197
Timeout: 10 * time.Minute,
180-
Transport: httpTransport,
198+
Transport: baseTransport,
181199
}
182200

183201
downloadClient := &http.Client{
184202
Timeout: 0,
185-
Transport: httpTransport,
203+
Transport: baseTransport,
186204
}
187205

188206
ranger := download.NewRanger(concurrentDownloads)
@@ -202,26 +220,61 @@ func NewClient(
202220
HTTP: httpClient,
203221
}
204222

205-
client.Auth = &AuthService{client: client}
206-
client.EULA = &EULAsService{client: client}
207-
client.ProductFiles = &ProductFilesService{client: client}
208-
client.ArtifactReferences = &ArtifactReferencesService{client: client}
209-
client.FederationToken = &FederationTokenService{client: client}
210-
client.FileGroups = &FileGroupsService{client: client}
211-
client.Releases = &ReleasesService{client: client, l: lgr}
212-
client.Products = &ProductsService{client: client, l: lgr}
213-
client.UserGroups = &UserGroupsService{client: client}
214-
client.SubscriptionGroups = &SubscriptionGroupsService{client: client}
215-
client.ReleaseTypes = &ReleaseTypesService{client: client}
216-
client.ReleaseDependencies = &ReleaseDependenciesService{client: client}
217-
client.DependencySpecifiers = &DependencySpecifiersService{client: client}
218-
client.ReleaseUpgradePaths = &ReleaseUpgradePathsService{client: client}
219-
client.UpgradePathSpecifiers = &UpgradePathSpecifiersService{client: client}
220-
client.PivnetVersions = &PivnetVersionsService{client: client}
223+
initializeClientServices(&client, lgr)
221224

222225
return client
223226
}
224227

228+
// NewClientWithProxy creates a new Pivnet client with optional proxy authentication support
229+
func NewClientWithProxy(
230+
token AccessTokenService,
231+
config ClientConfig,
232+
lgr logger.Logger,
233+
) (Client, error) {
234+
var transport http.RoundTripper
235+
var err error
236+
237+
// If proxy authentication is configured, use it; otherwise use standard transport
238+
if config.ProxyAuthConfig.AuthType != "" {
239+
transport, err = createProxyAuthTransport(config)
240+
if err != nil {
241+
return Client{}, err
242+
}
243+
} else {
244+
// Use standard transport with environment proxy support
245+
transport = &http.Transport{
246+
TLSClientConfig: &tls.Config{
247+
InsecureSkipVerify: config.SkipSSLValidation,
248+
},
249+
Proxy: http.ProxyFromEnvironment,
250+
}
251+
}
252+
253+
client := Client{
254+
baseURL: fmt.Sprintf("%s%s", config.Host, apiVersion),
255+
token: token,
256+
userAgent: config.UserAgent,
257+
logger: lgr,
258+
HTTP: &http.Client{
259+
Timeout: 10 * time.Minute,
260+
Transport: transport,
261+
},
262+
downloader: download.Client{
263+
HTTPClient: &http.Client{
264+
Timeout: 0,
265+
Transport: transport,
266+
},
267+
Ranger: download.NewRanger(concurrentDownloads),
268+
Logger: lgr,
269+
Timeout: 30 * time.Second,
270+
},
271+
}
272+
273+
initializeClientServices(&client, lgr)
274+
275+
return client, nil
276+
}
277+
225278
func (c Client) CreateRequest(
226279
requestType string,
227280
endpoint string,

0 commit comments

Comments
 (0)