Skip to content

Commit

Permalink
Bug 2003657: Respect user defined proxy's CA cert (#495)
Browse files Browse the repository at this point in the history
* First prototype

* Comments

* Update
  • Loading branch information
tremes committed Sep 22, 2021
1 parent 86992f1 commit 66d737f
Showing 1 changed file with 58 additions and 5 deletions.
63 changes: 58 additions & 5 deletions pkg/insights/insightsclient/insightsclient.go
Expand Up @@ -31,6 +31,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apimachineryversion "k8s.io/apimachinery/pkg/version"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"

"github.com/openshift/insights-operator/pkg/authorizer"
)
Expand Down Expand Up @@ -120,9 +121,9 @@ func getTrustedCABundle() (*x509.CertPool, error) {
}

// clientTransport creates new http.Transport with either system or configured Proxy
func clientTransport(authorizer Authorizer) http.RoundTripper {
func (c *Client) clientTransport() http.RoundTripper {
clientTransport := &http.Transport{
Proxy: authorizer.NewSystemOrConfiguredProxy(),
Proxy: c.authorizer.NewSystemOrConfiguredProxy(),
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
Expand All @@ -136,6 +137,21 @@ func clientTransport(authorizer Authorizer) http.RoundTripper {
if err != nil {
klog.Errorf("Failed to get proxy trusted CA: %v", err)
}
// check if some proxy is set
if isProxySet() {
userCAPem, err := c.getUserCABundle()
if err != nil {
klog.Error(err)
}
if userCAPem != nil {
if ok := rootCAs.AppendCertsFromPEM(userCAPem); !ok {
klog.Error("failed to parse CA pem data")
} else {
klog.Infof("Sucecssfully added CA cert referenced in the clusterProxy.Spec.TrustedCA bundle")
}
}
}

if rootCAs != nil {
clientTransport.TLSClientConfig = &tls.Config{}
clientTransport.TLSClientConfig.RootCAs = rootCAs
Expand Down Expand Up @@ -237,7 +253,7 @@ func (c *Client) Send(ctx context.Context, endpoint string, source Source) error
req.Body = pr

// dynamically set the proxy environment
c.client.Transport = clientTransport(c.authorizer)
c.client.Transport = c.clientTransport()

klog.V(4).Infof("Uploading %s to %s", source.Type, req.URL.String())
resp, err := c.client.Do(req)
Expand Down Expand Up @@ -306,7 +322,7 @@ func (c Client) RecvReport(ctx context.Context, endpoint string) (io.ReadCloser,
}

// dynamically set the proxy environment
c.client.Transport = clientTransport(c.authorizer)
c.client.Transport = c.clientTransport()

klog.V(4).Infof("Retrieving report from %s", req.URL.String())
resp, err := c.client.Do(req)
Expand Down Expand Up @@ -382,7 +398,7 @@ func (c Client) RecvSCACerts(ctx context.Context, endpoint string) ([]byte, erro
return nil, err
}
req.Header.Set("Content-Type", "application/json")
c.client.Transport = clientTransport(c.authorizer)
c.client.Transport = c.clientTransport()
authHeader := fmt.Sprintf("AccessToken %s:%s", cv.Spec.ClusterID, token)
req.Header.Set("Authorization", authHeader)

Expand Down Expand Up @@ -424,6 +440,43 @@ func ocmErrorMessage(url *url.URL, r *http.Response) error {
}
}

// isProxySet looks up "HTTP_PROXY" and "HTTPS_PROXY" environment variables
// and returns true if at least one is set
func isProxySet() (ok bool) {
_, httpProxySet := os.LookupEnv("HTTP_PROXY")
_, httpsProxySet := os.LookupEnv("HTTPS_PROXY")

return httpProxySet || httpsProxySet
}

// getUserCABundle reads "cluster" proxy resource to get a name of config map with
// "TrustedCA" certificate and then it tries to read the certificate data from "ca-bundle.crt" key
// Returns the certificate data or an error in case of failed reading
func (c *Client) getUserCABundle() ([]byte, error) {
configCli, err := configv1client.NewForConfig(c.gatherKubeConfig)
if err != nil {
return nil, err
}
clusterProxy, err := configCli.Proxies().Get(context.Background(), "cluster", metav1.GetOptions{})
if err != nil {
return nil, err
}
cmWithCACert := clusterProxy.Spec.TrustedCA.Name
coreCli, err := corev1client.NewForConfig(c.gatherKubeConfig)
if err != nil {
return nil, err
}
cm, err := coreCli.ConfigMaps("openshift-config").Get(context.Background(), cmWithCACert, metav1.GetOptions{})
if err != nil {
return nil, err
}
data, ok := cm.Data["ca-bundle.crt"]
if !ok {
return nil, fmt.Errorf("can't find ca-bundle.crt key in %s config map", cmWithCACert)
}
return []byte(data), nil
}

var (
counterRequestSend = metrics.NewCounterVec(&metrics.CounterOpts{
Name: "insightsclient_request_send_total",
Expand Down

0 comments on commit 66d737f

Please sign in to comment.