@@ -182,6 +182,11 @@ type ServiceConfig struct {
182
182
// Headers if provided, the headers list will be added on all
183
183
// outgoing requests for this service config.
184
184
Headers []Header `yaml:"headers"`
185
+
186
+ // PreservePath if true, will preserve the full original path when proxying
187
+ // requests instead of stripping the extension prefix. Default is false to
188
+ // maintain backward compatibility.
189
+ PreservePath bool `yaml:"preservePath,omitempty"`
185
190
}
186
191
187
192
// Header defines the header to be added in the proxy requests.
@@ -393,15 +398,21 @@ func NewManager(log *log.Entry, namespace string, sg SettingsGetter, ag Applicat
393
398
// the Argo CD configmap.
394
399
type ExtensionRegistry map [string ]ProxyRegistry
395
400
401
+ // Proxy extends httputil.ReverseProxy with additional configuration
402
+ type Proxy struct {
403
+ * httputil.ReverseProxy
404
+ PreservePath bool
405
+ }
406
+
396
407
// ProxyRegistry is an in memory registry that contains all proxies for a
397
408
// given extension. Different extensions will have independent proxy registries.
398
409
// This is required to address the use case when one extension is configured with
399
410
// multiple backend services in different clusters.
400
- type ProxyRegistry map [ProxyKey ]* httputil. ReverseProxy
411
+ type ProxyRegistry map [ProxyKey ]* Proxy
401
412
402
413
// NewProxyRegistry will instantiate a new in memory registry for proxies.
403
414
func NewProxyRegistry () ProxyRegistry {
404
- r := make (map [ProxyKey ]* httputil. ReverseProxy )
415
+ r := make (map [ProxyKey ]* Proxy )
405
416
return r
406
417
}
407
418
@@ -521,12 +532,12 @@ func validateConfigs(configs *ExtensionConfigs) error {
521
532
// NewProxy will instantiate a new reverse proxy based on the provided
522
533
// targetURL and config. It will remove sensitive information from the
523
534
// incoming request such as the Authorization and Cookie headers.
524
- func NewProxy (targetURL string , headers []Header , config ProxyConfig ) (* httputil. ReverseProxy , error ) {
535
+ func NewProxy (targetURL string , headers []Header , config ProxyConfig , preservePath bool ) (* Proxy , error ) {
525
536
url , err := url .Parse (targetURL )
526
537
if err != nil {
527
538
return nil , fmt .Errorf ("failed to parse proxy URL: %w" , err )
528
539
}
529
- proxy := & httputil.ReverseProxy {
540
+ reverseProxy := & httputil.ReverseProxy {
530
541
Transport : newTransport (config ),
531
542
Director : func (req * http.Request ) {
532
543
req .Host = url .Host
@@ -540,6 +551,10 @@ func NewProxy(targetURL string, headers []Header, config ProxyConfig) (*httputil
540
551
}
541
552
},
542
553
}
554
+ proxy := & Proxy {
555
+ ReverseProxy : reverseProxy ,
556
+ PreservePath : preservePath ,
557
+ }
543
558
return proxy , nil
544
559
}
545
560
@@ -606,7 +621,7 @@ func (m *Manager) UpdateExtensionRegistry(s *settings.ArgoCDSettings) error {
606
621
proxyReg := NewProxyRegistry ()
607
622
singleBackend := len (ext .Backend .Services ) == 1
608
623
for _ , service := range ext .Backend .Services {
609
- proxy , err := NewProxy (service .URL , service .Headers , ext .Backend .ProxyConfig )
624
+ proxy , err := NewProxy (service .URL , service .Headers , ext .Backend .ProxyConfig , service . PreservePath )
610
625
if err != nil {
611
626
return fmt .Errorf ("error creating proxy: %w" , err )
612
627
}
@@ -627,7 +642,7 @@ func (m *Manager) UpdateExtensionRegistry(s *settings.ArgoCDSettings) error {
627
642
func appendProxy (registry ProxyRegistry ,
628
643
extName string ,
629
644
service ServiceConfig ,
630
- proxy * httputil. ReverseProxy ,
645
+ proxy * Proxy ,
631
646
singleBackend bool ,
632
647
) error {
633
648
if singleBackend {
@@ -727,7 +742,7 @@ func (m *Manager) authorize(ctx context.Context, rr *RequestResources, extName s
727
742
728
743
// findProxy will search the given registry to find the correct proxy to use
729
744
// based on the given extName and dest.
730
- func findProxy (registry ProxyRegistry , extName string , dest v1alpha1.ApplicationDestination ) (* httputil. ReverseProxy , error ) {
745
+ func findProxy (registry ProxyRegistry , extName string , dest v1alpha1.ApplicationDestination ) (* Proxy , error ) {
731
746
// First try to find the proxy in the registry just by the extension name.
732
747
// This is the simple case for extensions with only one backend service.
733
748
key := proxyKey (extName , "" , "" )
@@ -796,7 +811,7 @@ func (m *Manager) CallExtension() func(http.ResponseWriter, *http.Request) {
796
811
userId := m .userGetter .GetUserId (r .Context ())
797
812
username := m .userGetter .GetUsername (r .Context ())
798
813
groups := m .userGetter .GetGroups (r .Context ())
799
- prepareRequest (r , m .namespace , extName , app , userId , username , groups )
814
+ prepareRequest (r , m .namespace , extName , app , userId , username , groups , proxy . PreservePath )
800
815
m .log .WithFields (log.Fields {
801
816
HeaderArgoCDUserId : userId ,
802
817
HeaderArgoCDUsername : username ,
@@ -831,8 +846,12 @@ func registerMetrics(extName string, metrics httpsnoop.Metrics, extensionMetrics
831
846
// - Cluster destination name
832
847
// - Cluster destination server
833
848
// - Argo CD authenticated username
834
- func prepareRequest (r * http.Request , namespace string , extName string , app * v1alpha1.Application , userId string , username string , groups []string ) {
835
- r .URL .Path = strings .TrimPrefix (r .URL .Path , fmt .Sprintf ("%s/%s" , URLPrefix , extName ))
849
+ func prepareRequest (r * http.Request , namespace string , extName string , app * v1alpha1.Application , userId string , username string , groups []string , preservePath bool ) {
850
+ if ! preservePath {
851
+ // Default behavior: strip the extension prefix from the path
852
+ r .URL .Path = strings .TrimPrefix (r .URL .Path , fmt .Sprintf ("%s/%s" , URLPrefix , extName ))
853
+ }
854
+
836
855
r .Header .Set (HeaderArgoCDNamespace , namespace )
837
856
if app .Spec .Destination .Name != "" {
838
857
r .Header .Set (HeaderArgoCDTargetClusterName , app .Spec .Destination .Name )
0 commit comments