diff --git a/.golangci.yaml b/.golangci.yaml index a80b6564c..9dcd6b279 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -11,3 +11,5 @@ linters: - gofmt - gosec - govet + disable: + - errcheck diff --git a/config/crds/troubleshoot.sh_collectors.yaml b/config/crds/troubleshoot.sh_collectors.yaml index d30a32fc2..ed5222823 100644 --- a/config/crds/troubleshoot.sh_collectors.yaml +++ b/config/crds/troubleshoot.sh_collectors.yaml @@ -408,11 +408,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -430,11 +453,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -450,11 +496,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -17054,11 +17123,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -17074,11 +17166,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -17094,11 +17209,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: diff --git a/config/crds/troubleshoot.sh_hostcollectors.yaml b/config/crds/troubleshoot.sh_hostcollectors.yaml index 61b6907f1..14414a0b3 100644 --- a/config/crds/troubleshoot.sh_hostcollectors.yaml +++ b/config/crds/troubleshoot.sh_hostcollectors.yaml @@ -1400,11 +1400,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -1420,11 +1443,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -1440,11 +1486,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: diff --git a/config/crds/troubleshoot.sh_hostpreflights.yaml b/config/crds/troubleshoot.sh_hostpreflights.yaml index f8c06613c..1b1bf828b 100644 --- a/config/crds/troubleshoot.sh_hostpreflights.yaml +++ b/config/crds/troubleshoot.sh_hostpreflights.yaml @@ -1400,11 +1400,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -1420,11 +1443,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -1440,11 +1486,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -1888,11 +1957,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -1908,11 +2000,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -1928,11 +2043,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: diff --git a/config/crds/troubleshoot.sh_preflights.yaml b/config/crds/troubleshoot.sh_preflights.yaml index d762ce2c6..27eef2914 100644 --- a/config/crds/troubleshoot.sh_preflights.yaml +++ b/config/crds/troubleshoot.sh_preflights.yaml @@ -2137,11 +2137,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -2159,11 +2182,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -2179,11 +2225,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -18737,11 +18806,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -18757,11 +18849,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -18777,11 +18892,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: diff --git a/config/crds/troubleshoot.sh_remotecollectors.yaml b/config/crds/troubleshoot.sh_remotecollectors.yaml index e408a2c18..c4b8765cc 100644 --- a/config/crds/troubleshoot.sh_remotecollectors.yaml +++ b/config/crds/troubleshoot.sh_remotecollectors.yaml @@ -221,11 +221,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -241,11 +264,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -261,11 +307,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: diff --git a/config/crds/troubleshoot.sh_supportbundles.yaml b/config/crds/troubleshoot.sh_supportbundles.yaml index 220bd1c33..2c8c5c2ed 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -2168,11 +2168,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -2190,11 +2213,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -2210,11 +2256,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -19978,11 +20047,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -19998,11 +20090,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: @@ -20018,11 +20133,34 @@ spec: type: object insecureSkipVerify: type: boolean + proxy: + type: string timeout: description: |- Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. Missing value or empty string or means no timeout. type: string + tls: + properties: + cacert: + type: string + clientCert: + type: string + clientKey: + type: string + secret: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + skipVerify: + type: boolean + type: object url: type: string required: diff --git a/go.mod b/go.mod index c504a25cf..409f7ff63 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,6 @@ require ( github.com/vmware-tanzu/velero v1.14.1 go.opentelemetry.io/otel v1.31.0 go.opentelemetry.io/otel/sdk v1.31.0 - go.opentelemetry.io/otel/trace v1.31.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/mod v0.21.0 golang.org/x/sync v0.8.0 @@ -124,6 +123,7 @@ require ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect diff --git a/pkg/apis/troubleshoot/v1beta2/collector_shared.go b/pkg/apis/troubleshoot/v1beta2/collector_shared.go index 1cc212f52..554f732e4 100644 --- a/pkg/apis/troubleshoot/v1beta2/collector_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/collector_shared.go @@ -186,7 +186,9 @@ type Get struct { Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"` // Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. // Missing value or empty string or means no timeout. - Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"` + TLS *TLSParams `json:"tls,omitempty" yaml:"tls,omitempty"` + Proxy string `json:"proxy,omitempty" yaml:"proxy,omitempty"` } type Post struct { @@ -196,7 +198,9 @@ type Post struct { Body string `json:"body,omitempty" yaml:"body,omitempty"` // Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. // Missing value or empty string or means no timeout. - Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"` + TLS *TLSParams `json:"tls,omitempty" yaml:"tls,omitempty"` + Proxy string `json:"proxy,omitempty" yaml:"proxy,omitempty"` } type Put struct { @@ -206,7 +210,9 @@ type Put struct { Body string `json:"body,omitempty" yaml:"body,omitempty"` // Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m. // Missing value or empty string or means no timeout. - Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"` + TLS *TLSParams `json:"tls,omitempty" yaml:"tls,omitempty"` + Proxy string `json:"proxy,omitempty" yaml:"proxy,omitempty"` } type Database struct { diff --git a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go index af210443e..8fb1ac586 100644 --- a/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go +++ b/pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go @@ -1620,6 +1620,11 @@ func (in *Get) DeepCopyInto(out *Get) { (*out)[key] = val } } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLSParams) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Get. @@ -3416,6 +3421,11 @@ func (in *Post) DeepCopyInto(out *Post) { (*out)[key] = val } } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLSParams) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Post. @@ -3560,6 +3570,11 @@ func (in *Put) DeepCopyInto(out *Put) { (*out)[key] = val } } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLSParams) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Put. diff --git a/pkg/collect/host_http.go b/pkg/collect/host_http.go index 06e9685d0..6bf2b194c 100644 --- a/pkg/collect/host_http.go +++ b/pkg/collect/host_http.go @@ -32,15 +32,15 @@ func (c *CollectHostHTTP) Collect(progressChan chan<- interface{}) (map[string][ case httpCollector.Get != nil: response, err = doRequest( "GET", httpCollector.Get.URL, httpCollector.Get.Headers, - "", httpCollector.Get.InsecureSkipVerify, httpCollector.Get.Timeout) + "", httpCollector.Get.InsecureSkipVerify, httpCollector.Get.Timeout, httpCollector.Get.TLS, httpCollector.Get.Proxy) case httpCollector.Post != nil: response, err = doRequest( "POST", httpCollector.Post.URL, httpCollector.Post.Headers, - httpCollector.Post.Body, httpCollector.Post.InsecureSkipVerify, httpCollector.Post.Timeout) + httpCollector.Post.Body, httpCollector.Post.InsecureSkipVerify, httpCollector.Post.Timeout, httpCollector.Post.TLS, httpCollector.Post.Proxy) case httpCollector.Put != nil: response, err = doRequest( "PUT", httpCollector.Put.URL, httpCollector.Put.Headers, - httpCollector.Put.Body, httpCollector.Put.InsecureSkipVerify, httpCollector.Put.Timeout) + httpCollector.Put.Body, httpCollector.Put.InsecureSkipVerify, httpCollector.Put.Timeout, httpCollector.Put.TLS, httpCollector.Put.Proxy) default: return nil, errors.New("no supported http request type") } diff --git a/pkg/collect/http.go b/pkg/collect/http.go index 697c30127..05fcd93a4 100644 --- a/pkg/collect/http.go +++ b/pkg/collect/http.go @@ -3,9 +3,13 @@ package collect import ( "bytes" "crypto/tls" + "crypto/x509" "encoding/json" "io" "net/http" + "net/http/httputil" + neturl "net/url" + "os" "path/filepath" "strings" "time" @@ -52,16 +56,13 @@ func (c *CollectHTTP) Collect(progressChan chan<- interface{}) (CollectorResult, switch { case c.Collector.Get != nil: response, err = doRequest( - "GET", c.Collector.Get.URL, c.Collector.Get.Headers, - "", c.Collector.Get.InsecureSkipVerify, c.Collector.Get.Timeout) + "GET", c.Collector.Get.URL, c.Collector.Get.Headers, "", c.Collector.Get.InsecureSkipVerify, c.Collector.Get.Timeout, c.Collector.Get.TLS, c.Collector.Get.Proxy) case c.Collector.Post != nil: response, err = doRequest( - "POST", c.Collector.Post.URL, c.Collector.Post.Headers, - c.Collector.Post.Body, c.Collector.Post.InsecureSkipVerify, c.Collector.Post.Timeout) + "POST", c.Collector.Post.URL, c.Collector.Post.Headers, c.Collector.Post.Body, c.Collector.Post.InsecureSkipVerify, c.Collector.Post.Timeout, c.Collector.Post.TLS, c.Collector.Post.Proxy) case c.Collector.Put != nil: response, err = doRequest( - "PUT", c.Collector.Put.URL, c.Collector.Put.Headers, - c.Collector.Put.Body, c.Collector.Put.InsecureSkipVerify, c.Collector.Put.Timeout) + "PUT", c.Collector.Put.URL, c.Collector.Put.Headers, c.Collector.Put.Body, c.Collector.Put.InsecureSkipVerify, c.Collector.Put.Timeout, c.Collector.Put.TLS, c.Collector.Put.Proxy) default: return nil, errors.New("no supported http request type") } @@ -82,24 +83,74 @@ func (c *CollectHTTP) Collect(progressChan chan<- interface{}) (CollectorResult, return output, nil } -func doRequest(method, url string, headers map[string]string, body string, insecureSkipVerify bool, timeout string) (*http.Response, error) { +func handleFileOrDir(path string) (bool, error) { + f, err := os.Stat(path) + if err != nil { + klog.V(2).Infof("Failed to stat file path: %s\n", err) + return false, err + } + if f.IsDir() { + os.Setenv("SSL_CERT_DIR", path) + klog.V(2).Infof("Using SSL_CERT_DIR: %s\n", path) + } else if f.Mode().IsRegular() { + os.Setenv("SSL_CERT_FILE", path) + klog.V(2).Infof("Using SSL_CERT_FILE: %s\n", path) + } + return true, nil +} + +func isPEMCertificate(s string) bool { + return strings.Contains(s, "BEGIN CERTIFICATE") || strings.Contains(s, "BEGIN RSA PRIVATE KEY") +} + +func doRequest(method, url string, headers map[string]string, body string, insecureSkipVerify bool, timeout string, tlsParams *troubleshootv1beta2.TLSParams, proxy string) (*http.Response, error) { + t, err := parseTimeout(timeout) if err != nil { return nil, err } - httpClient := &http.Client{ - Timeout: t, + tlsConfig := &tls.Config{MinVersion: tls.VersionTLS12} + httpTransport := &http.Transport{} + + if tlsParams != nil && tlsParams.CACert != "" { + if isPEMCertificate(tlsParams.CACert) { + klog.V(2).Infof("Using PEM certificate from spec\n") + certPool := x509.NewCertPool() + if !certPool.AppendCertsFromPEM([]byte(tlsParams.CACert)) { + return nil, errors.New("failed to append certificate to cert pool") + } + tlsConfig.RootCAs = certPool + } else if _, err := handleFileOrDir(tlsParams.CACert); err != nil { + return nil, errors.Wrap(err, "failed to handle cacert file path") + } } if insecureSkipVerify { - httpClient.Transport = &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, + tlsConfig.InsecureSkipVerify = true + } + + httpTransport.TLSClientConfig = tlsConfig + + if proxy != "" || os.Getenv("HTTPS_PROXY") != "" { + if proxy != "" { + klog.V(2).Infof("Using proxy from spec: %s\n", proxy) + httpTransport.Proxy = func(req *http.Request) (*neturl.URL, error) { + return neturl.Parse(proxy) + } + } else { + klog.V(2).Infof("Using proxy from environment: %s\n", os.Getenv("HTTPS_PROXY")) + httpTransport.Proxy = http.ProxyFromEnvironment } } + httpClient := &http.Client{ + Timeout: t, + Transport: &LoggingTransport{ + Transport: httpTransport, + }, + } + req, err := http.NewRequest(method, url, strings.NewReader(body)) if err != nil { return nil, err @@ -112,6 +163,36 @@ func doRequest(method, url string, headers map[string]string, body string, insec return httpClient.Do(req) } +type LoggingTransport struct { + Transport http.RoundTripper +} + +func (t *LoggingTransport) RoundTrip(req *http.Request) (*http.Response, error) { + // Log the request + dumpReq, err := httputil.DumpRequestOut(req, true) + if err != nil { + klog.V(2).Infof("Failed to dump request: %+v\n", err) + } else { + klog.V(2).Infof("Request: %s\n", dumpReq) + } + + resp, err := t.Transport.RoundTrip(req) + + // Log the response + if err != nil { + klog.V(2).Infof("Request failed: %+v\n", err) + } else { + dumpResp, err := httputil.DumpResponse(resp, true) + if err != nil { + klog.V(2).Infof("Failed to dump response: %v+\n", err) + } else { + klog.V(2).Infof("Response: %s\n", dumpResp) + } + } + + return resp, err +} + func responseToOutput(response *http.Response, err error) ([]byte, error) { output := make(map[string]interface{}) if err != nil { @@ -130,11 +211,15 @@ func responseToOutput(response *http.Response, err error) ([]byte, error) { } var rawJSON json.RawMessage - if err := json.Unmarshal(body, &rawJSON); err != nil { - klog.Infof("failed to unmarshal response body as JSON: %v", err) + if len(body) > 0 { + if err := json.Unmarshal(body, &rawJSON); err != nil { + klog.Infof("failed to unmarshal response body as JSON: %+v", err) + rawJSON = json.RawMessage{} + } + } else { rawJSON = json.RawMessage{} + klog.V(2).Infof("empty response body\n") } - output["response"] = HTTPResponse{ Status: response.StatusCode, Body: string(body), diff --git a/pkg/collect/http_test.go b/pkg/collect/http_test.go index b558765a0..46fd216e5 100644 --- a/pkg/collect/http_test.go +++ b/pkg/collect/http_test.go @@ -83,6 +83,13 @@ func TestCollectHTTP_Collect(t *testing.T) { res.WriteHeader(http.StatusInternalServerError) res.Write([]byte("{\"error\": { \"message\": \"context deadline exceeded\"}}")) }) + mux.HandleFunc("/certificate-mismatch", func(res http.ResponseWriter, req *http.Request) { + time.Sleep(1 * time.Millisecond) + fmt.Println("Sleeping for 2 seconds on /error call") + res.Header().Set("Content-Type", "application/json; charset=utf-8") + res.WriteHeader(http.StatusInternalServerError) + res.Write([]byte("{\"error\": { \"message\": \"Request failed: proxyconnect tcp: tls: failed to verify certificate: x509: \"10.0.0.254\" certificate is not trusted\"}}")) + }) sample_get_response := &ResponseData{ Response: Response{ @@ -125,9 +132,15 @@ func TestCollectHTTP_Collect(t *testing.T) { Message: "context deadline exceeded", }, } - sample_error_bytes, _ := sample_error_response.ToJSONbytes() + sample_certificate_untrusted := &ErrorResponse{ + Error: HTTPError{ + Message: "Request failed: proxyconnect tcp: tls: failed to verify certificate: x509: \"10.0.0.254\" certificate is not trusted", + }, + } + sample_certificate_untrusted_bytes, _ := sample_certificate_untrusted.ToJSONbytes() + tests := []CollectorTest{ { // check valid file path when CollectorName is not supplied @@ -250,7 +263,25 @@ func TestCollectHTTP_Collect(t *testing.T) { checkTimeout: true, wantErr: false, }, - // TODO: add TLS cert case + { + name: "TLS: certificate is not trusted", + Collector: &troubleshootv1beta2.HTTP{ + CollectorMeta: troubleshootv1beta2.CollectorMeta{ + CollectorName: "", + }, + Get: &troubleshootv1beta2.Get{ + Timeout: "300ms", + }, + }, + args: args{ + progressChan: nil, + }, + want: CollectorResult{ + "result.json": sample_certificate_untrusted_bytes, + }, + checkTimeout: true, + wantErr: true, + }, } for _, tt := range tests { var ts *httptest.Server @@ -273,6 +304,9 @@ func TestCollectHTTP_Collect(t *testing.T) { c.Collector.Get.URL = fmt.Sprintf("%s%s", url, "/error") response_data := sample_error_response response_data.testCollectHTTP(t, &tt, c) + c.Collector.Get.URL = fmt.Sprintf("%s%s", url, "/certificate-mismatch") + response_data = sample_certificate_untrusted + response_data.testCollectHTTP(t, &tt, c) } else { c.Collector.Get.URL = fmt.Sprintf("%s%s", url, "/get") response_data := sample_get_response diff --git a/schemas/collector-troubleshoot-v1beta2.json b/schemas/collector-troubleshoot-v1beta2.json index c6b6105a8..d54ff65a6 100644 --- a/schemas/collector-troubleshoot-v1beta2.json +++ b/schemas/collector-troubleshoot-v1beta2.json @@ -570,10 +570,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -600,10 +635,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -627,10 +697,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -14622,10 +14727,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -14649,10 +14789,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -14676,10 +14851,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } diff --git a/schemas/preflight-troubleshoot-v1beta2.json b/schemas/preflight-troubleshoot-v1beta2.json index 7b4ddd0f7..02e7687e8 100644 --- a/schemas/preflight-troubleshoot-v1beta2.json +++ b/schemas/preflight-troubleshoot-v1beta2.json @@ -3234,10 +3234,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -3264,10 +3299,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -3291,10 +3361,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -17215,10 +17320,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -17242,10 +17382,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -17269,10 +17444,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } diff --git a/schemas/supportbundle-troubleshoot-v1beta2.json b/schemas/supportbundle-troubleshoot-v1beta2.json index 884ac10f6..2c1ac4ff7 100644 --- a/schemas/supportbundle-troubleshoot-v1beta2.json +++ b/schemas/supportbundle-troubleshoot-v1beta2.json @@ -3280,10 +3280,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -3310,10 +3345,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -3337,10 +3407,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -19134,10 +19239,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -19161,10 +19301,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } @@ -19188,10 +19363,45 @@ "insecureSkipVerify": { "type": "boolean" }, + "proxy": { + "type": "string" + }, "timeout": { "description": "Timeout is the time to wait for a server's response. Its a duration e.g 15s, 2h30m.\nMissing value or empty string or means no timeout.", "type": "string" }, + "tls": { + "type": "object", + "properties": { + "cacert": { + "type": "string" + }, + "clientCert": { + "type": "string" + }, + "clientKey": { + "type": "string" + }, + "secret": { + "type": "object", + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "skipVerify": { + "type": "boolean" + } + } + }, "url": { "type": "string" } diff --git a/testdata/https-proxy-replicated-app.yaml b/testdata/https-proxy-replicated-app.yaml new file mode 100644 index 000000000..675c1001c --- /dev/null +++ b/testdata/https-proxy-replicated-app.yaml @@ -0,0 +1,74 @@ +apiVersion: troubleshoot.sh/v1beta2 +kind: HostPreflight +metadata: + name: mitm-proxy +spec: + collectors: + - http: + collectorName: &https https + get: + url: &url https://replicated.app + tls: + cacert: &ca |- + -----BEGIN CERTIFICATE----- + MIIDajCCAlKgAwIBAgIUFlUns1qeD6ss4cdXz52287KtPQswDQYJKoZIhvcNAQEL + BQAwTjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5 + MRMwEQYDVQQKDApSZXBsaWNhdGVkMQswCQYDVQQLDAJJVDAeFw0yNDA5MjcxNTU5 + MDJaFw0yNDEwMDQxNTU5MDJaME4xCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0 + ZTENMAsGA1UEBwwEQ2l0eTETMBEGA1UECgwKUmVwbGljYXRlZDELMAkGA1UECwwC + SVQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLe7PlgdPiApQzZzkY + 0dN/NDBib72Y5TAEhNguPVDY1Rj4PLiKjUXvHbVsRLpP8DrKJAeK/kJqeR4xr1O5 + dQenCoTZTHX24TLFx0D1SKfdUtpxzKta8jd+O5TwaY/tLsi9YcJ6mz8n7+giJH1r + ZH5Isa9JkZ3fb2+VoX054I/C88MfsvdZahL7/RHLvolRiLeV7X86Zx2EJ3hUFWoZ + kYeIggbt2BeikeDlHQDBmxzpIaP1IMl3LHOjZhj7TiNuSYtDiE8OQIV34c9IZ1yi + lcUjrwKQCfzaE9lZK5UbS3KRD1XFSrSP4tWVsUmesYeFD+nc5/wku/J+PXDM1QAu + B8q9AgMBAAGjQDA+MA8GA1UdEQQIMAaHBAoKHskwDAYDVR0TBAUwAwEB/zAdBgNV + HQ4EFgQUuwXZYrzbdQVGCS5O0sdlCJo761cwDQYJKoZIhvcNAQELBQADggEBAH3G + 9C6sJ+uR9ZAOnFyCQEdBVaw02NMOY0ajc8gMrmgl9btx1rLnS8r+zLf9Jev0YxiG + Pq6HbkceQNa6Rl6l6JH4O0sV0KUXe5r7kPPYv9pMsy+JZYH9H1ppUr0a13s4vrgA + 4YbFE3TispC6WXFng4w85ODc9nmXGDvjPX6mzZxcsxooDX5+PPAo+WueKutOZMvT + yvB2hUgb4hy6CT6OvJJFb9Lh1Hl5aE/9FKgF3u/Tq2U3SSzMHMZiWzUVfAO0J1Ev + jcr8Mb5t3iQwH3t2eT07K2fouPa70vbOfj1kSiexUoUllHgoOXUeOpGv4Aykly7m + C/XdeJyP1tnZ3j2ozPo= + -----END CERTIFICATE----- + - http: + collectorName: &https-proxy https-proxy + get: + url: *url + tls: + cacert: *ca + proxy: &proxy https://10.10.30.201:3130 + - http: + collectorName: &https-proxy-nocert https-proxy-nocert + get: + url: *url + proxy: *proxy + + analyzers: + - http: + checkName: *https-proxy + collectorName: *https-proxy + outcomes: + - pass: + when: &200 "statusCode == 200" + message: &passed checking https://replicated.app passed + - fail: + message: &failed checking https://replicated.app failed + - http: + checkName: *https-proxy-nocert + collectorName: *https-proxy-nocert + outcomes: + - pass: + when: *200 + message: *passed + - fail: + message: *failed + - http: + checkName: *https + collectorName: *https + outcomes: + - pass: + when: *200 + message: *passed + - fail: + message: *failed