Skip to content

Commit 004934c

Browse files
author
OpenShift Bot
committedJun 30, 2015
Merge pull request #3444 from stevekuznetsov/skuznets/healthz
Merged by openshift-bot
2 parents c139b93 + edefc04 commit 004934c

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
 

Diff for: ‎pkg/cmd/server/origin/master.go

+12
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ func (c *MasterConfig) InstallProtectedAPI(container *restful.Container) []strin
284284
initControllerRoutes(root, "/controllers", c.Options.Controllers != configapi.ControllersDisabled, c.ControllerPlug)
285285
initAPIVersionRoute(root, LegacyOpenShiftAPIPrefix, legacyAPIVersions...)
286286
initAPIVersionRoute(root, OpenShiftAPIPrefix, currentAPIVersions...)
287+
initHealthCheckRoute(root, "healthz")
287288
initReadinessCheckRoute(root, "healthz/ready", c.ProjectAuthorizationCache.ReadyForAccess)
288289

289290
return messages
@@ -473,6 +474,17 @@ func initAPIVersionRoute(root *restful.WebService, prefix string, versions ...st
473474
Consumes(restful.MIME_JSON))
474475
}
475476

477+
// initHealthCheckRoute initalizes an HTTP endpoint for health checking.
478+
// OpenShift is deemed healthy if the API server can respond with an OK messages
479+
func initHealthCheckRoute(root *restful.WebService, path string) {
480+
root.Route(root.GET(path).To(func(req *restful.Request, resp *restful.Response) {
481+
resp.ResponseWriter.WriteHeader(http.StatusOK)
482+
resp.ResponseWriter.Write([]byte("ok"))
483+
}).Doc("return the health state of OpenShift").
484+
Returns(http.StatusOK, "if OpenShift is healthy", nil).
485+
Produces(restful.MIME_JSON))
486+
}
487+
476488
// initReadinessCheckRoute initializes an HTTP endpoint for readiness checking
477489
func initReadinessCheckRoute(root *restful.WebService, path string, readyFunc func() bool) {
478490
root.Route(root.GET(path).To(func(req *restful.Request, resp *restful.Response) {

Diff for: ‎test/integration/external_kube_test.go

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// +build integration,!no-etcd
2+
3+
package integration
4+
5+
import (
6+
"crypto/tls"
7+
"io"
8+
"net/http"
9+
"net/url"
10+
"os"
11+
"testing"
12+
"time"
13+
14+
testutil "github.com/openshift/origin/test/util"
15+
)
16+
17+
func TestExternalKube(t *testing.T) {
18+
// Start one OpenShift master as "cluster1" to play the external kube server
19+
cluster1MasterConfig, cluster1AdminConfigFile, err := testutil.StartTestMaster()
20+
if err != nil {
21+
t.Fatalf("unexpected error: %v", err)
22+
}
23+
24+
// Copy admin.kubeconfig with a name-change top stop from over-writing it later
25+
persistentCluster1AdminConfigFile := cluster1AdminConfigFile + "old"
26+
err = copyFile(cluster1AdminConfigFile, persistentCluster1AdminConfigFile)
27+
if err != nil {
28+
t.Fatalf("unexpected error: %v", err)
29+
}
30+
31+
// Set up cluster 2 to run against cluster 1 as external kubernetes
32+
cluster2MasterConfig, err := testutil.DefaultMasterOptions()
33+
if err != nil {
34+
t.Fatalf("unexpected error: %v", err)
35+
}
36+
// Don't start kubernetes in process
37+
cluster2MasterConfig.KubernetesMasterConfig = nil
38+
// Connect to cluster1 using the service account credentials
39+
cluster2MasterConfig.MasterClients.ExternalKubernetesKubeConfig = persistentCluster1AdminConfigFile
40+
// Don't start etcd
41+
cluster2MasterConfig.EtcdConfig = nil
42+
// Use the same credentials as cluster1 to connect to existing etcd
43+
cluster2MasterConfig.EtcdClientInfo = cluster1MasterConfig.EtcdClientInfo
44+
// Set a custom etcd prefix to make sure data is getting sent to cluster1
45+
cluster2MasterConfig.EtcdStorageConfig.KubernetesStoragePrefix += "2"
46+
cluster2MasterConfig.EtcdStorageConfig.OpenShiftStoragePrefix += "2"
47+
// Don't manage any names in cluster2
48+
cluster2MasterConfig.ServiceAccountConfig.ManagedNames = []string{}
49+
// Don't create any service account tokens in cluster2
50+
cluster2MasterConfig.ServiceAccountConfig.PrivateKeyFile = ""
51+
// Use the same public keys to validate tokens as cluster1
52+
cluster2MasterConfig.ServiceAccountConfig.PublicKeyFiles = cluster1MasterConfig.ServiceAccountConfig.PublicKeyFiles
53+
// Don't run controllers in the second cluster
54+
cluster2MasterConfig.PauseControllers = true
55+
56+
// Start cluster 2 (without clearing etcd) and get admin client configs and clients
57+
cluster2Options := testutil.TestOptions{DeleteAllEtcdKeys: false}
58+
_, err = testutil.StartConfiguredMasterWithOptions(cluster2MasterConfig, cluster2Options)
59+
if err != nil {
60+
t.Fatalf("unexpected error: %v", err)
61+
}
62+
63+
// Ping the healthz endpoint on the second OpenShift cluster
64+
url, err := url.Parse(cluster2MasterConfig.MasterPublicURL)
65+
if err != nil {
66+
t.Fatalf("unexpected error: %v", err)
67+
}
68+
url.Path = "/healthz"
69+
response, err := doHTTPSProbe(url, 1*time.Second)
70+
if err != nil {
71+
t.Fatalf("unexpected error: %v", err)
72+
}
73+
// Only valid "healthy" response from server is 200 - OK
74+
if response.StatusCode != http.StatusOK {
75+
t.Fatalf("OpenShift reported unhealthy: %v", response)
76+
}
77+
}
78+
79+
func copyFile(oldFile, newFile string) (err error) {
80+
in, err := os.Open(oldFile)
81+
if err != nil {
82+
return
83+
}
84+
defer in.Close()
85+
out, err := os.Create(newFile)
86+
if err != nil {
87+
return
88+
}
89+
defer func() {
90+
cerr := out.Close()
91+
if cerr == nil {
92+
err = cerr
93+
}
94+
}()
95+
if _, err = io.Copy(out, in); err != nil {
96+
return
97+
}
98+
err = out.Sync()
99+
return
100+
}
101+
102+
// TODO(skuznets): Use Kube HTTPSProbe once HTTPS support is added and OpenShift GoDeps are updated
103+
func doHTTPSProbe(url *url.URL, timeout time.Duration) (result *http.Response, err error) {
104+
tlsConfig := &tls.Config{InsecureSkipVerify: true}
105+
transport := &http.Transport{TLSClientConfig: tlsConfig}
106+
client := &http.Client{Timeout: timeout, Transport: transport}
107+
result, err = client.Get(url.String())
108+
return
109+
}

0 commit comments

Comments
 (0)
Please sign in to comment.