Skip to content

Commit

Permalink
Status handling for RouteHealth
Browse files Browse the repository at this point in the history
  • Loading branch information
jhadvig committed Mar 23, 2020
1 parent 7a9c899 commit 66ff13d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 7 deletions.
5 changes: 5 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ const (
OCCLIDownloadsCustomResourceName = "oc-cli-downloads"
ODOCLIDownloadsCustomResourceName = "odo-cli-downloads"
)

const (
DefaultIngressCertFilePath = "/var/default-ingress-cert/ca-bundle.crt"
OAuthEndpointCAFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
)
85 changes: 78 additions & 7 deletions pkg/console/operator/sync_v400.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package operator

import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net/http"
"os"
"time"

// kube
appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -61,6 +65,7 @@ func (co *consoleOperator) sync_v400(updatedOperatorConfig *operatorv1.Console,
if rtErr != nil {
return rtErr
}
co.CheckRouteHealth(updatedOperatorConfig, rt)

cm, cmChanged, cmErrReason, cmErr := co.SyncConfigMap(set.Operator, set.Console, set.Infrastructure, rt)
toUpdate = toUpdate || cmChanged
Expand Down Expand Up @@ -148,13 +153,6 @@ func (co *consoleOperator) sync_v400(updatedOperatorConfig *operatorv1.Console,
return updatedOperatorConfig, prefix, "", nil
}())

status.HandleAvailable(updatedOperatorConfig, "Route", "FailedAdmittedIngress", func() error {
if !routesub.IsAdmitted(rt) {
return errors.New("console route is not admitted")
}
return nil
}())

// if we survive the gauntlet, we need to update the console config with the
// public hostname so that the world can know the console is ready to roll
klog.V(4).Infoln("sync_v400: updating console status")
Expand Down Expand Up @@ -472,6 +470,79 @@ func (c *consoleOperator) ValidateCustomLogo(operatorConfig *operatorsv1.Console
return true, "", nil
}

func (c *consoleOperator) CheckRouteHealth(opConfig *operatorv1.Console, rt *routev1.Route) {
status.HandleDegraded(func() (conf *operatorv1.Console, prefix string, reason string, err error) {
prefix = "RouteHealth"

caPool, err := c.getCA()
if err != nil {
return opConfig, prefix, "FailedLoadCA", fmt.Errorf("failed to read CA to check route health: %v", err)
}
client := clientWithCA(caPool)

// TODO: deal with an environment with a MitM proxy?
url := "https://" + rt.Spec.Host + "/health"
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return opConfig, prefix, "FailedRequest", fmt.Errorf("failed to build request to route (%s): %v", url, err)
}
resp, err := client.Do(req)
if err != nil {
return opConfig, prefix, "FailedGet", fmt.Errorf("failed to GET route (%s): %v", url, err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return opConfig, prefix, "StatusError", fmt.Errorf("route not yet available, %s returns '%s'", url, resp.Status)

}
return opConfig, prefix, "", nil
}())

status.HandleAvailable(opConfig, "Route", "FailedAdmittedIngress", func() error {
if !routesub.IsAdmitted(rt) {
return errors.New("console route is not admitted")
}
return nil
}())
}

func (co *consoleOperator) getCA() (*x509.CertPool, error) {
caCertPool, _ := x509.SystemCertPool()
if caCertPool == nil {
caCertPool = x509.NewCertPool()
}

trustedCA, tcaErr := co.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Get(api.TrustedCAConfigMapName, metav1.GetOptions{})
if tcaErr != nil {
klog.V(4).Infof("failed to GET configmap %s in %s (synced from %ss)", api.TrustedCAConfigMapName, api.OpenShiftConsoleNamespace, api.OpenShiftConfigManagedNamespace)
return nil, tcaErr
}
trustedCABundle := trustedCA.Data[api.TrustedCABundleKey]
caCertPool.AppendCertsFromPEM([]byte(trustedCABundle))

ingressCA, icaErr := co.configMapClient.ConfigMaps(api.OpenShiftConsoleNamespace).Get(api.DefaultIngressCertConfigMapName, metav1.GetOptions{})
if icaErr != nil {
klog.Infof("failed to GET configmap %s in %s (synced from %s)", api.DefaultIngressCertConfigMapName, api.OpenShiftConsoleNamespace, api.OpenShiftConfigManagedNamespace)
return nil, icaErr
}
ingressCABundle := ingressCA.Data[api.TrustedCABundleKey]
caCertPool.AppendCertsFromPEM([]byte(ingressCABundle))

return caCertPool, nil
}

func clientWithCA(caPool *x509.CertPool) *http.Client {
return &http.Client{
Timeout: 5 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: caPool,
},
},
}
}

func getDeploymentGeneration(co *consoleOperator) int64 {
deployment, err := co.deploymentClient.Deployments(api.TargetNamespace).Get(deploymentsub.Stub().Name, metav1.GetOptions{})
if err != nil {
Expand Down

0 comments on commit 66ff13d

Please sign in to comment.