blob: 7c71fe24fc53f5cb4b62a2b37dc3a3d24b4647a7 [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001/*
2Copyright 2015 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package util
18
19import (
20 "encoding/json"
21 "fmt"
22 "io/ioutil"
23 "net/http"
24
25 etcd "github.com/coreos/etcd/client"
26)
27
28// IsEtcdNotFound returns true if and only if err is an etcd not found error.
29func IsEtcdNotFound(err error) bool {
30 return isEtcdErrorNum(err, etcd.ErrorCodeKeyNotFound)
31}
32
33// IsEtcdNodeExist returns true if and only if err is an etcd node already exist error.
34func IsEtcdNodeExist(err error) bool {
35 return isEtcdErrorNum(err, etcd.ErrorCodeNodeExist)
36}
37
38// IsEtcdTestFailed returns true if and only if err is an etcd write conflict.
39func IsEtcdTestFailed(err error) bool {
40 return isEtcdErrorNum(err, etcd.ErrorCodeTestFailed)
41}
42
43// IsEtcdWatchExpired returns true if and only if err indicates the watch has expired.
44func IsEtcdWatchExpired(err error) bool {
45 // NOTE: This seems weird why it wouldn't be etcd.ErrorCodeWatcherCleared
46 // I'm using the previous matching value
47 return isEtcdErrorNum(err, etcd.ErrorCodeEventIndexCleared)
48}
49
50// IsEtcdUnreachable returns true if and only if err indicates the server could not be reached.
51func IsEtcdUnreachable(err error) bool {
52 // NOTE: The logic has changed previous error code no longer applies
53 return err == etcd.ErrClusterUnavailable
54}
55
56// isEtcdErrorNum returns true if and only if err is an etcd error, whose errorCode matches errorCode
57func isEtcdErrorNum(err error, errorCode int) bool {
58 if err != nil {
59 if etcdError, ok := err.(etcd.Error); ok {
60 return etcdError.Code == errorCode
61 }
62 // NOTE: There are other error types returned
63 }
64 return false
65}
66
67// GetEtcdVersion performs a version check against the provided Etcd server,
68// returning the string response, and error (if any).
69func GetEtcdVersion(host string) (string, error) {
70 response, err := http.Get(host + "/version")
71 if err != nil {
72 return "", err
73 }
74 defer response.Body.Close()
75 if response.StatusCode != http.StatusOK {
76 return "", fmt.Errorf("unsuccessful response from etcd server %q: %v", host, err)
77 }
78 versionBytes, err := ioutil.ReadAll(response.Body)
79 if err != nil {
80 return "", err
81 }
82 return string(versionBytes), nil
83}
84
85type etcdHealth struct {
86 // Note this has to be public so the json library can modify it.
87 Health string `json:"health"`
88}
89
90func EtcdHealthCheck(data []byte) error {
91 obj := etcdHealth{}
92 if err := json.Unmarshal(data, &obj); err != nil {
93 return err
94 }
95 if obj.Health != "true" {
96 return fmt.Errorf("Unhealthy status: %s", obj.Health)
97 }
98 return nil
99}