Skip to content

Commit 70cdbff

Browse files
authored
[Feature] Expose HTTP Client Config (#1680)
1 parent a023475 commit 70cdbff

File tree

11 files changed

+296
-112
lines changed

11 files changed

+296
-112
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- (Maintenance) Go 1.22.4 & Kubernetes 1.29.6 libraries
55
- (Feature) Fix CRD Schema types
66
- (Bugfix) Adjust Prometheus Monitor labels
7+
- (Feature) Expose HTTP Client Config
78

89
## [1.2.41](https://github.com/arangodb/kube-arangodb/tree/1.2.41) (2024-05-24)
910
- (Maintenance) Bump Prometheus API Version

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ Flags:
166166
--deployment.feature.upgrade-version-check Enable initContainer with pre version check - Required ArangoDB 3.8.0 or higher (default true)
167167
--deployment.feature.upgrade-version-check-v2 Enable initContainer with pre version check based by Operator - Required ArangoDB 3.8.0 or higher
168168
--features-config-map-name string Name of the Feature Map ConfigMap (default "arangodb-operator-feature-config-map")
169+
--http1.keep-alive If false, disables HTTP keep-alives and will only use the connection to the server for a single HTTP request (default true)
170+
--http1.transport.dial-timeout duration Maximum amount of time a dial will wait for a connect to complete (default 30s)
171+
--http1.transport.idle-conn-timeout duration Maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. Zero means no limit (default 1m30s)
172+
--http1.transport.idle-conn-timeout-short duration Maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. Zero means no limit (default 100ms)
173+
--http1.transport.keep-alive-timeout duration Interval between keep-alive probes for an active network connection (default 1m30s)
174+
--http1.transport.keep-alive-timeout-short duration Interval between keep-alive probes for an active network connection (default 100ms)
175+
--http1.transport.max-idle-conns int Maximum number of idle (keep-alive) connections across all hosts. Zero means no limit (default 100)
176+
--http1.transport.tls-handshake-timeout duration Maximum amount of time to wait for a TLS handshake. Zero means no timeout (default 10s)
169177
--image.discovery.status Discover Operator Image from Pod Status by default. When disabled Pod Spec is used. (default true)
170178
--image.discovery.timeout duration Timeout for image discovery process (default 1m0s)
171179
--internal.scaling-integration Enable Scaling Integration

cmd/cmd.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ func init() {
262262
if err := reconcile.ActionsConfigGlobal.Init(&cmdMain); err != nil {
263263
panic(err.Error())
264264
}
265+
if err := operatorHTTP.InitConfiguration(&cmdMain); err != nil {
266+
panic(err.Error())
267+
}
265268
}
266269

267270
func Command() *cobra.Command {

pkg/deployment/context_impl.go

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,9 @@ package deployment
2222

2323
import (
2424
"context"
25-
"crypto/tls"
2625
"fmt"
2726
"net"
28-
nhttp "net/http"
2927
"strconv"
30-
"time"
3128

3229
core "k8s.io/api/core/v1"
3330
apiErrors "k8s.io/apimachinery/pkg/api/errors"
@@ -53,9 +50,11 @@ import (
5350
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
5451
"github.com/arangodb/kube-arangodb/pkg/operator/scope"
5552
"github.com/arangodb/kube-arangodb/pkg/replication"
53+
"github.com/arangodb/kube-arangodb/pkg/util"
5654
"github.com/arangodb/kube-arangodb/pkg/util/constants"
5755
"github.com/arangodb/kube-arangodb/pkg/util/errors"
5856
"github.com/arangodb/kube-arangodb/pkg/util/globals"
57+
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
5958
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
6059
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
6160
persistentvolumeclaimv1 "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/persistentvolumeclaim/v1"
@@ -219,24 +218,7 @@ func (d *Deployment) GetAgency(ctx context.Context, agencyIDs ...string) (agency
219218
}
220219

221220
func (d *Deployment) getConnConfig() (http.ConnectionConfig, error) {
222-
transport := &nhttp.Transport{
223-
Proxy: nhttp.ProxyFromEnvironment,
224-
DialContext: (&net.Dialer{
225-
Timeout: 10 * time.Second,
226-
KeepAlive: 100 * time.Millisecond,
227-
DualStack: true,
228-
}).DialContext,
229-
MaxIdleConns: 100,
230-
IdleConnTimeout: 100 * time.Millisecond,
231-
TLSHandshakeTimeout: 10 * time.Second,
232-
ExpectContinueTimeout: 1 * time.Second,
233-
}
234-
235-
if d.GetSpec().TLS.IsSecure() {
236-
transport.TLSClientConfig = &tls.Config{
237-
InsecureSkipVerify: true,
238-
}
239-
}
221+
transport := operatorHTTP.RoundTripperWithShortTransport(operatorHTTP.WithTransportTLS(util.BoolSwitch(d.GetSpec().TLS.IsSecure(), operatorHTTP.Insecure, nil)))
240222

241223
connConfig := http.ConnectionConfig{
242224
Transport: transport,

pkg/deployment/reconcile/plan_builder_tls.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ import (
4343
"github.com/arangodb/kube-arangodb/pkg/util"
4444
"github.com/arangodb/kube-arangodb/pkg/util/constants"
4545
"github.com/arangodb/kube-arangodb/pkg/util/crypto"
46+
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
4647
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
4748
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
4849
memberTls "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tls"
@@ -450,10 +451,7 @@ func checkServerValidCertRequest(ctx context.Context, context PlanBuilderContext
450451
endpoint = fmt.Sprintf("https://%s:%d%s", k8sutil.CreatePodDNSNameWithDomain(apiObject, context.GetSpec().ClusterDomain, group.AsRole(), member.ID), shared.ArangoSyncMasterPort, shared.ArangoSyncStatusEndpoint)
451452
}
452453

453-
tlsConfig := &tls.Config{
454-
RootCAs: ca.AsCertPool(),
455-
}
456-
transport := &http.Transport{TLSClientConfig: tlsConfig}
454+
transport := operatorHTTP.RoundTripper(operatorHTTP.WithTransportTLS(operatorHTTP.WithRootCA(ca.AsCertPool())))
457455
client := &http.Client{Transport: transport, Timeout: time.Second}
458456

459457
auth, err := context.GetAuthentication()()

pkg/exporter/passthru.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
package exporter
2222

2323
import (
24-
"crypto/tls"
2524
"io"
2625
"net/http"
2726
"strings"
2827
"sync"
2928
"time"
3029

30+
"github.com/arangodb/kube-arangodb/pkg/util"
3131
"github.com/arangodb/kube-arangodb/pkg/util/errors"
32+
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
3233
)
3334

3435
var _ http.Handler = &passthru{}
@@ -44,17 +45,13 @@ type httpClientFactory func(endpoint string) (*http.Client, *http.Request, error
4445

4546
func newHttpClientFactory(auth Authentication, sslVerify bool, timeout time.Duration) httpClientFactory {
4647
return func(endpoint string) (*http.Client, *http.Request, error) {
47-
transport := &http.Transport{}
48+
transport := operatorHTTP.Transport(operatorHTTP.WithTransportTLS(util.BoolSwitch(sslVerify, operatorHTTP.Insecure, nil)))
4849

4950
req, err := http.NewRequest("GET", endpoint, nil)
5051
if err != nil {
5152
return nil, nil, errors.WithStack(err)
5253
}
5354

54-
if !sslVerify {
55-
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
56-
}
57-
5855
jwt, err := auth()
5956
if err != nil {
6057
return nil, nil, err

pkg/storage/provisioner/client/client.go

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,15 @@ package client
2323
import (
2424
"bytes"
2525
"context"
26-
"crypto/tls"
2726
"encoding/json"
2827
"io"
29-
"net"
3028
"net/http"
3129
"net/url"
3230
"time"
3331

3432
"github.com/arangodb/kube-arangodb/pkg/storage/provisioner"
3533
"github.com/arangodb/kube-arangodb/pkg/util/errors"
34+
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
3635
)
3736

3837
// New creates a new client for the provisioner API.
@@ -44,39 +43,23 @@ func New(endpoint string) (provisioner.API, error) {
4443
u.Path = ""
4544
return &client{
4645
endpoint: *u,
46+
client: &http.Client{
47+
Transport: operatorHTTP.RoundTripper(operatorHTTP.WithTransportTLS(operatorHTTP.Insecure)),
48+
Timeout: defaultHTTPTimeout,
49+
},
4750
}, nil
4851
}
4952

5053
type client struct {
5154
endpoint url.URL
55+
56+
client *http.Client
5257
}
5358

5459
const (
5560
defaultHTTPTimeout = time.Minute * 2
5661
)
5762

58-
var (
59-
httpClient = &http.Client{
60-
Timeout: defaultHTTPTimeout,
61-
Transport: &http.Transport{
62-
Proxy: http.ProxyFromEnvironment,
63-
DialContext: (&net.Dialer{
64-
Timeout: 30 * time.Second,
65-
KeepAlive: 30 * time.Second,
66-
DualStack: true,
67-
}).DialContext,
68-
MaxIdleConns: 100,
69-
MaxIdleConnsPerHost: 10,
70-
IdleConnTimeout: 90 * time.Second,
71-
TLSHandshakeTimeout: 90 * time.Second,
72-
TLSClientConfig: &tls.Config{
73-
InsecureSkipVerify: true,
74-
},
75-
ExpectContinueTimeout: 1 * time.Second,
76-
},
77-
}
78-
)
79-
8063
// GetNodeInfo fetches information from the current node.
8164
func (c *client) GetNodeInfo(ctx context.Context) (provisioner.NodeInfo, error) {
8265
req, err := c.newRequest("GET", "/nodeinfo", nil)
@@ -165,7 +148,7 @@ func (c *client) newRequest(method string, localPath string, body interface{}) (
165148
// do performs the given request and parses the result.
166149
func (c *client) do(ctx context.Context, req *http.Request, result interface{}) error {
167150
req = req.WithContext(ctx)
168-
resp, err := httpClient.Do(req)
151+
resp, err := c.client.Do(req)
169152
if err != nil {
170153
// Request failed
171154
return errors.WithStack(err)

pkg/util/arangod/client.go

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@ package arangod
2222

2323
import (
2424
"context"
25-
"crypto/tls"
2625
"net"
2726
nhttp "net/http"
2827
"strconv"
29-
"time"
3028

3129
typedCore "k8s.io/client-go/kubernetes/typed/core/v1"
3230

@@ -39,6 +37,7 @@ import (
3937
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
4038
"github.com/arangodb/kube-arangodb/pkg/util/errors"
4139
"github.com/arangodb/kube-arangodb/pkg/util/globals"
40+
operatorHTTP "github.com/arangodb/kube-arangodb/pkg/util/http"
4241
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
4342
)
4443

@@ -61,58 +60,21 @@ func WithRequireAuthentication(ctx context.Context) context.Context {
6160
return context.WithValue(ctx, requireAuthenticationKey{}, true)
6261
}
6362

64-
var (
65-
sharedHTTPTransport = &nhttp.Transport{
66-
Proxy: nhttp.ProxyFromEnvironment,
67-
DialContext: (&net.Dialer{
68-
Timeout: 30 * time.Second,
69-
KeepAlive: 90 * time.Second,
70-
DualStack: true,
71-
}).DialContext,
72-
MaxIdleConns: 100,
73-
IdleConnTimeout: 90 * time.Second,
74-
TLSHandshakeTimeout: 10 * time.Second,
75-
ExpectContinueTimeout: 1 * time.Second,
76-
}
77-
sharedHTTPSTransport = &nhttp.Transport{
78-
Proxy: nhttp.ProxyFromEnvironment,
79-
DialContext: (&net.Dialer{
80-
Timeout: 30 * time.Second,
81-
KeepAlive: 90 * time.Second,
82-
DualStack: true,
83-
}).DialContext,
84-
MaxIdleConns: 100,
85-
IdleConnTimeout: 90 * time.Second,
86-
TLSHandshakeTimeout: 10 * time.Second,
87-
ExpectContinueTimeout: 1 * time.Second,
88-
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
89-
}
90-
sharedHTTPTransportShortTimeout = &nhttp.Transport{
91-
Proxy: nhttp.ProxyFromEnvironment,
92-
DialContext: (&net.Dialer{
93-
Timeout: 30 * time.Second,
94-
KeepAlive: 100 * time.Millisecond,
95-
DualStack: true,
96-
}).DialContext,
97-
MaxIdleConns: 100,
98-
IdleConnTimeout: 100 * time.Millisecond,
99-
TLSHandshakeTimeout: 10 * time.Second,
100-
ExpectContinueTimeout: 1 * time.Second,
101-
}
102-
sharedHTTPSTransportShortTimeout = &nhttp.Transport{
103-
Proxy: nhttp.ProxyFromEnvironment,
104-
DialContext: (&net.Dialer{
105-
Timeout: 30 * time.Second,
106-
KeepAlive: 100 * time.Millisecond,
107-
DualStack: true,
108-
}).DialContext,
109-
MaxIdleConns: 100,
110-
IdleConnTimeout: 100 * time.Millisecond,
111-
TLSHandshakeTimeout: 10 * time.Second,
112-
ExpectContinueTimeout: 1 * time.Second,
113-
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
114-
}
115-
)
63+
func sharedHTTPTransport() nhttp.RoundTripper {
64+
return operatorHTTP.Transport()
65+
}
66+
67+
func sharedHTTPSTransport() nhttp.RoundTripper {
68+
return operatorHTTP.Transport(operatorHTTP.WithTransportTLS(operatorHTTP.Insecure))
69+
}
70+
71+
func sharedHTTPTransportShortTimeout() nhttp.RoundTripper {
72+
return operatorHTTP.RoundTripperWithShortTransport()
73+
}
74+
75+
func sharedHTTPSTransportShortTimeout() nhttp.RoundTripper {
76+
return operatorHTTP.RoundTripperWithShortTransport(operatorHTTP.WithTransportTLS(operatorHTTP.Insecure))
77+
}
11678

11779
// CreateArangodClient creates a go-driver client for a specific member in the given group.
11880
func CreateArangodClient(ctx context.Context, cli typedCore.CoreV1Interface, apiObject *api.ArangoDeployment, group api.ServerGroup, id string, asyncSupport bool) (driver.Client, error) {
@@ -192,7 +154,7 @@ func createArangodHTTPConfigForDNSNames(apiObject *api.ArangoDeployment, dnsName
192154
}
193155
}
194156
connConfig := http.ConnectionConfig{
195-
Transport: transport,
157+
Transport: transport(),
196158
DontFollowRedirect: true,
197159
}
198160
for _, dnsName := range dnsNames {

pkg/util/http/client.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package http
22+
23+
import (
24+
"crypto/tls"
25+
"crypto/x509"
26+
"net/http"
27+
)
28+
29+
func RoundTripper(mods ...TransportMod) http.RoundTripper {
30+
df := append([]TransportMod{
31+
configuration.DefaultTransport,
32+
}, mods...)
33+
34+
return Transport(df...)
35+
}
36+
37+
func RoundTripperWithShortTransport(mods ...TransportMod) http.RoundTripper {
38+
df := append([]TransportMod{
39+
configuration.ShortTransport,
40+
}, mods...)
41+
42+
return Transport(df...)
43+
}
44+
45+
func Insecure(in *tls.Config) {
46+
in.InsecureSkipVerify = true
47+
}
48+
49+
func WithRootCA(ca *x509.CertPool) TransportTLSMod {
50+
return func(in *tls.Config) {
51+
in.RootCAs = ca
52+
}
53+
}

0 commit comments

Comments
 (0)